Найти сумму всех возможных базовых представлений


20

Целью этой задачи является написание программы для преобразования введенной строки, которая может быть принята как содержащая только буквы и цифры из максимально возможного числа оснований от 2 до 36, и поиска суммы результатов по основанию 10.

Входная строка будет преобразована для всех оснований , в которых число будет определяться в соответствии со стандартом алфавита для баз до 36: 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ. Например, ввод 2Tбудет действительным только в базах 30 и выше. Программа преобразует 2T из оснований с 30 по 36 в десятичное и суммирует результаты.

Вы можете предположить, что входная строка содержит только буквы и цифры. Ваша программа может использовать прописные или строчные буквы; он может, но не должен, поддерживать оба.


Контрольные примеры

Пример ввода: 2T

Схема возможных баз

Base   Value
30     89
31     91
32     93
33     95
34     97
35     99
36     101

Выход: 665

Пример ввода: 1012

Схема возможных оснований:

Base   Value
3      32
4      70
5      132
6      224
7      352
8      522
9      740
10     1012
11     1344
12     1742
13     2212
14     2760
15     3392
16     4114
17     4932
18     5852
19     6880
20     8022
21     9284
22     10672
23     12192
24     13850
25     15652
26     17604
27     19712
28     21982
29     24420
30     27032
31     29824
32     32802
33     35972
34     39340
35     42912
36     46694

Выход: 444278

Пример ввода: HELLOworld

Схема возможных баз

Base   Value
33     809608041709942
34     1058326557132355
35     1372783151310948
36     1767707668033969

Выход: 5008425418187214

Ввод 0будет читаться как 0во всех базах от 2 до 36 включительно. Там нет такого понятия, как база 1.


Это код гольф. Стандартные правила применяются. Самый короткий код в байтах побеждает.


5
Разрешены ли встроенные функции для преобразования базы?
lirtosiast

2
Важный контрольный пример:0
Мартин Эндер

Черт возьми, я собирался опубликовать очень похожий вызов.
DanTheMan

3
@ MartinBüttner Почему 0важен контрольный пример? 0есть 0в каждой базе, и нет такой вещи, как база 1.
Арктур

3
@Eridan, потому что некоторые языки могут попытаться преобразовать это из базы 1 и потерпеть неудачу.
Мартин Эндер

Ответы:


12

Python 3, 72 71 69 байт

Спасибо FryAmTheEggman за сохранение байта!

Спасибо DSM за сохранение 2 байта!

N=x=0
y=input()
while N<36:
 N+=1
 try:x+=int(y,N)
 except:0
print(x)

@ThomasKwa, который добавит ноль, который не будет работать для чисто числовых входов, так как он работает как проверка, является ли его основание 10 (что приведет к некоторым результатам слишком большим)
Кевин В.

@FryAmTheEggman Спасибо! Я настроил это
Аднан

Только что проверил для тебя. Это try exceptпозволит вам сделать range(37). Два байта!
Sherlock9

@ Sherlock9 Он не будет работать для чисто числовых входов, они будут интерпретироваться как цифры 10.
Аднан

Ах да, черт возьми. @Adnan
Sherlock9


4

Чистый Баш (без коммунальных услуг), 38

Предполагая, что встроенные базовые преобразования разрешены:

