Basis terbaik adalah 10 ... Ayo kita capai!


40

Memasukkan:

Bilangan bulat positif n yang terdiri dari angka dalam kisaran 0-9 .

Tantangan:

Jika d adalah digit tertinggi dalam bilangan bulat, anggap pangkalan angka tersebut adalah d +1 . Misalnya jika bilangan bulat adalah 1256 maka Anda harus menganggap itu dalam basis-7 , jika itu 10110 maka Anda harus menganggap itu basis-2 (biner), dan jika 159 maka itu adalah desimal.

Sekarang, lakukan hal berikut sampai Anda, 1: mencapai integer basis-10 , atau 2: mencapai integer satu digit.

  1. Konversikan bilangan bulat dari basis- (d + 1) ke basis-10
  2. Temukan basis dari integer baru ini (sekali lagi, base- (d + 1) di mana d adalah digit tertinggi dalam angka baru)
  3. Lanjutkan ke langkah 1 .

Contoh:

Asumsikan inputnya adalah n = 413574 . Digit tertinggi d = 7 , jadi ini adalah base-8 (oktal). Ubah ini menjadi desimal dan dapatkan 137084 . Digit tertinggi d = 8 , jadi ini adalah base-9 . Ubah ini menjadi desimal dan dapatkan 83911 . Digit tertinggi adalah 9 , jadi ini adalah angka desimal dan kami berhenti. Outputnya adalah 83911 .

Asumsikan inputnya adalah n = 13552 . Digit tertinggi adalah d = 5 , jadi ini adalah basis-6 . Ubah ini menjadi desimal dan dapatkan 2156 . Digit tertinggi d = 6 , jadi ini adalah base-7 . Ubah ini menjadi desimal dan dapatkan 776 . Digit tertinggi adalah d = 7 , jadi ini adalah basis-8 . Konversikan ke desimal dan dapatkan 510 . Digit tertinggi adalah d = 5 jadi ini adalah basis-6 . Ubah ini menjadi desimal dan dapatkan 186 . Digit tertinggi adalah 8 , jadi ini adalah base-9 . Ubah ini menjadi desimal dan dapatkan 159. Digit tertinggi adalah 9 , jadi ini adalah angka desimal dan kami berhenti. Outputnya adalah 159 .

Asumsikan inputnya adalah n = 17 . Ini akan memberi kita 15 , lalu 11 , lalu 3 , yang akan kita hasilkan karena itu satu digit.


Kasus uji:

5
5

17
3

999
999

87654321  (base-9 -> 42374116 in decimal -> base-7 -> 90419978 in decimal) 
9041998

41253  (5505 -> 1265 -> 488 -> 404 -> 104 -> 29)
29

Catatan:

  • Aturan standar tentang I / O, celah dll. Anda dapat mengambil input sebagai string
  • Penjelasan didorong
  • Anda dapat menggunakan perintah konversi konversi bawaan
    • Solusi yang tidak menggunakan fungsi konversi basis bawaan bahasa (jika ada) diterima, bahkan jika mereka berakhir lebih lama daripada pendekatan yang jelas menggunakan fungsi builtin.

Rupanya, ini adalah OEIS A091047 .


2
Rupanya saya suka matriks , jadi saya pikir saya akan melakukan tantangan konversi basis .
Stewie Griffin

34
"Basis terbaik adalah 10" ... "10" ditulis di pangkalan mana?
Olivier Grégoire

5
@ OlivierGrégoire Itu hal yang pintar ... Apa pun dasar yang kita miliki, itu masih akan menjadi pernyataan yang valid!
Stewie Griffin

@StewieGriffin Tapi bagaimana Anda membacanya? "10" memiliki nama berbeda di setiap basis.
user11153

10
Yah, itu tergantung pada pangkalan ... atau seperti yang Meghan katakan, "ini semua tentang pangkalan itu, 'Tentang pangkalan itu, tidak ada masalah" ;-)
Stewie Griffin

Jawaban:


20

Mathematica, 56 byte

#//.x_/;(b=Max[d=IntegerDigits@x]+1)<11:>d~FromDigits~b&

Cobalah online! (Menggunakan Matematika.)

Saya pikir saya akan memeriksa seperti apa urutannya:

masukkan deskripsi gambar di sini

Dan ini adalah plot jumlah langkah yang diperlukan untuk menemukan hasilnya:

masukkan deskripsi gambar di sini

