この数字はどのベースにありますか?


31

ここに簡単な挑戦があります:

未知の基数の数値を表す文字列が与えられた場合、その数値が含まれる可能性のある最も低い基数を決定します0-9, a-z。文字列にはのみが含まれます。必要に応じて、小文字ではなく大文字を使用することもできますが、これを指定してください。この可能な限り低いベースを10進数で出力する必要があります。

より具体的な例を次に示します。入力文字列が「01234」の場合、2、3、および4はすべてバイナリで定義されていないため、この数値をバイナリにすることはできません。同様に、この数値は基数3または基数4にすることはできません。したがって、この数は基数5以上でなければなりません。したがって、「5」を出力する必要があります。

コードは、ベース1(単項、すべて「0」)からベース36(「0-9」および「a-z」)までの任意のベースで機能する必要があります。

入力を受け取り、適切な形式で出力を提供できます。基本変換ビルトインが許可されています。いつものように、標準的な抜け穴が適用され、バイト単位の最短回答が勝者です!

テストIO:

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

8
ベース36で出力できますか?
— リーキー修道女

9
@LeakyNun Geez、私はそうではないことを願っています。
— デニス

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

3
@RohanJhunjhunwalaそれが文字列に最も近いあなたの言語である場合、なぜそうなのかわかりません。
— DJMcMayhem

3
通常、単項はすべて1であり、先行ゼロは位置ベースの数値システムの標準ではありません。
— 停止ハーミングモニカ

回答:


16

ゼリー、4 バイト

ṀØBi

大文字が必要です。オンラインでお試しください!または、すべてのテストケースを確認します。

使い方

ṀØ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
実際には4バイトではなく7バイトです。最初の2文字はマルチバイトです。
— ニコマク

14
@Nicomakこの回答はJellyコードページでエンコードされます。これらの文字はすべて1バイトとしてエンコードされます。
— -Loovjo

26

Python、27 22バイト

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

これには、入力がバイト文字列(Python 3)またはバイト配列(Python 2および3)である必要があります。

5バイトのゴルフをしてくれた@AleksiTorhamoに感謝します!

Ideoneでテストします。

使い方

まず、文字列の最大値を取得します。これは文字のコードポイントが数字のコードポイントよりも高く、この最大文字は最大36桁です。

コードポイント「0」 - 「9」である57から48まで、我々は減算しなければならないので、48を対応する数字、または計算するために、それらのコードポイントから47を可能な限り低いベースを計算します。同様に、文字のコードポイント「A」 - 「Z」はである97 - 122。以来'値の桁を表し10を、我々は減算しなければならない87の対応する数字、または計算するために、それらのコードポイントから86を可能な限り低いベースを計算します。これを実現する1つの方法は次のとおりです。

差97および58(「:」の後に文字「9」)が39、したがってコードポイントモジュロ取っ39減算を達成することができます。以来、48%39 = 9、および文字の所望の結果「0」である1、まず減算8を結果モジュロ取る前に39。それ以外の場合は'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

If you make it Python 3, and take the input as a byte string, you can drop the ord() and win by 3 bytes. :)
— Aleksi Torhamo

Nice idea! Let me ask the OP.
— Dennis

3
@AleksiTorhamo NOOOOOOOOOOOO y u do dis
— Rɪᴋᴇʀ

20

Python, 25 bytes

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

