Basis apa nomor ini?


31

Inilah tantangan mudah yang menyenangkan:

Diberikan string yang merepresentasikan angka dalam basis yang tidak diketahui, tentukan basis terendah yang mungkin dimiliki nomor tersebut. String hanya akan berisi 0-9, a-z. Jika suka, Anda dapat memilih untuk mengambil huruf besar alih-alih huruf kecil, tetapi harap tentukan ini. Anda harus mengeluarkan basis serendah mungkin ini dalam desimal.

Ini adalah contoh yang lebih konkret. Jika string input adalah "01234", angka ini tidak mungkin berada dalam biner, karena 2, 3, dan 4 semuanya tidak terdefinisi dalam biner. Demikian pula, angka ini tidak boleh di basis 3, atau basis 4. Oleh karena itu, angka ini harus di basis-5, atau basis yang lebih tinggi, jadi Anda harus menampilkan '5'.

Kode Anda harus berfungsi untuk basis apa pun antara basis 1 (unary, semua '0's) dan basis 36 (' 0-9 'dan' a-z ').

Anda dapat mengambil input dan memberikan output dalam format apa pun yang masuk akal. Basis-konversi bawaan diizinkan. Seperti biasa, celah standar berlaku, dan jawaban terpendek dalam byte adalah pemenangnya!

Tes IO:

#Input          #Output
00000       --> 1
123456      --> 7
ff          --> 16
4815162342  --> 9
42          --> 5
codegolf    --> 25
0123456789abcdefghijklmnopqrstuvwxyz    --> 36

8
Bisakah saya menghasilkan basis 36?
Leaky Nun

9
@ LeakyNun Ya ampun, saya harap tidak.
Dennis

4
@LeakyNunYou must output this lowest possible base in decimal.
DJMcMayhem

3
@RohanJhunjhunwala Jika itu bahasa Anda yang setara dengan string, saya tidak mengerti mengapa tidak.
DJMcMayhem

3
Biasanya unary adalah semua 1s, dan nol di depan tidak standar untuk sistem numerik berbasis posisi.
Stop Harming Monica

Jawaban:


16

Jelly , 4 byte

ṀØBi

Membutuhkan huruf besar. Cobalah online! atau verifikasi semua kasus uji .

Bagaimana itu bekerja

ṀØBi  Main link. Arguments: s (string)

Ṁ     Yield the maximum of s.
 ØB   Yield "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
   i  Find the 1-based index of the maximum in that string.

1
Ini sebenarnya 7 byte, bukan 4. 2 karakter pertama adalah multi-byte.
Nicomak

14
@Nicomak Jawaban ini disandikan di halaman kode Jelly , di mana semua karakter ini dikodekan sebagai masing-masing 1 byte.
Loovjo

26

Python, 27 22 byte

lambda s:(max(s)-8)%39

Ini membutuhkan input untuk menjadi bytestring (Python 3) atau bytearray (Python 2 dan 3).

Terima kasih kepada @AleksiTorhamo untuk bermain golf 5 byte!

Uji di Ideone .

Bagaimana itu bekerja

Kami mulai dengan mengambil string maksimal. Ini titik kode huruf lebih tinggi dari titik kode angka, karakter maksimal ini juga basis maksimal 36 digit.

Titik kode '0' - '9' adalah 48 - 57 , jadi kita harus mengurangi 48 dari titik kode mereka untuk menghitung angka yang sesuai, atau 47 untuk menghitung basis serendah mungkin. Demikian pula, titik kode huruf 'a' - 'z' adalah 97 - 122 . Karena 'a' mewakili digit dengan nilai 10 , kita harus mengurangi 87 dari titik kode mereka untuk menghitung angka yang sesuai, atau 86 untuk menghitung basis serendah mungkin. Salah satu cara untuk mencapai ini adalah sebagai berikut.

Perbedaan antara 97 dan 58 ( ':' , karakter setelah '9' ) adalah 39 , jadi mengambil poin kode modulo 39 dapat mencapai pengurangan. Karena 48% 39 = 9 , dan hasil yang diinginkan untuk karakter '0' adalah 1 , pertama-tama kita kurangi 8 sebelum mengambil hasil modulo 39 . Pengurangan pertama diperlukan karena jika tidak 'u'% 39 = 117% 39 = 0 .