for((b=36;s+=$b#$1;b--));{ :;}
echo $s

Это выведет ошибку в STDERR. Я предполагаю, что это нормально в соответствии с этим мета-ответом .

Тестовый вывод:

$ for t in 0 2T 1012 HELLOworld; do ./basesum.sh $t; done 2> /dev/null
0
665
444278
5008425418187214
$ 

3

Mathematica, 57 байт

#~Sum~{x,Max@CoefficientList[#,x]+1,36}&@FromDigits[#,x]&

Вы можете использовать инфиксную форму для FromDigits.
LegionMammal978

3

Серьезно, 65 байтов

,û;╗rk`"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu`MSd:37:@x`╜¿`MΣ.

Содержит непечатные, hexdump:

2c963bbb726b6022303132333435363738394142434445464748494a4b4c4d4e4f505152535455565758595a22a175604d53643a33373a407860bda8604de42e7f

К сожалению, у меня нет хорошего способа фильтрации из списка по типам. Примечание для себя: добавьте это.

Принимает вход как "2T"

Попробуйте онлайн (вам нужно будет вручную ввести ввод)

Объяснение:

,û    get input and convert to uppercase
;╗    make a copy and save to register 0
rk    explode string into list
`"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu`M  map the function over the list:
    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"íu    get the character's index in the string and add one to get a value in [1,36]
Sd    get maximum element (maximum base aka max_base) from list by sorting and popping the last element off and pushing it to the stack
:37:@x  push range(max_base,37)
`╜¿`M  map the function over the list:
    ╜¿    convert value in register 0 to an int, interpreting it as a base-n int (n is value from list)
Σ.    sum and print
0x7f  quit

Возможно, серьезно должна быть команда, которая выдает алфавит и / или цифры 0-9?
Арктур

@Eridan Это серьезно должно - получение этого индекса стоит половину байтов.
Мего


2

Октава, 75 73 байта

function v=u(a) m([48:57 65:90])=0:35;v=sum(polyval(t=m(a),max(t)+1:36));

Объяснение:

function v=u(a) 
   m([48:57 65:90])=0:35; %// create a map: '0'-'9' = 0-9
                          %//               'A'-'Z' = 10-35
   t=m(a);                %// convert string to mapped values
   b=max(t)+1;            %// find minimum base
   p=polyval(t,b:36);     %// calculate polynomial for each base (vectorized)
   v=sum(p);              %// and return the sum of the resulting vector

polyvalимеет преимущество перед base2decтем, что оно векторизовано, поэтому forцикл не требуется.

Только '0' .. '9' и прописные буквы 'A' .. 'Z' поддерживаются в качестве входных данных.


Очень умное использование polyvalдля векторизации!
Луис Мендо

1

Japt , 26 байт

1+U¬r@XwYn36}0)o37 £UnX} x

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

Неуправляемый и объяснение

1+U¬ r@   XwYn36}0)o37 £    UnX} x
1+Uq rXYZ{XwYn36}0)o37 mXYZ{UnX} x

           // Implicit: U = input string
Uq rXYZ{   // Split U into chars, and reduce each item Y and previous value X by:
XwYn36     //  Choosing the larger of X and parseInt(Y,36),
}0         // starting at 0.
1+   )o37  // Add 1 and create a range from this number to 36.
mXYZ{UnX}  // Map each item X in this range to parseInt(U,X)
x          // and sum.
           // Implicit: output last expression


1

CJam, 28 27 байтов

Спасибо Reto Koradi за сохранение 1 байта.

Это немного ужасно ...

qA,s'[,65>+f#_:e>)37,>\fb:+

Требуются заглавные буквы.

Проверьте это здесь.

CJam не имеет встроенного преобразования base-36 из строк, поэтому мы должны сами выводить строки. Я пробовал все виды divmod shenanigans, но, кажется, самое короткое, чтобы построить строку из всех 36 цифр и просто найти индекс каждого символа в этой строке.


