На какой базе находится это число?

31

Вот хороший простой вызов:

Учитывая строку, которая представляет число в неизвестной базе, определите минимально возможную базу, в которой может быть число. Эта строка будет содержать только 0-9, a-z. Если хотите, вы можете выбрать заглавные буквы вместо строчных, но, пожалуйста, укажите это. Вы должны вывести эту минимально возможную базу в десятичной форме.

Вот более конкретный пример. Если входная строка была «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
DJMcMayhem
источник
8
Можно ли вывести на базу 36?
Утренняя монахиня
9
@ LeakyNun Боже, надеюсь, нет.
Деннис
4
@LeakyNunYou must output this lowest possible base in decimal.
DJMcMayhem
3
@RohanJhunjhunwala Если ваш язык ближе всего к строке, я не понимаю, почему нет.
DJMcMayhem
3
Обычно унарное - все 1, а начальные нули не являются стандартными для любой позиционной числовой системы.
Стоп Harm Моника

Ответы:

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
На самом деле это 7 байтов, а не 4. Первые 2 символа являются многобайтовыми.
Никомак
14
@Nicomak Этот ответ закодирован в кодовой странице Jelly , где все эти символы закодированы как 1 байт каждый.
Loovjo
26

Python, 27 22 байта

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

Для этого требуется, чтобы входные данные были байтовой строкой (Python 3) или байтовой решеткой (Python 2 и 3).

Спасибо @AleksiTorhamo за 5 байтов в гольфе!

Проверьте это на Ideone .

Как это работает

Мы начинаем с того, что берем максимум строки. Это кодовые точки букв выше, чем кодовые точки цифр, этот максимальный символ также является максимальным основанием 36 цифр.

Кодовая точка '0' - '9' - это 48 - 57 , поэтому мы должны вычесть 48 из их кодовых точек, чтобы вычислить соответствующие цифры, или 47, чтобы вычислить минимально возможную базу. Точно так же кодовые точки букв «а» - «z» равны 97 - 122 . Поскольку «а» представляет цифру со значением 10 , мы должны вычесть 87 из их кодовых точек, чтобы вычислить соответствующие цифры, или 86, чтобы вычислить минимально возможное основание. Один из способов достижения этого заключается в следующем.

Разница между 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
Деннис
источник
Если вы сделаете это Python 3 и примете ввод как строку байтов, вы можете отбросить ord()и выиграть на 3 байта. :)
Алекси Торхамо
Хорошая идея! Позвольте мне спросить ОП.
Деннис
3
@AleksiTorhamo NOOOOOOOOOOOO yu do dis
Rɪᴋᴇʀ
20

Python, 25 байт

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

Определяет лямбду, которая принимает строку x. Находит самую большую цифру в строке (отсортированную по буквам над цифрами по умолчанию в python) и конвертируется в базу 36. Добавляет 1, потому что 8отсутствует в базе 8.

Rɪᴋᴇʀ
источник
11

Haskell, 34 байта

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

Использует mod(ord(c)-8,39)идею от Денниса.

41 байт

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

45 байт:

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

Выходы вроде Just 3.

XNOR
источник
6

Чеддер , 34 29 21 байт

Сохранено 8 байт благодаря Денису !!!

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

Использует строчные буквы

Попробуйте онлайн

объяснение

s -> (      // Input is `s`
  s.bytes    // Returns array of char codes
   .max      // Get maximum item in array
) % 39      // Modulus 39
Downgoat
источник
1
Или вы можете просто поместить кавычки вокруг ввода
DJMcMayhem
12
@DJMcMayhem .___. я даже не знал, что мой родной язык может это сделать
Downgoat
Как насчет (-)&8вместо n->n-8?
Конор О'Брайен
@ ConorO'Brien> _> _> _> Я еще не дошел до этого. Я просто планировал сделать это, а затем этот вызов был опубликован. Bassically f&nсвязывается nс первым аргументом функции.
Downgoat
@ Downgoat Ох. > _>
Конор О'Брайен
6

05AB1E , 6 байтов

{¤36ö>

Берет буквы в верхнем регистре.

объяснение

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

Попробуйте онлайн

Emigna
источник
Простите мою наивность с 05AB1E, но вы имеете в виду конвертировать из базы 36 (в базу 10)?
Keeta
@Keeta Вы, конечно, правы. Виноват.
Эминья
5

Юлия, 22 байта

!s=(maximum(s)-'')%39

Между кавычками есть символ BS (0x08). Попробуйте онлайн!

Деннис
источник
что делает -''?
Даунгоут
Вычитает 8 из кодовой точки и возвращает целое число.
Деннис
4

JavaScript (ES6), 41 37 байт

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

Редактировать: 4 байта сохранены благодаря @ edc65.

Нил
источник
используйте pop()для сохранения 4
edc65
@ edc65 Не могу поверить, что это не по советам JavaScript.
Нил
3

Haskell, 55 40 байт

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

Спасибо @Dennis за его подход. (возьми, @xnor;))

