Знайдіть суму всіх можливих базових уявлень


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

Пітон 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 (що зробить деякі результати занадто великими)
Kevin W.

@FryAmTheEggman Дякую! Я його скоригував
Аднан

Щойно перевірили для вас. try exceptДозволить вам робити range(37). Два байти!
Шерлок9

@ 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

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

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

Містить недруковані матеріали, шістнадцятковий

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

C функція, 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

Пітон 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

Це настільки масово, тому що я повинен сам реалізувати як char-to-ASCII, так і базові перетворення. Відповідні попередньо визначені функції знаходяться в модулях, які потребують ще дорожчого імпорту.

Як це працює: iперетворює персонаж cу його цифрне значення (наприклад i 't'-> 29). fобчислює значення вхідного рядка для кожної можливої ​​бази та підсумовує його. Неточкова версія внутрішнього циклу є 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 Ви тестували? Я майже впевнений, що це було б недійсним лівим завданням.
користувач81655

Вибачте, що я переплутав це з подібним випадком в іншому гольфі.
Ніл

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.