q{'0-_9>7*-}%это так же коротко.
Питер Тейлор

@PeterTaylor О, верно ...
Мартин Эндер

1

Функция C, 93 (только 32-разрядное целое число)

Предполагая, что все в порядке, если выходные данные доходят только до INT_MAX, тогда мы можем сделать это:

i,n,x;f(char *s){char *e;for(i=36,x=0;n=strtol(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%d\n",x);}

Последний тестовый пример подразумевает, что этого, вероятно, недостаточно. Если так, то с 64-битными целыми числами мы имеем:

Функция С, 122

#include<stdlib.h>
f(char *s){long long i=36,n,x=0;char *e;for(;n=strtoll(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%lld\n",x);}

К сожалению, #include <stdlib.h>требуется, поэтому тип возвращаемого значения strtoll()правильный. Нам нужно использовать long longдля обработки HELLOworldтеста. В противном случае это может быть немного короче.

Тестовый водитель:

#include<stdlib.h>
f(char *s){long long i=36,n,x=0;char *e;for(;n=strtoll(s,&e,i--),!*e&&i;)x+=*e?0:n;printf("%lld\n",x);}

int main (int argc, char **argv)
{
    f("0");
    f("2T");
    f("1012");
    f("HELLOworld");
}

Тестовый вывод:

$ ./basesum
0
665
444278
5008425418187214
$ 

В C вы можете удалить пространство, #include <stdlib.h>как вы можете в C ++?
Алекс А.

@AlexA. Да, я этого не знал, спасибо!
Цифровая травма

0

Python 3, 142 байта

Аднан добился от меня удачного решения, но я хотел добавить свою попытку.

def f(s):
 t=0
 for x in range(37):
  n=0
  for i in s:
   try:m=int(i)
   except:m=ord(i)-55
   if x<=m:n=0;break
   n=n*x+m
  t+=n
 return t

Эта функция обрабатывает только заглавные буквы. Добавьте .upper()к for i in s, и он будет обрабатывать как прописные, так и строчные буквы.


0

Scala 2.11, 93 байта

Это запускается на консоли Scala.

val i=readLine
var s=0
for(j<-2 to 36)try{s=s+Integer.parseInt(i,j)}catch{case _:Exception=>}

0

Haskell, 97 байт

i c|'_'<c=fromEnum c-87|1<2=read[c]
f s=sum$map((`foldl1`map i s).((+).).(*))[1+i(maximum s)..36]

Поддерживает только строчные буквы. Пример использования:

f "2t"           -> 665
f "helloworld"   -> 5008425418187214

Это так масштабно, потому что я должен сам реализовать как преобразование символов в ASCII, так и базовое преобразование. Соответствующие предопределенные функции находятся в модулях, которые требуют еще более дорогого импорта.

Как это работает: iпреобразовывает символ cв его цифровое значение (например, i 't'-> 29). fвычисляет значение входной строки для каждой возможной базы и суммирует ее. Вариант без pointfree внутренней петли map (\base -> foldl1 (\value digit -> value*base + digit) (map i s)) [ ...bases... ].


0

JavaScript (ES6), 86 байт

s=>eval(`p=parseInt;b=2;[...s].map(d=>(v=p(d,36))>b?b=v:0);for(r=0;++b<37;)r+=p(s,b)`)

объяснение

s=>
  eval(`                     // use eval to enable for loop without return keyword or {}
    p=parseInt;
    b=2;                     // b = minimum base of s
    [...s].map(d=>           // iterate through each digit d
      (v=p(d,36))            // get it's base-36 value
        >b?b=v:0             // set b to the max value
    );
    for(r=0;++b<37;)         // r = sum of all base values
      r+=p(s,b)              // add each base value from b to 36 to r
  `)                         // implicit: return r

Тестовое задание


&&b=vсохраняет 1 байт над ?b=v:0.
Нил

@Neil Вы проверяли это? Я почти уверен, что это будет недействительной левой рукой назначения.
user81655

Извините, я перепутал это с аналогичным случаем в другом гольфе.
Нил

0

Perl 6 , 35 байт

{[+] map {+(":$^a"~"<$_>")||0},^37}

использование:

# store it somewhere
my &code = {[+] map {+(":$^a"~"<$_>")||0},^37}

say code 'HELLOworld' # 5008425418187214

say map &code, <2T 1012>
# (665 444278)

say code 'qwertyuiopasdfghjklzxcvbnm1234567890'
# 79495849566202185148466281109757186006261081372450955140

0

Цейлон, 100 96 байт

Integer b(String s)=>sum(((any(s*.letter)then 11else 2)..36).map((r)=>parseInteger(s,r)else 0));

Сначала у меня была эта более простая версия, занимающая всего 69 байт:

Integer b(String s)=>sum((2..36).map((r)=>parseInteger(s,r)else 0));

Но это терпит неудачу с первым контрольным примером, возвращая 2000000000665вместо 665. ( Причина в том, что Tin 2Tанализируется как Tera, то есть умножает 2 на 10 ^ 12, когда основание равно 10. ) Поэтому нам нужно уловить этот случай отдельно. Спасибо Нейлу за то, что он предложил другой способ сделать это, сохранив 4 байта.

отформатирован:

// Find sum of all possible base representations.
//
// Question:  /codegolf//q/65748/2338
// My Answer: /codegolf//a/65836/2338

Integer b(String s) =>
// take the sum of ...
        sum(
    // span from 2 to 36. (Though
    // if there are letters in there, we start at 11,
    // because the other ones can't be valid.
    // Also, parseInteger(s, 10) behaves a bit strange in Ceylon.)
    ((any(s*.letter) then 11 else 2) .. 36)
    // map each r of them to ...
        .map((r) =>
            // try parsing s as a number using base r
            parseInteger(s, r)
            // if that didn't succeed, use 0.
                    else 0
    )
);

Можете ли вы сократить код, начиная с базы 11, если строка содержит букву, избегая, таким образом, необходимости использовать базу 10 для особых случаев?
Нил
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.