В якій базі знаходиться це число?


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

8
Чи можу я вивести в базі 36?
Leaky Nun

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
Це фактично 7 байт, а не 4. Перші 2 символи є багатобайтовими.
Нікомак

14
@Nicomak Ця відповідь кодується на кодовій сторінці Jelly , де всі ці символи кодуються як 1 байт кожен.
Loovjo

26

Пітон, 27 22 байти

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

Для цього потрібно, щоб вхід був тестуванням (Python 3) або байтовим масивом (Python 2 і 3).

Дякуємо @AleksiTorhamo за те, що ти граєш на 5 байт!

Перевірте це на Ideone .

Як це працює

Почнемо з взяття максимуму рядка. Це кодові точки літер вище, ніж кодові точки цифр, цей максимальний символ також є максимальною базовою 36 цифрою.

Точки коду '0' - '9' - це 48 - 57 , тому ми повинні відняти 48 з їхніх кодових точок для обчислення відповідних цифр або 47 для обчислення найменшої можливої ​​бази. Аналогічно, кодові точки букв 'a' - 'z' - 97 - 122 . Оскільки 'a' позначає цифру зі значенням 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

Пітон, 25 байт

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

Визначає лямбда, яка приймає рядок x. Знаходить найбільшу цифру в рядку (відсортовано за літерами вище цифр, за замовчуванням python) та перетворює на базу 36. Додає 1, оскільки 8її немає в базі 8.


11

Хаскелл, 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.


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


12
@DJMcMayhem .___. Я навіть не знав, що моя власна мова могла це зробити
Downgoat

Як щодо (-)&8цього n->n-8?
Conor O'Brien

@ ConorO'Brien> _> _> _> Я до цього ще не дійшов. Я просто планував це зробити, і тоді це завдання було викладено. Басично f&nзв'язується nз першим аргументом функції.
Вниз

@Downgoat О. > _>
Conor O'Brien

6

05AB1E , 6 байт

{¤36ö>

Бере букви у великому регістрі.

Пояснення

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

Спробуйте в Інтернеті


Пробачте мою наївність з 05AB1E, але ви маєте на увазі конвертувати З бази 36 (в базу 10)?
Кіта

@Keeta Ви, звичайно, правильні. Моє ліжко.
Емінья



4

JavaScript (ES6), 41 37 байт

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

Редагувати: збережено 4 байти завдяки @ edc65.


використовувати pop()для збереження 4
edc65

@ edc65 Я не можу повірити, що це не в парадах JavaScript.
Ніл

3

Хаскелл, 55 40 байт

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

Дякуємо @Dennis за його підхід. (візьміть це, @xnor;))


Я думаю, ви можете видалити f=на 38 байт, оскільки fне беруть явних аргументів.
Кіос

3

Perl 6: 18 байт

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

Визначає лямбда, який бере аргумент одного рядка і повертає ціле число. Він розбиває рядок на символи, знаходить "найвищий", перетворює його в базу 36, додає 1.

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

У цьому використовується модульний підхід від Денніса. Однакової довжини.


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)

Безумовно:

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 .

Невикористаний і тестовий код:

Спробуйте тут.

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 Ну звичайно, дякую. Повністю забув про це .. Іноді я забуваю про найпростіші речі з кодового гольфу на Яві, про які навіть кілька разів згадується в Порадах для Codegolfing в пості Java . Дякуємо за нагадування.
Кевін Кройсейсен

Якщо ви перейдете на Java 8, ви можете замінити всю цю функцію лямбда, яка виконує єдинуreduce
BlueRaja - Danny Pflughoeft

@ BlueRaja-DannyPflughoeft Я знаю, саме тому я спеціально згадав його як Java 7. Сміливо публікуйте лямбду Java 8 як окрему відповідь.
Kevin Cruijssen

@ 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 байти завдяки Toby Speight

Збережено 2 байти завдяки Kevin Cruijssen


Ви можете зберегти 2 байти за допомогою прототипу, який не є прототипом: f(char*s,int b)стає f(s,b)char*s;.
Toby Speight

Ви можете зберегти 3 байти, видаливши непотрібні дужки та пробіл:f(s,b)char*s;{return*s?f(s+1,*s>b?*s:b):(b-8)%39;}
Кевін Круїйсен

@KevinCruijssen thx
YSC

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 з базової {{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 з'являється на верхньому рівні файлу, його зовнішній вигляд, який передбачає статичне, а це означає, що він ініціалізований до нуля.
Бетмен

@Batman - так, але тільки якщо ви не зателефонуєте f()більше одного разу. Я знаю, що майже все є чесною грою в гольф, але мої професійні інстинкти вважають це занадто крихким!
Toby Speight

З подальшої думки, я можу зробити зовнішню вимогу скидання mміж дзвінками до f(). Тоді моя тестова програма могла ще працювати.
Toby Speight

@Batman: щодо Code Golf Meta , думка більшості щодо питання " Чи потрібно подавати функції багаторазово? ", Схоже, проти дозволу функцій одноразового використання. Тож я буду дотримуватися того, що маю. Дякую за пропозицію, все одно.
Toby Speight

1

Математика, 34 32 байти

2 байти збережено завдяки Мартіну Ендеру

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

Я вирішив, що інший метод заслужив нову відповідь.

Метод крадений натхненне рішенням Денніса


2
Використовуйте позначення префікса: Max@Mod[ToCharacterCode@#-8,39]&(те саме стосується і вашої іншої відповіді)
Мартін Ендер

2
Також потрібно додати &до кінця, щоб вказати анонімну функцію.
LegionMammal978

Ви забули один @із обох своїх відповідей ( ToCharacterCode@#і Characters@#).
Мартін Ендер

1

Математика, 34 32 байти

врятував 2 байти завдяки Мартіну Ендеру

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

Визначає чисту функцію, яка приймає рядок як вхідний.

Розбиває вхід на символи, перетворює їх на базові 36 чисел і повертає максимальний +1.


Max@BaseForm[Characters@#,36]+1&
алефальфа


1

CJam, 10 байт

Дякую Мартіну Ендеру, що врятував мені кілька байт!

Використовує формулу Денніса

q:e>8-i39%

Спробуйте в Інтернеті

CJam, 18 16 btyes

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

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


1

R, 62 54 байти

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

Безголовки:

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

БАШ 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

Ви можете збити 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 байти), але це суперечить функції оператора прив'язки: /

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.