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


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.