ThreeFx
источник
Я думаю, что вы можете удалить f=для 38 байтов, так fкак не принимает явных аргументов.
Cyoce
3

Perl 6: 18 байт

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

Определяет лямбду, которая принимает один строковый аргумент и возвращает целое число. Он разбивает строку на символы, находит самый высокий, преобразует ее в базу 36, добавляет 1.

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

Этот использует подход по модулю от Денниса. Одинаковой длины

SMLS
источник
2

Сетчатка , 28 байт

O`.
.\B

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

Попробуйте онлайн! (Первая строка включает набор тестов, разделенных переводом строки.)

объяснение

O`.

Это сортирует символы ввода.

.\B

При этом удаляются все символы, кроме последнего, поэтому первые два этапа находят максимальный символ.

{2`
$`
}T01`dl`_o

Это две стадии, которые образуют петлю. Первый дублирует первый символ, а второй «уменьшает» его (заменяя, например, xна w, aс 9и 1на 0). На последнем этапе в качестве первого символа встречается ноль, вместо этого он удаляется. Это стандартная техника для генерации диапазона символов, учитывая верхний предел. Следовательно, это генерирует все «цифры» от 0максимальной цифры.

.

Наконец, мы просто посчитаем количество цифр, которое дает нам базу.

Мартин Эндер
источник
2

R, 99 89 85 байт

Смотри ! Менее 100 байт!
Смотри ! 10 байтов!
Смотри ! 4 байта!

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.

Как часто этот ответ использует ifelseфункцию:ifelse(Condition, WhatToDoIfTrue, WhatToDoElse)

Фредерик
источник
Я люблю вашу версию; однако обработка букв и цифр отдельно создает эти надоедливые дополнительные байты. Пожалуйста, посмотрите на мое решение, которое использует другой метод.
Андрей Костырка
Ваш ответ действительно интересен. Я буду использовать ваш scanметод для игры в гольф несколько байтов;)
Фредерик
1

PHP, 51 38 байт

(От Денниса) ^^

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

Другое предложение без уловки Денниса

<?=($a=max(str_split($argv[1])))<a?$a+1:ord($a)-86;
  • Принимает входные данные в качестве аргумента $ argv [1];
  • Взять максимальные символьные (используя ASCII) значения
  • Если это число (уступающее значению <'a' ascii), выведите число + 1
  • Еще выходное значение ascii -86 (97 для «a» в ascii, -11 для «a» - 11-я базовая цифра)
крипто-
источник
Очень жаль, что в PHP есть такие подробные имена функций: <?=base_convert(max(str_split($argv[1])),36,10)+1это элегантное решение, но с 49 байтами!
@YiminRong вы можете использовать intval()вместо base_convert()которого сокращается до 38 байт <?=intval(max(str_split($argn)),36)+1;tio: tio.run/##K8go@P/…
640KB
1

Java 7, 67 61 байт

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

(m-8)%39это благодаря удивительному ответу @Dennis .

Ungolfed & тестовый код:

Попробуй это здесь.

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

Выход:

1
7
16
9
5
25
36
Кевин Круйссен
источник
2
Вместо Math.max()тебя можно использоватьm = m>c?m:c
RobAu
@RobAu Ну, конечно, спасибо. Полностью забыл об этом .. Иногда я забываю самые простые вещи в Java по кодгольфингу, которые даже упоминались несколько раз в статье « Советы по программированию в Java» . Спасибо за напоминание.
Кевин Круйссен
Если вы переключитесь на Java 8, вы можете заменить всю эту функцию лямбда-функцией, которая выполняет одинreduce
BlueRaja - Danny Pflughoeft
@ BlueRaja-DannyPflughoeft Я знаю, именно поэтому я специально упомянул это как Java 7. Не стесняйтесь публиковать лямбду Java 8 в качестве отдельного ответа.
Кевин Круйссен
@ BlueRaja-DannyPflughoeft Интересно, если бы это закончилось с меньшим количеством байтов ..
RobAu
1

C89, 55 53 52 50 байтов

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

-8%39 бесстыдно украденный у Дениса

Тест

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

Выход

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

Сохранено 2 байта благодаря Тоби Спейт

Сохранено 2 байта благодаря Кевину Круйссену

МКЦ
источник
Вы можете сохранить 2 байта с объявлением не-прототипа: f(char*s,int b)становится f(s,b)char*s;.
Тоби Спейт
Вы можете сэкономить 3 байта, удалив ненужные скобки и место:f(s,b)char*s;{return*s?f(s+1,*s>b?*s:b):(b-8)%39;}
Кевин Круйссен
@KevinCruijssen ТНХ
СМУ
1

C, 55 байтов

Этот ответ предполагает, что входные данные представлены в формате ASCII (или идентичны цифрам и буквам, например, ISO-8859 или UTF-8):

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