(Klik untuk versi yang lebih besar. Lihat riwayat revisi untuk plot hanya hingga n = 1000. )

Tampak seperti campuran yang sangat menarik dari struktur skala besar dan kekacauan skala halus. Saya bertanya-tanya ada apa dengan kesenjangan yang lebih luas sekitar 30.000 dan 60.000.


4
@StewieGriffin harus di sebelah kiri. Kesenjangan kecil ada di sana, karena angka yang mengarah ke kelipatan kekuatan 10 berisi a 9, jadi mereka sudah ada di basis 10. Tapi untuk 30k dan 60k tampaknya angka dengan 8 atau bahkan 7 (harus check) di tempat 9 yang selalu menjadi basis 10 setelah paling banyak satu langkah.
Martin Ender

@StewieGriffin Lebih tepatnya, semua angka dalam kisaran [28051, 28888] adalah basis 9 dan diterjemahkan ke angka-angka dari formulir 19xxx, sehingga cukup banyak menggandakan celah itu.
cmaster

Ah, mengerti ... :) Sebagai catatan: Saya tahu mengapa ada celah di sisi kiri kekuatan 10-an ... Itu hanya celah ganda yang aneh (mengapa 30/60, dan bukan 20 / 40/50). Saya melihat sekarang bahwa angka-angka dalam kisaran 28xxx -> 19xxx, tetapi 38xxx -> 26xxx, bukan 29xxx.
Stewie Griffin

10

Java 8, 172 166 163 152 151 140 140 116 116 99 byte

s->{for(Integer b=0;b<10&s.length()>1;s=""+b.valueOf(s,b=s.chars().max().getAsInt()-47));return s;}

Mengambil input sebagai a String.

-64 byte terima kasih kepada @ OlivierGrégoire . Dan di sini saya pikir 172 awal saya tidak terlalu buruk ..;)

Coba di sini.

Penjelasan:

s->{                    // Method with String as parameter and return-type
  for(Integer b=0;b<10  //  Loop as long as the largest digit + 1 is not 10
      &s.length()>1;    //  and as long as `s` contains more than 1 digit
    s=""+               //   Replace `s` with the String representation of:
         b.valueOf(s,   //    `s` as a Base-`b` integer
          b=s.chars().max().getAsInt()-47)
                        //     where `b` is the largest digit in the String + 1
  );                    //  End of loop
  return s;             //  Return result-String
}                       // End of method

1
Berjanji untuk tetap tenang? : p Ok ... mari kita pergi: s->{for(Integer b=0;b<10&s.length()>1;)s=""+b.valueOf(s,b=s.chars().max().getAsInt()-47);return s;}. Juga saya menghapus sebagian besar komentar saya karena sama sekali tidak relevan sekarang ( badalah basis, Anda a; dan sadalah nomor yang sedang kami kerjakan).
Olivier Grégoire

1
Saya sudah mencoba recursify ini untuk memangkas beberapa byte dengan: Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:c(""+b.valueOf(s,b));(88), tapi saya baru mengenal kode golf. Ini potongan, kan? Apakah ada cara untuk menyatakan ini sebagai metode tanpa perlu menambahkan public String c(String s)?
Lord Farquaad

1
@LordFarquaad Anda tidak memerlukannya public, tapi saya khawatir Anda memang harus menggunakan String c(String s){}untuk panggilan rekursif, bahkan di Java 8. Ketika Anda membuat lambda menggunakan java.util.function.Function<String, String> c=s->{Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:c‌.apply​(""+b.valueOf(s,b));}atau menggunakan antarmuka interface N{String c(String s);}N n = s->{Integer b;return(b=s.chars().max().getAsInt()-47)>9|s.length()<2?s:n.c‌​(""+b.valueOf(s,b));};akan memberikan " referensi diri dalam initializer kesalahan "dalam kedua kasus. Namun pendekatan yang sangat bagus!
Kevin Cruijssen

Ah, saya kira saya tidak meng-unbootnya beberapa byte. Tapi terima kasih atas bantuannya! Saya akan terus mengingat hal ini.
Lord Farquaad

8

Pyth, 9 byte

ui`GhseS`

Suite uji

Penjelasan:

ui`GhseS`
ui`GhseS`GQ    Implicit variable introduction
u         Q    Repeatedly apply the following function until the value repeats,
               starting with Q, the input.
        `G     Convert the working value to a string.
      eS       Take its maximum.
     s         Convert to an integer.
    h          Add one.
 i`G           Convert the working value to that base