c    n    n-8    (n-8)%39
0    48    40     1
1    49    41     2
2    50    42     3
3    51    43     4
4    52    44     5
5    53    45     6
6    54    46     7
7    55    47     8
8    56    48     9
9    57    49    10
a    97    89    11
b    98    90    12
c    99    91    13
d   100    92    14
e   101    93    15
f   102    94    16
g   103    95    17
h   104    96    18
i   105    97    19
j   106    98    20
k   107    99    21
l   108   100    22
m   109   101    23
n   110   102    24
o   111   103    25
p   112   104    26
q   113   105    27
r   114   106    28
s   115   107    29
t   116   108    30
u   117   109    31
v   118   110    32
w   119   111    33
x   120   112    34
y   121   113    35
z   122   114    36

Jika Anda membuatnya Python 3, dan mengambil input sebagai string byte, Anda dapat menjatuhkan ord()dan menang dengan 3 byte. :)
Aleksi Torhamo

Ide bagus! Izinkan saya bertanya pada OP.
Dennis

3
@AleksiTorhamo NOOOOOOOOOOOO yu do dis
Rɪᴋᴇʀ

20

Python, 25 byte

lambda x:int(max(x),36)+1

Mendefinisikan lambda yang mengambil string x. Menemukan digit terbesar dalam string (diurutkan dengan huruf di atas angka, menurut standar python), dan mengonversi ke basis 36. Menambahkan 1, karena 8tidak ada di basis 8.


11

Haskell, 34 byte

f s=length['\t'..maximum s]`mod`39

Menggunakan mod(ord(c)-8,39)ide dari Dennis.

41 byte

g '0'=1
g 'W'=1
g x=1+g(pred x)
g.maximum

45 byte:

(`elemIndex`(['/'..'9']++['a'..'z'])).maximum

Output seperti Just 3.


6

Cheddar , 34 29 21 byte

Disimpan 8 byte berkat Dennis !!!

s->(s.bytes.max-8)%39

Menggunakan huruf kecil

Cobalah online

Penjelasan

s -> (      // Input is `s`
  s.bytes    // Returns array of char codes
   .max      // Get maximum item in array
) % 39      // Modulus 39


12
@DJMcMayhem .___. Saya bahkan tidak tahu bahasa saya sendiri bisa melakukan itu
Downgoat

Bagaimana kalau (-)&8bukan n->n-8?
Conor O'Brien

@ ConorO'Brien> _> _> _> Saya belum melakukannya. Saya hanya berencana untuk melakukannya dan kemudian tantangan ini diposting. Bassically f&nobligasi nuntuk arg pertama dari fungsi.
Downgoat

@Downgoat Oh. > _>
Conor O'Brien

6

05AB1E , 6 byte