Defines a lambda that takes the string x. Finds the largest digit in the string (sorted with letters above digits, by python's default), and converts to base 36. Adds 1, because 8 is not in base 8.


11

Haskell, 34 bytes

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

Uses the mod(ord(c)-8,39) idea from Dennis.

41 bytes

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

45 bytes:

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

Outputs like Just 3.


6

Cheddar, 34 29 21 bytes

Saved 8 bytes thanks to Dennis!!!

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

Uses lowercase letters

Try it online

Explanation

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

1
Or you could just put quotes around the input
— DJMcMayhem

12
@DJMcMayhem .___. i didn't even know my own language could do that
— Downgoat

How about (-)&8 instead of n->n-8?
— Conor O'Brien

@ConorO'Brien >_>_>_> I haven't gotten to that yet. I was just planning to do it and then this challenge was posted. Bassically f&n bonds n to first arg of the function.
— Downgoat

@Downgoat Oh. >_>
— Conor O'Brien

6

05AB1E, 6 bytes

{¤36ö>

Takes letters in upper case.

Explanation

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

Try it online


Forgive my naivete with 05AB1E, but do you mean convert FROM base 36 (to base 10)?
— Keeta

@Keeta You are of course correct. My bad.
— Emigna



4

JavaScript (ES6), 41 37 bytes

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

Edit: Saved 4 bytes thanks to @edc65.


use pop() to save 4
— edc65

@edc65 I can't believe that's not under JavaScript tips.
— Neil

3

Haskell, 55 40 bytes

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

Thanks @Dennis for his approach. (take that, @xnor ;))


I think you can remove f= for 38 bytes since f doesn't take explicit arguments.
— Cyoce

3

Perl 6: 18 bytes

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

Defines a lambda that takes a single string argument, and returns an integer. It splits the string into characters, finds the "highest" one, converts it to base 36, adds 1.

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

This one uses the modulo approach from Dennis. Same length.


2

Retina, 28 bytes

O`.
.\B

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

Try it online! (The first line enables a linefeed-separated test suite.)

Explanation

O`.

This sorts the characters of the input.

.\B

This removes all characters except the last, so the first two stages find the maximum character.

{2`
$`
}T01`dl`_o

These are two stages which form a loop. The first one duplicates the first character and the second one "decrements" it (replacing e.g. x with w, a with 9 and 1 with 0). The latter stage encounters a zero as the first character, it removes it instead. This is a standard technique for generating a range of characters, given the upper end. Hence, this generates all "digits" from 0 to the maximum digit.

.

Finally, we simply count the number of digits, which gives us the base.


2

R, 99 89 85 bytes

Look ! Less than 100 bytes !
Look ! 10 bytes off !
Look ! 4 bytes off !

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

Ungolfed :

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.

As often, this answer makes use of the ifelse function : ifelse(Condition, WhatToDoIfTrue, WhatToDoElse)


I love your version; however, treating letters and numbers separately creates those pesky extra bytes. Please have a look at my solution that uses a different method.
— Andreï Kostyrka

Your answer is interesting indeed. I will use the your scan method to golf some bytes ;)
— Frédéric

1

PHP, 51 38 bytes

(From Dennis) ^^

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

Other proposal without Dennis' trick

<?=($a=max(str_split($argv[1])))<a?$a+1:ord($a)-86;
  • Takes input as argument $argv[1];
  • Take max character (using ASCII) values
  • If it is a number (inferior to < 'a' ascii value) then output number+1
  • Else output ascii value -86 (97 for 'a' in ascii, -11 for 'a' is 11th base-digit)

It's too bad PHP has such verbose function names: <?=base_convert(max(str_split($argv[1])),36,10)+1 is an elegant solution, but at 49 bytes!

@YiminRong you can use intval() instead of base_convert() which shortens down to 38 bytes <?=intval(max(str_split($argn)),36)+1; tio: tio.run/##K8go@P/…
— 640KB



1

Java 7, 67 61 bytes

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

(m-8)%39 is thanks to @Dennis' amazing answer.

Ungolfed & test code:

Try it here.

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()));
  }
}

Output:

1
7
16
9
5
25
36

2
Instead of Math.max() you can use m = m>c?m:c
— RobAu

@RobAu Ah of course, thanks. Completely forgot about it.. Sometimes I forget the easiest codegolfing things in Java that are even mentioned multiple times in the Tips for Codegolfing in Java post. Thanks for the reminder.
— Kevin Cruijssen

If you switch to Java 8 you can replace this whole function with a lambda that does a single reduce
— BlueRaja - Danny Pflughoeft