Agak aneh bagaimana Anda menggunakan lambda dua variabel yang berakhir dengan menggunakan satu variabel ... dan itu tidak menimbulkan kesalahan. Oh, kedua variabel itu adalah Qdan Q, saya mengerti.
Erik the Outgolfer

@EriktheOutgolfer Tidak persis sama. utanpa input ketiga diterapkan hingga pengulangan, sedangkan dengan input ketiga diterapkan beberapa kali tetap. ulambda memiliki Gdan H, tetapi Anda tidak perlu menggunakan H.
isaacg

Sebenarnya mengganti Gdengan Hakan memiliki hasil yang sama ... btw variabel implisit adalah G?
Erik the Outgolfer

@EriktheOutgolfer Variabel implisit adalah G, ya. Hdihitung dari 0 dengan setiap iterasi, sehingga sangat berbeda. Saya tidak begitu yakin apa yang Anda bicarakan. Berikut ini contoh program untuk menunjukkan kepada Anda apa yang terjadi: pyth.herokuapp.com/…
isaacg

6

JavaScript (ES6), 63 57 54 53 byte

f=a=>a>9&(b=Math.max(...a+""))<9?f(parseInt(a,b+1)):a

Disimpan 8 byte berkat Shaggy dan Dom Hastings

f=a=>a>9&(b=Math.max(...a+""))<9?f(parseInt(a,b+1)):a;

console.log(f("413574"))


Kalahkan aku untuk itu. Saya pikir Anda bisa menghemat beberapa byte dengan +a>9||b<9dan membalikkan terner.
Shaggy

1
@Shaggy sunting: Aku bodoh
Tom

1
Jangan terlalu keras pada dirimu, Tom! Anda tidak bodoh ,,, tetapi Anda pasti tidak sepintar @Shaggy!
Stewie Griffin

1
Alternatif untuk 55 bytef=n=>n>9&&(k=Math.max(...n+"")+1)<10?f(parseInt(n,k)):n
Dom Hastings

@HomHastings Terima kasih atas perbaikannya! :)
Tom

5

Python 3 , 91 78 76 75 73 byte

@Emigna mencukur 5 byte. @FelipeNardiBatista menyimpan 1 byte. @ RomanGräf menyimpan 2 byte

i=input()
while'9'>max(i)and~-len(i):i=str(int(i,int(max(i))+1))
print(i)

Cobalah online!


Penjelasan

i=input()                                  - takes input and assigns it to a variable i
while '9'>max(i)and~-len(i):               - repeatedly checks if the number is still base-9 or lower and has a length greater than 1
    i=str(...)                             - assigns i to the string representation of ...
          int(i,int(max(i))+1)             - converts the current number to the real base 10 and loops back again
print(i)                                   - prints the mutated i

5

05AB1E , 10 5 byte

5 byte disimpan berkat Magic Octopus Guci

F§Z>ö

Karena ini tumbuh lambat dengan sangat cepat untuk input besar, saya meninggalkan versi lama yang jauh lebih cepat di sini untuk pengujian. Algoritmanya sama, hanya jumlah iterasi yang berbeda.