{¤36ö>

Mengambil huruf dalam huruf besar.

Penjelasan

{       # sort
 ¤      # take last
  36ö   # convert from base 36 to base 10
     >  # increment

Cobalah online


Maafkan kenaifan saya dengan 05AB1E, tetapi apakah maksud Anda mengkonversi dari basis 36 (ke basis 10)?
Keeta

@ Keeta Anda tentu saja benar. Salahku.
Emigna



4

JavaScript (ES6), 41 37 byte

s=>parseInt([...s].sort().pop(),36)+1

Sunting: Disimpan 4 byte berkat @ edc65.


gunakan pop()untuk menyimpan 4
edc65

@ edc65 Saya tidak percaya itu tidak di bawah tips JavaScript.
Neil

3

Haskell, 55 40 byte

f=(\y->mod(y-8)39).Data.Char.ord.maximum

Terima kasih @Dennis atas pendekatannya. (ambil itu, @xnor;))


Saya pikir Anda dapat menghapus f=38 byte karena ftidak mengambil argumen eksplisit.
Cyoce

3

Perl 6: 18 byte

{:36(.comb.max)+1}

Mendefinisikan lambda yang mengambil argumen string tunggal, dan mengembalikan integer. Ini membagi string menjadi karakter, menemukan yang "tertinggi", mengubahnya menjadi basis 36, menambahkan 1.

{(.ords.max-8)%39}

Yang ini menggunakan pendekatan modulo dari Dennis. Sama panjang.


2

Retina , 28 byte

O`.
.\B

{2`
$`
}T01`dl`_o
.

Cobalah online! (Baris pertama memungkinkan suite tes yang dipisahkan dengan linefeed.)

Penjelasan

O`.

Ini memilah karakter input.

.\B

Ini menghapus semua karakter kecuali yang terakhir, sehingga dua tahap pertama menemukan karakter maksimum.

{2`
$`
}T01`dl`_o

Ini adalah dua tahap yang membentuk lingkaran. Yang pertama menduplikasi karakter pertama dan yang kedua "decrements" (menggantikan misalnya xdengan w, adengan 9dan 1dengan 0). Tahap terakhir menemukan nol sebagai karakter pertama, ia menghilangkannya sebagai gantinya. Ini adalah teknik standar untuk menghasilkan serangkaian karakter, mengingat ujung atas. Karenanya, ini menghasilkan semua "digit" dari 0ke digit maksimum.

.

Akhirnya, kita cukup menghitung jumlah digit, yang memberi kita basis.


2

R, 99 89 85 byte

Lihat! Kurang dari 100 byte!
Lihat! Off 10 byte!
Lihat! Off 4 byte!

ifelse((m=max(strsplit(scan(,''),"")[[1]]))%in%(l=letters),match(m,l)+10,strtoi(m)+1)

Tidak Disatukan:

l=letters                  #R's built-in vector of lowercase letters

n=scan(what=characters())  #Takes an input from STDIN and convert it to characters

m=max(strsplit(n,"")[[1]]) #Splits the input and takes to max. 
                           #`letters` are considered > to numbers (i.e. a>1)


ifelse(m%in%l,match(m,l)+10,strtoi(m)+1) #If the max is in `letters`,
                                             #outputs the matching position of `m`in `letters` + 10 (because of [0-9]). 
                                             #Else, outputs `m` (as a number) + 1.

Seperti sering, jawaban ini memanfaatkan ifelsefungsi:ifelse(Condition, WhatToDoIfTrue, WhatToDoElse)


Saya suka versimu; Namun, memperlakukan huruf dan angka secara terpisah menciptakan byte ekstra sial itu. Silakan lihat solusi saya yang menggunakan metode yang berbeda.
Andreï Kostyrka

Jawaban Anda memang menarik. Saya akan menggunakan scanmetode Anda untuk golf beberapa byte;)
Frédéric

1

PHP, 51 38 byte

(Dari Dennis) ^^

<?=(ord(max(str_split($argv[1])))-8)%39;

Proposal lain tanpa trik Dennis

<?=($a=max(str_split($argv[1])))<a?$a+1:ord($a)-86;
  • Mengambil input sebagai argumen $ argv [1];
  • Ambil nilai karakter maksimum (menggunakan ASCII)
  • Jika itu adalah angka (lebih rendah dari nilai ascii <'a') maka nomor keluaran +1
  • Output lain nilai ascii -86 (97 untuk 'a' di ascii, -11 untuk 'a' adalah base-digit ke-11)

Sayang sekali PHP memiliki nama fungsi verbose seperti itu: <?=base_convert(max(str_split($argv[1])),36,10)+1adalah solusi yang elegan, tetapi pada 49 byte!

@YiminRong Anda dapat menggunakan intval()alih-alih base_convert()yang lebih pendek menjadi 38 byte <?=intval(max(str_split($argn)),36)+1;tio: tio.run/##K8go@P/…
640KB



1

Java 7, 67 61 byte

int c(char[]i){int m=0;for(int c:i)m=m>c?m:c;return(m-8)%39;}

(m-8)%39berkat @Dennis jawaban menakjubkan ' .

Tidak digabungkan & kode uji:

Coba di sini.

class Main{
  static int c(char[] i){
    int m = 0;
    for(int c : i){
      m = m > c
           ? m
           : c;
    }
    return (m-8) % 39;
  }

  public static void main(String[] a){
    System.out.println(c("00000".toCharArray()));
    System.out.println(c("123456".toCharArray()));
    System.out.println(c("ff".toCharArray()));
    System.out.println(c("4815162342".toCharArray()));
    System.out.println(c("42".toCharArray()));
    System.out.println(c("codegolf".toCharArray()));
    System.out.println(c("0123456789abcdefghijklmnopqrstuvwxyz".toCharArray()));
  }
}

Keluaran:

1
7
16
9
5
25
36

2
Alih-alih Math.max()Anda dapat menggunakanm = m>c?m:c
RobAu

