ค้นหาผลรวมของการเป็นฐานที่เป็นไปได้ทั้งหมด


20

วัตถุประสงค์ของความท้าทายนี้คือการเขียนโปรแกรมเพื่อแปลงสตริงที่ป้อนเข้าของสิ่งที่สามารถสันนิษฐานได้ว่ามีเพียงตัวอักษรและตัวเลขจากฐานจำนวนมากระหว่าง 2 ถึง 36 เท่าที่จะทำได้และค้นหาผลลัพธ์ 10 ฐาน

สายป้อนจะถูกแปลงเป็นฐานทั้งหมดซึ่งในจำนวนนี้จะถูกกำหนดตามตัวอักษรมาตรฐานสำหรับฐานถึง 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ36: ตัวอย่างเช่นอินพุต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
มี buildins สำหรับการแปลงฐานหรือไม่
lirtosiast

2
กรณีทดสอบที่สำคัญ:0
Martin Ender

Dang it ฉันจะโพสต์การท้าทายที่คล้ายกันมาก
DanTheMan

3
@ MartinBüttnerทำไมเป็น0กรณีทดสอบที่สำคัญ 0อยู่0ในทุกฐานและไม่มีสิ่งใดเช่นฐาน 1
Arcturus

3
@Eridan เนื่องจากบางภาษาอาจลองแปลงจากฐาน 1 และล้มเหลว
Martin Ender

คำตอบ:


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 (ซึ่งจะทำให้ผลลัพธ์มีขนาดใหญ่เกินไป)
Kevin W.

@FryAmTheEggman ขอบคุณ! ฉันปรับมันแล้ว
Adnan

เพียงตรวจสอบให้คุณ จะช่วยให้คุณทำtry except range(37)สองไบต์!
Sherlock9

@ Sherlock9 มันจะไม่ทำงานสำหรับอินพุตที่เป็นตัวเลขล้วน ๆ ซึ่งจะถูกตีความเป็นฐาน 10 ตัวเลข
Adnan

โอ้ใช่แล้ว @Adnan
Sherlock9

10

Pyth, 20 19 11 ไบต์

sm.xizd0S36

โจ๋งครึ่มขโมยความคิดของ Adnan จากคำตอบของ Python อย่างโจ๋งครึ่ม

ลองที่นี่


@orlp คุณสามารถลบSถ่านได้
Blue

Nope 1012ทดสอบ
orlp

4

Pure Bash (ไม่มีค่าสาธารณูปโภค), 38

อนุญาตให้สมมติว่ามีการแปลงในตัว:

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

สิ่งนี้จะส่งออกข้อผิดพลาดไปยัง STDERR ฉันสมมติว่านี่เป็น OK ตามคำตอบ metaนี้

ผลการทดสอบ:

$ 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Σ.

มี unprintables, 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?
Arcturus

@Eridan อย่างจริงจังควร - รับค่าดัชนีที่ครึ่งไบต์
Mego


2

อ็อกเทฟ75 75ไบต์

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' เป็นอินพุต


ใช้polyvalvectorize ได้อย่างชาญฉลาดมาก!
Luis Mendo

1

Japt 26 ไบต์

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

ลองออนไลน์!

Ungolfed และคำอธิบาย

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 ไม่มีการแปลงเบสในตัว -36 จากสตริงดังนั้นเราจึงต้องเขียนสตริงตัวเราเอง ฉันได้ลองทุกประเภทของ divmod shenanigans แต่ดูเหมือนว่าจะสั้นที่สุดในการสร้างสตริงของตัวเลขทั้งหมด 36 และเพียงแค่ค้นหาดัชนีของตัวละครแต่ละตัวในสตริงนั้น


q{'0-_9>7*-}%สั้น
Peter Taylor

@PeterTaylor โอ้ใช่ ...
Martin Ender

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

Testcase ล่าสุดบ่งบอกว่านี่อาจไม่เพียงพอ ถ้าเป็นเช่นนั้นแล้วด้วยจำนวนเต็ม 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 testcase ไม่เช่นนั้นอาจสั้นกว่านี้เล็กน้อย

ไดรเวอร์ทดสอบ:

#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 ++ ได้ไหม?
Alex A.

@AlexA ใช่ - ฉันไม่รู้ - ขอบคุณ!
Digital Trauma

0

Python 3, 142 ไบต์

Adnanให้ฉันเอาชนะวิธีแก้ปัญหาของพวกเขาได้อย่างสมบูรณ์ แต่ฉันต้องการเพิ่มความพยายามของตัวเอง

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

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

@ Neil คุณทดสอบมันหรือยัง? ฉันค่อนข้างแน่ใจว่าจะเป็นมือซ้ายที่ไม่ถูกต้องของงานที่มอบหมาย
user81655

ขอโทษฉันสับสนด้วยกรณีที่คล้ายกันในสนามกอล์ฟอื่น
Neil

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

Ceylon, 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 เมื่อ radix เท่ากับ 10 ) ดังนั้นเราต้องแยกกรณีนี้ออก ขอบคุณNeil ที่แนะนำวิธีการต่าง ๆ ในการทำเช่นนี้ซึ่งบันทึกได้ 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?
Neil
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.