Мы просто выполняем итерацию по строке, помня наибольшее значение, которое видели, а затем используем хорошо известное преобразование по модулю 39 из base- {11..36}.

Тестовая программа

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

Результаты теста

00000 -> 1
123456 -> 7
ff -> 16
4815162342 -> 9
42 -> 5
codegolf -> 25
0123456789abcdefghijklmnopqrstuvwxyz -> 36
Тоби Спейт
источник
Не могли бы вы удалить m = 0? Если m появляется на верхнем уровне файла, его внешний вид, который подразумевает статический, что означает, что он инициализируется нулем.
Бэтмен
@ Бэтмен - да, но только если вы не будете звонить f()более одного раза. Я знаю, что в гольфе почти все честно, но мои профессиональные инстинкты считают это слишком хрупким!
Тоби Спейт
Если подумать дальше, я мог бы сделать это внешним требованием для сброса mмежду вызовами f(). Тогда моя тестовая программа все еще может работать.
Тоби Спейт
@Batman: в Code Golf Meta мнение большинства по вопросу « Должны ли представления функций быть повторно используемыми? », По-видимому, противоречит разрешению одноразовых функций. Поэтому я буду придерживаться того, что у меня есть. В любом случае, спасибо за предложение.
Тоби Спейт
1

Mathematica, 34 32 байта

2 байта сэкономлено благодаря Мартину Эндеру

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

Я решил, что другой метод заслуживает нового ответа.

метод украден вдохновлен решением Денниса

DanTheMan
источник
2
Используйте некоторые префиксные обозначения: Max@Mod[ToCharacterCode@#-8,39]&(то же самое относится и к вашему другому ответу)
Мартин Эндер
2
Также необходимо добавить &в конец, чтобы указать анонимную функцию.
LegionMammal978
Вы забыли один @в обоих своих ответах ( ToCharacterCode@#и Characters@#).
Мартин Эндер
1

Mathematica, 34 32 байта

сэкономил 2 байта благодаря Мартину Эндеру

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

Определяет чистую функцию, которая принимает строку в качестве входных данных.

Разбивает ввод на символы, преобразует их в базовые 36 чисел и возвращает максимум +1.

DanTheMan
источник
Max@BaseForm[Characters@#,36]+1&
алефальфа
1

C # REPL, 17 байт

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

Просто портировал @ ответ Денниса на C #.

stannius
источник
1

CJam, 10 байтов

Спасибо Мартину Эндеру за то, что он спас мне несколько байтов!

Использует формулу Денниса

q:e>8-i39%

Попробуйте онлайн

CJam, 18 16 месяцев

Альтернативное решение:

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

Попробуйте онлайн

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

Скала, 25 байт

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

Запустите это как:

$ scala whatbase.scala 0123456789abcdefghijklmnopqrstuvwxyz

AmazingDreams
источник
1

R, 62 54 байта

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

Обновление: сокращено на 8 байт из-за избыточности na.rm=Tв предположении достоверности ввода.

Увеличение размера на 39% по сравнению с ответом Фредерика . Кроме того, он работает немного быстрее: 0,86 секунды для 100000 повторов против 1,09 секунды для конкурирующего ответа. Так что один из них меньше и эффективнее.

Андрей Костырка
источник
0

Dyalog APL , 10 байт

Запрашивает ввод в верхнем регистре.

⌈/⍞⍳⍨⎕D,⎕A

⌈/ максимальная

символы ввода

⍳⍨ 1-индексируется в

⎕D, все цифры следуют

⎕A все персонажи

Попробуй APL онлайн!

Адам
источник
0

BASH 70

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

Вводимые буквы строчные.

Райли
источник
0

JavaScript, 57 50 48 байт

7 байтов сохранено благодаря @ kamaroso97 2 байта сохранено благодаря @Neil

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

Оригинальный ответ:

n=>n.split``.map(a=>parseInt(a,36)).sort((a,b)=>b-a)[0]+1
DanTheMan
источник
Вы можете сбросить 7 байтов с n=>Math.max(...n.split``.map(a=>parseInt(a,36)+1)).
kamoroso94
@ kamoroso94 Я не знал, что Math.maxсуществует. Спасибо, что рассказали мне об этом!
DanTheMan
[...s]короче чем s.split``.
Нил
0

Perl, 30 27 байт

Включает +1 для -p

Запустите с помощью ввода на STDIN, например,

base.pl <<< codegolf

base.pl:

#!/usr/bin/perl -p
\@F[unpack"W*"];$_=@F%39-9
Тон Хоспел
источник
0

LiveScript, 32 байта

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

Порт этого ответа на моем любимом языке, который компилируется в JavaScript. Если base~numberоператор работал с переменными, я мог бы написать ->1+36~(it/'')sort!pop!(23 байта), но это конфликтует с оператором связывания функции: /

Густаво Родригес
источник