@RobAu Ah, tentu saja, terima kasih. Benar-benar lupa tentang itu .. Kadang-kadang saya lupa hal-hal codegolfing termudah di Jawa yang bahkan disebutkan beberapa kali dalam Tips untuk Codegolfing di Jawa post . Terima kasih atas pengingatnya.
Kevin Cruijssen

Jika Anda beralih ke Java 8, Anda dapat mengganti seluruh fungsi ini dengan lambda yang memiliki satureduce
BlueRaja - Danny Pflughoeft

@ BlueRaja-DannyPflughoeft Saya tahu, itulah sebabnya saya secara khusus menyebutkannya sebagai Java 7. Jangan ragu untuk mengirim Java 8 lambda sebagai jawaban terpisah.
Kevin Cruijssen

@ BlueRaja-DannyPflughoeft Saya ingin tahu apakah itu akan berakhir dengan lebih sedikit byte ..
RobAu

1

C89, 55 53 52 50 byte

f(s,b)char*s;{return*s?f(s+1,*s>b?*s:b):(b-8)%39;}

-8%39 tanpa malu-malu dicuri dari Dennis

Uji

test(const char* input)
{
    printf("%36s -> %u\n", input, f((char*)input,0));
}

main()
{
    test("00000");
    test("123456");
    test("ff");
    test("4815162342");
    test("42");
    test("codegolf");
    test("0123456789abcdefghijklmnopqrstuvwxyz");
}

Keluaran

                               00000 -> 1
                              123456 -> 7
                                  ff -> 16
                          4815162342 -> 9
                                  42 -> 5
                            codegolf -> 25
0123456789abcdefghijklmnopqrstuvwxyz -> 36

Disimpan 2 byte berkat Toby Speight

Disimpan 2 byte berkat Kevin Cruijssen


Anda dapat menyimpan 2 byte dengan deklarasi non-prototipe: f(char*s,int b)menjadi f(s,b)char*s;.
Toby Speight

Anda dapat menghemat 3 byte dengan menghapus tanda kurung dan ruang yang tidak perlu:f(s,b)char*s;{return*s?f(s+1,*s>b?*s:b):(b-8)%39;}
Kevin Cruijssen

@KevinCruijssen thx
YSC

1

C, 55 byte

Jawaban ini mengasumsikan bahwa input dalam ASCII (atau identik dalam angka dan huruf, misalnya ISO-8859 atau UTF-8):

m;f(char*s){for(m=0;*s;++s)m=m>*s?m:*s;return(m-8)%39;}

Kami hanya mengulang di sepanjang string, mengingat nilai terbesar yang terlihat, kemudian menggunakan konversi modulo-39 yang terkenal dari basis- {11..36}.

Program uji

int printf(char*,...);
int main(int c,char **v){while(*++v)printf("%s -> ",*v),printf("%d\n",f(*v));}

Hasil tes

00000 -> 1
123456 -> 7
ff -> 16
4815162342 -> 9
42 -> 5
codegolf -> 25
0123456789abcdefghijklmnopqrstuvwxyz -> 36

Tidak bisakah Anda menghapus m = 0? Jika m muncul di tingkat atas file, eksternalnya yang menyiratkan statis yang menyiratkan inisialisasi ke nol.
Batman

@Batman - ya, tetapi hanya jika Anda tidak akan menelepon f()lebih dari sekali. Saya tahu bahwa hampir semua permainan yang adil dalam golf, tetapi naluri profesional saya menganggapnya terlalu rapuh!
Toby Speight

Dipikirkan lebih lanjut, saya bisa menjadikannya persyaratan eksternal untuk mengatur ulang mantar panggilan f(). Maka program pengujian saya masih bisa bekerja.
Toby Speight

@Batman: pada Code Golf Meta , pendapat mayoritas atas pertanyaan " Apakah pengiriman fungsi harus dapat digunakan kembali? " Jadi saya akan tetap dengan apa yang saya miliki. Terima kasih atas sarannya.
Toby Speight

1

Mathematica, 34 32 byte

2 byte disimpan berkat Martin Ender