@BlueRaja-DannyPflughoeft I know, which is why I specifically mentioned it as Java 7. Feel free to post a Java 8 lambda as a separate answer.
— Kevin Cruijssen

@BlueRaja-DannyPflughoeft I wonder if that would end up with less bytes..
— RobAu

1

C89, 55 53 52 50 bytes

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

-8%39 shamelessly stolen from Dennis

Test

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");
}

Output

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

Saved 2 bytes thanks to Toby Speight

Saved 2 bytes thanks to Kevin Cruijssen


You can save 2 bytes with the non-prototype declaration: f(char*s,int b) becomes f(s,b)char*s;.
— Toby Speight

You can save 3 bytes by removing the unnecessary parenthesis and space: 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 bytes

This answer assumes that the input is in ASCII (or identical in the numbers and letters, e.g. ISO-8859 or UTF-8):

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

We simply iterate along the string, remembering the largest value seen, then use the well-known modulo-39 conversion from base-{11..36}.

Test program

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

Test results

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

Couldn't you remove the m=0? If m appears at the top level of the file, its extern which implies static which implies it is initialized to zero.
— Batman

@Batman - yes, but only if you won't call f() more than once. I know that almost anything's fair game in golf, but my professional instincts regard that as too fragile!
— Toby Speight

On further thought, I could make it an external requirement to reset m between calls to f(). Then my test program could still work.
— Toby Speight

@Batman: on Code Golf Meta, the majority opinion on the question "Do function submissions have to be reusable?" seems to be against allowing single-use functions. So I'll stick with what I have. Thanks for the suggestion, anyway.
— Toby Speight

1

Mathematica, 34 32 bytes

2 bytes saved thanks to Martin Ender

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

I decided the different method deserved a new answer.

method stolen inspired by Dennis' solution


2
Use some prefix notation: Max@Mod[ToCharacterCode@#-8,39]& (same goes for your other answer)
— Martin Ender

2
Also, you need to add & to the end to indicate an anonymous function.
— LegionMammal978

You forgot one @ in both of your answers (ToCharacterCode@# and Characters@#).
— Martin Ender

1

Mathematica, 34 32 bytes

saved 2 bytes thanks to Martin Ender

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

Defines a pure function that takes a string as input.

Splits the input into characters, converts them to base 36 numbers, and returns the maximum +1.


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

1

C# REPL, 17 bytes

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

Just ported @Dennis's answer to C#.


1

CJam, 10 bytes

Thanks to Martin Ender for saving me a few bytes!

Uses Dennis's formula

q:e>8-i39%

Try it online

CJam, 18 16 btyes

Alternative solution:

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

Try it 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 bytes

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

Run it like:

$ scala whatbase.scala 0123456789abcdefghijklmnopqrstuvwxyz


1

R, 62 54 bytes

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

Ungolfed:

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"
                                                )

Update: shaved off 8 bytes due to the redundancy of na.rm=T under the assumption of input validity.

A 39% improvement in size compared to Frédéric's answer. Besides that, it runs a wee bit faster: 0.86 seconds for 100000 replications versus 1.09 seconds for the competing answer. So the one of mine is both smaller and more efficient.



0

BASH 70

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

Input letters are lowercase.


0

JavaScript, 57 50 48 bytes

7 bytes saved thnks to @kamaroso97 2 bytes saved thanks to @Neil

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

Original answer:

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

You can knock off 7 bytes with n=>Math.max(...n.split``.map(a=>parseInt(a,36)+1)).
— kamoroso94

@kamoroso94 I didn't realize Math.max existed. Thanks for telling me about it!
— DanTheMan

[...s] is shorter than s.split``.
— Neil

0

Perl, 30 27 bytes

Includes +1 for -p

Run with the input on STDIN, e.g.

base.pl <<< codegolf

base.pl:

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

0

LiveScript, 32 bytes

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

A port of this answer in my favorite language that compile to JavaScript. If base~number operator worked with variables I could write ->1+36~(it/'')sort!pop! (23 bytes), but it conflicts with the function bind operator :/

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.