[©Z>öD®Q#§

Cobalah online!

Penjelasan

[             # start a loop
 ©            # store a copy of the current value in the register
  Z>          # get the maximum (digit) and increment
    ö         # convert the current value to base-10 from this base
     D        # duplicate
      ®Q#     # break loop if the new value is the same as the stored value
         §    # convert to string (to prevent Z from taking the maximum int on the stack)

Juga, tidak bisakah kamu menggunakan saja тFZ>ö§? Melihat jumlah iterasi ( seperti yang terlihat di sini ) tampaknya dataran tinggi? Jika Anda ingin mendapatkan teknis, tingkat kenaikan iterasi mungkin adalah logaritmik ... Jadi Anda bisa menggunakan sesuatu seperti: DFZ>ö§dan nyatakan itu tidak akan berjalan besar n. ATAU bahkan mungkin: T.n>FZ>ö§untuk secara langsung menghitung jumlah iterasi sebagai log_10(n).
Magic Octopus Mm

@ MagicOctopusUrn: Ya, sekarang Anda menyebutkannya, karena urutannya pasti lebih lambat dari linear, F§Z>öharus melakukan trik.
Emigna

Saya pikir Anda dapat menghapus §.
Erik the Outgolfer

@EriktheOutgolfer: Sayangnya tidak. Jika kita menghapus §, Zakan mengambil angka tertinggi di tumpukan alih-alih digit tertinggi di nomor di atas tumpukan.
Emigna


3

APL (Dyalog) , 20 16 byte

Mengambil dan mengembalikan string

((⍕⊢⊥⍨1+⌈/)⍎¨)⍣≡

(... )⍣≡ terapkan fungsi berikut sampai dua istilah berturut-turut identik:

⍎¨ mengeksekusi setiap karakter (mengubah string menjadi daftar angka)

(... ) terapkan fungsi tersembunyi berikut untuk itu:

  ⌈/ temukan argumen maksimal

  1+ tambahkan satu

  ⊢⊥⍨ mengevaluasi argumen di pangkalan itu

   format (stringify, sebagai persiapan untuk aplikasi fungsi luar lainnya)

Cobalah online!



3

Mathematica, 52 byte

FromDigits[s=IntegerDigits@#,Max@s+1]&~FixedPoint~#&

Fungsi murni mengambil bilangan bulat negatif sebagai masukan dan mengembalikan bilangan bulat negatif. Menggunakan inti mekanik yang FromDigits[s=IntegerDigits@#,Max@s+1]sama dengan jawaban Jenny_mathy , tetapi mengeksploitasi FixedPointuntuk melakukan iterasi.


3

Perl 6 , 49 byte

{($_,{.Str.parse-base(1+.comb.max)}...*==*).tail}

Menguji

Diperluas:

{
  (

    $_,                 # seed the sequence with the input

    {
      .Str
      .parse-base(      # parse in base:
        1 + .comb.max   # largest digit + 1
      )
    }

    ...                 # keep generating values until

    * == *              # two of them match (should only be in base 10)

  ).tail                # get the last value from the sequence
}


2

Pip , 17 byte

Wa>9>YMXaaFB:1+ya

Mengambil input sebagai argumen baris perintah. Cobalah online!

Penjelasan

Ini menyenangkan - saya harus menarik keluar operator perbandingan rantai.

Kami ingin mengulang sampai angka adalah satu digit ATAU berisi 9. Sama dengan itu, kami ingin mengulang sementara angka tersebut adalah beberapa digit DAN tidak mengandung angka 9. Secara setara, loop sementara angka lebih besar dari 9 DAN angka maksimum adalah kurang dari 9: a>9>MXa.

Wa>9>YMXaaFB:1+ya
                   a is 1st cmdline arg (implicit)
     YMXa          Yank a's maximum digit into the y variable
Wa>9>              While a is greater than 9 and 9 is greater than a's max digit:
         aFB:1+y    Convert a from base 1+y to decimal and assign back to a
                a  At the end of the program, print a

2

Python 2 , 60 59 56 53 byte

Disimpan 4 byte berkat Felipe Nardi Batista
Disimpan 3 byte berkat ovs

f=lambda x,y=0:x*(x==y)or f(`int(x,int(max(x))+1)`,x)

Cobalah online!

Menggunakan lambda rekursif, membandingkan hasil konversi basis ke iterasi sebelumnya.


mengapa tidak digunakan x==y and x or ...karena xtidak akan pernah 0(basis 1). atau bahkan(x==y)*x or ...
Felipe Nardi Batista

@FelipeNardiBatista: Terima kasih! Saya mencoba x and x==y or ...yang tidak berhasil, tetapi saya tidak terlalu mahir dengan trik ini sehingga saya tidak menyadari bahwa saya bisa membalikkannya :)
Emigna

@ovs: Benar sekali. Terima kasih!
Emigna

@FelipeNardiBatista "Input: Bilangan bulat positif n yang terdiri dari angka di kisaran 0-9." 0 masih input yang valid, dan sekarang kode menolaknya.
Mast

@Mast: Untungnya bagi kami, 0 bukan bilangan bulat positif sehingga tidak akan diberikan sebagai input.
Emigna

2

C #, 257 244 243 244 233 222 byte

using System.Linq;z=m=>{int b=int.Parse(m.OrderBy(s=>int.Parse(s+"")).Last()+""),n=0,p=0;if(b<9&m.Length>1){for(int i=m.Length-1;i>=0;i--)n+=int.Parse(m[i]+"")*(int)System.Math.Pow(b+1,p++);return z(n+"");}else return m;};

Yah, C # selalu membutuhkan banyak byte tetapi ini hanya konyol. Tidak ada built-in yang dapat menangani basis arbitrer, jadi saya harus menghitung sendiri konversi. Tidak Disatukan:

using System.Linq;
z = m => {
int b = int.Parse(m.OrderBy(s => int.Parse(s + "")).Last()+""), n = 0, p = 0; //Get the max digit in the string
if (b < 9 & m.Length > 1) //if conditions not satisfied, process and recurse
{
    for (int i = m.Length - 1; i >= 0; i--)
        n += int.Parse(m[i] + "") * (int)System.Math.Pow(b+1, p++); //convert each base-b+1 representation to base-10
    return z(n + ""); //recurse
}
else return m; };

1

Mathematica, 92 byte

f[x_]:=FromDigits[s=IntegerDigits@x,d=Max@s+1];(z=f@#;While[d!=10&&Length@s>1,h=f@z;z=h];z)&

1

Javascript (ES6) dengan fungsi panah 0, 74 byte

function f(a){a>9&&b=Math.max(...a)<9&&f(parseInt(a,b+1));alert(a)}f('11')

3
Selamat datang di PPCG! :) Ini mungkin jawaban yang sangat bagus, tetapi saya tidak bisa mengatakannya tanpa penjelasan. Saya (dan mungkin orang lain) tidak pernah memilih jawaban yang tidak mengandung penjelasan.
Stewie Griffin

1
Mengapa Anda memanggil f('11')setelah fungsi? Kecuali jika saya melewatkan sesuatu yang hanya terlihat sebagai penggunaan, sebenarnya bukan bagian dari pengiriman. Jika demikian, Anda harus mengeluarkannya dari bagian kode dan memasukkannya ke dalam penjelasan Anda (ketika Anda menambahkannya) dan memperbarui jumlah byte Anda menjadi 67.
PunPun1000

1

K4 , 19 byte

Larutan:

{(1+|/x)/:x:10\:x}/

Contoh:

q)\
  {(1+|/x)/:x:10\:x}/413574
83911
  {(1+|/x)/:x:10\:x}/13552
159
  {(1+|/x)/:x:10\:x}/17
3
  {(1+|/x)/:x:10\:x}/41253
29    

Penjelasan:

Gunakan /:bawaan untuk mengonversi basis.

{(1+|/x)/:x:10\:x}/ / the solution
{                }/ / converge lambda, repeat until same result returned
            10\:x   / convert input x to base 10 (.:'$x would do the same)
          x:        / store in variable x
 (     )/:          / convert to base given by the result of the brackets
    |/x             / max (|) over (/) input, ie return largest
  1+                / add 1 to this

1

Kotlin , 97 byte

fun String.f():String=if(length==1||contains("9"))this else "${toInt(map{it-'0'}.max()!!+1)}".f()

Yg diperindahkan

fun String.f(): String = if (length == 1 || contains("9")) this else "${toInt(map { it - '0' }.max()!! + 1)}".f()

Uji

fun String.f():String=if(length==1||contains("9"))this else "${toInt(map{it-'0'}.max()!!+1)}".f()
val tests = listOf(
        5 to 5,
        17 to 3,
        999 to 999,
        87654321 to 9041998,
        41253 to 29
)

fun main(args: Array<String>) {
    tests.forEach { (input, output) ->
        val answer = input.toString().f()
        if (answer != output.toString()) {
            throw AssertionError()
        }
    }
}

TIO

TryItOnline




0

C, 159 157 byte

#include <stdlib.h>
char b[99];i=0;m=-1;c(n){do{m=-1;sprintf(b,"%d",n);i=0;while(b[i]){m=max(b[i]-48,m);i++;}n=strtol(b,0,++m);}while(b[1]&&m<10);return n;}

0

Scala , 119 byte

if(x.max==57|x.length==1)x else{val l=x.length-1
f((0 to l).map(k=>(((x(k)-48)*math.pow(x.max-47,l-k))) toInt).sum+"")}

Cobalah online!

Scala , 119 byte

if(x.max==57|x.length==1)x else f((0 to x.length-1).map(k=>(((x(k)-48)*math.pow(x.max-47,x.length-1-k))) toInt).sum+"")

Cobalah online!

Kedua metode bekerja dengan cara yang sama, tetapi yang pertama saya masukkan ke x.length-1dalam variabel, dan yang kedua tidak.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.