Max@Mod[ToCharacterCode@#-8,39]&

Saya memutuskan metode yang berbeda pantas mendapat jawaban baru.

Metode yang dicuri terinspirasi oleh solusi Dennis


2
Gunakan beberapa notasi awalan: Max@Mod[ToCharacterCode@#-8,39]&(hal yang sama berlaku untuk jawaban Anda yang lain)
Martin Ender

2
Juga, Anda perlu menambahkan &sampai akhir untuk menunjukkan fungsi anonim.
LegionMammal978

Anda lupa satu @di kedua jawaban Anda ( ToCharacterCode@#dan Characters@#).
Martin Ender

1

Mathematica, 34 32 byte

disimpan 2 byte berkat Martin Ender

Max@BaseForm[Characters@#,36]+1&

Mendefinisikan fungsi murni yang mengambil string sebagai input.

Pisahkan input menjadi karakter, ubah menjadi basis 36 angka, dan kembalikan +1 maksimum.


Max@BaseForm[Characters@#,36]+1&
alephalpha

1

C # REPL, 17 byte

x=>(x.Max()-8)%39

Baru saja mengirim jawaban @ Dennis ke C #.


1

CJam, 10 byte

Terima kasih kepada Martin Ender karena telah menyelamatkan saya beberapa byte!

Menggunakan formula Dennis

q:e>8-i39%

Cobalah online

CJam, 18 16 btyes

Solusi alternatif:

A,s'{,97>+q:e>#)

Cobalah online

A,s'{,97>+       e# Push the string "0123456789abcdefghijklmnopqrstuvwxyz"
          q      e# Get the input
           :e>   e# Find the highest character in the input
              #  e# Find the index of that character in the string
               ) e# Increment

1

Scala, 25 byte

print((args(0).max-8)%39)

Jalankan seperti:

$ scala whatbase.scala 0123456789abcdefghijklmnopqrstuvwxyz


1

R, 62 54 byte

max(match(strsplit(scan(,''),"")[[1]],c(0:9,letters)))

Tidak Disatukan:

max(
  match( # 2: Finds the respective positions of these characters
    strsplit(scan(,''),"")[[1]], # 1: Breaks the input into characters
                                c(0:9,letters)) # 3: In the vector "0123...yz"
                                                )

Pembaruan: dicukur 8 byte karena redundansi na.rm=T bawah asumsi validitas input.

Peningkatan 39% dalam ukuran dibandingkan dengan jawaban Frédéric . Selain itu, ia menjalankan sedikit lebih cepat: 0,86 detik untuk 100000 replikasi dibandingkan 1,09 detik untuk jawaban yang bersaing. Jadi salah satu tambang saya lebih kecil dan lebih efisien.


0

Dyalog APL , 10 byte

Anjuran untuk input huruf besar.

⌈/⍞⍳⍨⎕D,⎕A

⌈/ maksimum

karakter input

⍳⍨ 1 diindeks menjadi

⎕D, semua digit diikuti oleh

⎕A semua karakter

TryAPL online!


0

BASH 70

grep -o .|sort -r|head -c1|od -An -tuC|sed s/$/-86/|bc|sed s/-/39-/|bc

Input huruf adalah huruf kecil.


0

JavaScript, 57 50 48 byte

7 byte disimpan thnks ke @ kamaroso97 2 byte disimpan berkat @Neil

n=>Math.max(...[...n].map(a=>parseInt(a,36))+1)

Jawaban asli:

n=>n.split``.map(a=>parseInt(a,36)).sort((a,b)=>b-a)[0]+1

Anda dapat mematikan 7 byte dengan n=>Math.max(...n.split``.map(a=>parseInt(a,36)+1)).
kamoroso94

@ kamoroso94 Saya tidak menyadari Math.maxada. Terima kasih telah memberi tahu saya tentang itu!
DanTheMan

[...s]lebih pendek dari s.split``.
Neil

0

Perl, 30 27 byte

Termasuk +1 untuk -p

Jalankan dengan input pada STDIN, mis

base.pl <<< codegolf

base.pl:

#!/usr/bin/perl -p
\@F[unpack"W*"];$_=@F%39-9

0

LiveScript, 32 byte

->1+parseInt (it/'')sort!pop!,36

Port jawaban ini dalam bahasa favorit saya yang mengkompilasi ke JavaScript. Jika base~numberoperator bekerja dengan variabel saya bisa menulis ->1+36~(it/'')sort!pop!(23 byte), tetapi bertentangan dengan fungsi bind operator: /

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.