ตัวแปลงฐานตัวเลขแบบกำหนดเอง


30

พลังที่ต้องการแปลงตัวเลขใด ๆ ที่พวกเขามีให้เป็นฐานหมายเลขของตนเองอย่างรวดเร็วโดยใช้รูปแบบที่พวกเขาต้องการ

อินพุต

โปรแกรมของคุณต้องยอมรับ 3 พารามิเตอร์

  1. Number: หมายเลขสตริงที่จะถูกแปลง
  2. InputFormat: สตริงฐานที่เป็นหมายเลขปัจจุบัน
  3. OutputFormat: สตริงฐานที่จะแปลงเป็นตัวเลข

เอาท์พุต

โปรแกรมของคุณต้องแปลงNumberจากเลขฐานเดิมเป็นฐานInputFormatจำนวนใหม่OutputFormat

ตัวอย่าง

("1","0123456789","9876543210") = "8"
("985724","9876543210","0123456789ABCDEF") = "37C3"
("FF","0123456789ABCDEF","0123456789") = "255"
("FF","0123456789ABCDEF","01234567") = "377"
("18457184548971248772157", "0123456789","Aa0Bb1Cc2Dd3Ee4Ff5Gg6Hh7Ii8Jj9Kk,Ll.Mm[Nn]Oo@Pp#Qq}Rr{Ss-Tt+Uu=Vv_Ww!Xx%Yy*Zz") = ",sekYFg_fdXb"

เพิ่มเติม

การทดสอบ 77 ฐานใหม่ไม่จำเป็นต้องใช้อุปกรณ์ประกอบฉากหากใช้งานได้

  1. หากในภาษาที่คุณต้องแปลงเป็นตัวเลขก่อนและถูกล็อคภายใน 32 บิตคุณสามารถข้ามได้
  2. มันเป็นการทดสอบเพิ่มเติม

ตัวอย่างทั้งหมดถูกสร้างขึ้นโดย PHP 7.2 พร้อมกับส่วนขยาย bcmath โดยใช้รหัสต่อไปนี้ (vars mins แต่จัดรูปแบบโค้ด) อาจจะมีวิธีที่สั้นกว่านี้เป็นเพียงวิธีที่ฉันใช้กับระบบที่ฉันต้องการจะทำด้วยจะดีเพื่อดูว่าใครจะมากับรุ่นที่สั้นกว่าแม้ว่า

PHP 7.2 (bcmath - ส่วนขยาย) 614 ไบต์

<?php
function f($a, $b, $c)
{
    $d= str_split($b,1);
    $e= str_split($c,1);
    $f= str_split($a,1);
    $g=strlen($b);
    $h=strlen($c);
    $k=strlen($a);
    $r='';
    if ($c== '0123456789')
    {
        $r=0;
        for ($i = 1;$i <= $k; $i++)
            $retval = bcadd($retval, bcmul(array_search($f[$i-1], $d),bcpow($g,$k-$i)));
        return $r;
    }
    if ($b!= '0123456789')
        $l=f($a, $b, '0123456789');
    else
        $l= $a;
    if ($l<strlen($c))
        return $e[$l];
    while($l!= '0')
    {
        $r= $e[bcmod($l,$h)].$r;
        $l= bcdiv($l,$h,0);
    }
    return $r;
}

ลองออนไลน์

เกณฑ์การให้คะแนน

นี่คือรหัสกอล์ฟ รหัสที่สั้นที่สุดชนะ ช่องโหว่มาตรฐานใช้


5
@WindmillCookies โดยตัวละครอะไรก็ตามที่อยู่ในสตริงรูปแบบ
อดัม

6
คำถามแรกที่ดี! :-)
Giuseppe

2
เกี่ยวข้องอย่างใกล้ชิด
AdmBorkBork

2
มันอาจจะมีมูลค่าเพิ่มกรณีทดสอบสำหรับฐาน "ไม่ซ้ำกัน" - ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb"เช่น (หรืออะไรก็ตามที่ควรจะเป็นถ้าไม่ถูกต้อง)
คดีของกองทุนโมนิก้า

2
ฉันขอแนะนำกรณีทดสอบที่มีอักขระมากกว่า 36 ตัวในรูปแบบเพื่อจับทุกคนที่ใช้บิวด์อินเท่านั้นที่จะขึ้นไปจนถึงฐาน 36
โจคิง

คำตอบ:


13

....................... คุณรู้ไหมฉันเห็นว่านั่นเป็นการZaแปลงฐาน แต่เอกสารบน matl.suever ไม่ชัดเจนว่ามันยอมรับตัวละครของฐาน ดังนั้นฉันไม่ได้ลอง ฉีกฉัน!
Giuseppe

@Giuseppe ฮ่าฮ่าฉันจำได้เพียงเพราะมันดูเหมือนว่าคำสั่งที่ใช้ในการแฮ็คที่ฉลาดหรือสองคน แดกดันว่าการใช้ครั้งแรกของฉันมันเป็นคำตอบที่สร้างขึ้นตรง :)
sundar - Reinstate Monica

1
ความคิดแรกของฉันเมื่อฉันเห็น "Za" คือ "ลอร์ดแฮร์รี่เดรสเดน" +1
คดีกองทุนของโมนิก้า

8

R , 124 ไบต์

function(n,s,t,T=L(t),N=(match(!n,!s)-1)%*%L(s)^(L(n):1-1))intToUtf8((!t)[N%/%T^rev(0:log(N,T))%%T+1])
"!"=utf8ToInt
L=nchar

ลองออนไลน์!

ฮึนี่เป็นคนบ้ามาก ฉันใช้เทคนิคการแปลงพื้นฐานทั่วไปสำหรับ R แต่การจัดการสตริงใน R ยังคงยุ่งอยู่!


น่าเสียดายที่นี่จะไม่ทำงานกับ n = "0" ... คุณควรเพิ่ม 2 ไบต์log(N+1,T)แต่บางครั้งก็ทำให้เกิดศูนย์นำหน้าบางครั้งเช่นเมื่อคุณแปลง 31 จากฐาน 10 เป็นฐาน 2 :(
digEmAll

เพื่อหลีกเลี่ยงการ "ศูนย์ปัญหา" ในลอการิทึมโดยไม่ต้องศูนย์ชั้นนำผมไม่เห็นมากของโซลูชั่นอื่น ๆ ... คุณจะทำlog(N+!N,T)แน่นอนโดยใช้!ที่มีความหมายเดิม
digEmAll

@digEmAll ความคิดเห็นของ OP ยังคงไม่ชัดเจน แต่ดูเหมือนว่าไม่จำเป็นต้องมีการสนับสนุนศูนย์
Giuseppe

โอ้ดี .. ที่ปรับแล้ว :)
digEmAll

7

APL (Dyalog Unicode) , 22 ไบต์

แลมบ์ดานิรนาม ใช้InputFormatอาร์กิวเมนต์ซ้ายและอาร์กิวเมนต์OutputFormatขวาและพร้อมต์Numberจาก stdin ถือว่า⎕IO( I ndex O rigin) 0เป็นค่าเริ่มต้นในหลาย ๆ ระบบ

{⍵[(≢⍵)⊥⍣¯1⊢(≢⍺)⊥⍺⍳⎕]}

ลองออนไลน์!

{} "dfn"; เป็นอาร์กิวเมนต์ที่เหลือคืออาร์กิวเมนต์ที่ถูกต้อง
(ตัวช่วยจำ: ปลายด้านซ้ายและขวาของตัวอักษรกรีก)

⍵[…ทำ] ดัชนีรูปแบบผลลัพธ์ด้วย:

   พรอมต์สำหรับการป้อนข้อมูล

  ⍺⍳ɩ ndices ของตัวละครเหล่านั้นในรูปแบบการป้อนข้อมูล

  ()⊥ ประเมินว่าอยู่ในฐานต่อไปนี้:

   ≢⍺ ความยาวของรูปแบบอินพุต

   ให้ผลผลิตนั้น (แยก¯1จาก(≢⍺))

  ()⊥⍣¯1 แปลงเป็นฐานต่อไปนี้:

  ≢⍺ ความยาวของรูปแบบผลลัพธ์


7

Japt, 5 ไบต์

กลับมาเล่นกอล์ฟหลังจากหยุดพัก 2 สัปดาห์

nV sW

ลองมัน


คำอธิบาย

           :Implicit input of U=Number, V=InputFormat & W=OutputFormat
 nV        :Convert U from base V to decimal
    sW     :Convert to base W string

7

C (gcc), 79 + 46 = 125 ไบต์

char*O;l,n;g(n){n/l&&g(n/l);write(1,O+n%l,1);}

สิ่งนี้จะต้องรวบรวมด้วย

-Df(s,i,o)=for(n=l=0;n=n*strlen(i)+index(i,s[l])-i,s[++l];);l=strlen(O=o);g(n)

ธง. (ใช่นี่เป็นภาพร่างที่เหลือเชื่ออย่างไม่น่าเชื่อซึ่งเป็นสาเหตุที่ฉันเก็บคำตอบเก่าไว้ด้านล่าง) นี่เป็นคำจำกัดความของแมโครfที่แสดงคำตอบของ STDOUT

ลองออนไลน์!

C (gcc), 133 131 ไบต์

char*O;l;g(n){n/l&&g(n/l);write(1,O+n%l,1);}f(s,i,o,n)char*s,*i,*o;{for(n=0,l=strlen(O=o);n=n*strlen(i)+index(i,*s)-i,*++s;);g(n);}

ลองออนไลน์!

สิ่งนี้จะกำหนดฟังก์ชั่นfที่ส่งคำตอบให้กับ STDOUT

char*O;           // declare variable to store output charset
l;                // will be set to length of O
g(n){             // helper function to print the result
  n/l&&g(n/l);    // recursively calls itself if there are more digits
  write(1,        // output to stdout...
   O+n%l,1);      // the byte at (n mod output base) in O
}
f(s,i,o,n)        // main function
char*s,*i,*o;{    // declare string inputs
for(n=0,          // initialize n to 0
l=strlen(O=o);    // assign output charset so we don't have to pass it to g
n=n*strlen(i)     // repeatedly multiply n by input base...
+index(i,*s)-i,   // ... add the index of the digit in input charset...
*++s;);           // and move to the next digit until there's none left
g(n);             // call the helper function on the resulting integer
}

คุณสามารถบันทึก 2 ไบต์โดยใช้putcharแทนwriteและเปลี่ยนวนการถอดรหัสเล็กน้อย: ลองออนไลน์!
ErikF

นี้indexฟังก์ชั่นบันทึกฉันหนึ่งไบต์เช่นเดียวกับวิธีการของฉันไม่ได้รู้เกี่ยวกับมัน;)
เฟลิกซ์ Palmen

6

05AB1E , 5 ไบต์

ÅβIÅв

ลองออนไลน์!

สิ่งนี้ทำ ได้ทำงานในรุ่นเก่าของ 05AB1E ใช้งานได้เฉพาะกับเวอร์ชั่นใหม่ Elixir เขียนใหม่เท่านั้น

มันทำงานอย่างไร

ÅβIÅв - โปรแกรมเต็มรูปแบบ
Åβ - แปลงจากฐานที่กำหนดเองเป็นทศนิยม
  I - ดันอินพุตที่สาม
   Åв - แปลงจากฐานสิบเป็นฐานที่กำหนดเอง 

คุณระบุว่าจะทำงานใน 05AB1E v2 เท่านั้น (ไม่แน่ใจว่าเป็นหมายเลขเวอร์ชั่นที่ถูกต้อง .. ) แต่คุณยังคงให้ลิงค์ TIO รุ่น Elixir มีอยู่ใน TIO แล้วหรือยัง! : S หรือใช้งานได้กับกรณีทดสอบส่วนใหญ่ แต่มีบางกรณีที่ใช้กับรุ่นใหม่ได้เท่านั้น
Kevin Cruijssen

2
05AB1E v2 พร้อมใช้งานบน TIO แล้ว 05AB1E (ดั้งเดิม) (ค้นหาในแถบ tio) คือชื่อของ 05AB1E เก่าและ 05AB1E เป็นชื่อของใหม่ ฉันรู้ว่าคุณเคยเห็นมาแล้วในห้องสนทนา แต่ฉันจะฝากไว้ที่นี่เพื่อเป็นข้อมูลอ้างอิงสำหรับผู้ใช้รายอื่น
Mr. Xcoder

5

MATL , 5 ไบต์

sundar ได้พบกับ builtin ของจริงเพื่อทำสิ่งนี้! ไปโหวตคำตอบนั้นแทนคำใบ้ของฉัน :-(

ZAwYA

ลองออนไลน์!

          % implicit input N, the number, and S, the digits of the Source base
ZA        % base2dec, convert string N using S as digits into a base 10 integer
w         % swap stack elements, with implicit input T, the digits of the Target base
YA        % dec2base, reverse the ZA operation with digits coming from T instead.

4

ถ่าน 5 ไบต์

⍘⍘SSS

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำอธิบาย:

  S     Input the "number"
   S    Input the input format
 ⍘      Convert to number using that format
    S   Input the output format
⍘       Convert to string using that format
        Implicitly print

BaseStringฟังก์ชันแปลงระหว่างจำนวนและสตริงโดยอัตโนมัติขึ้นอยู่กับชนิดของพารามิเตอร์แรก


3

Python 2 , 132 129 122 121 ไบต์

lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b)
g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)]

ลองออนไลน์!

ฟังก์ชั่นที่ไม่ระบุชื่อ (ขอบคุณ Erik the Outgolfer !) ซึ่งแปลงหมายเลขเดิมเป็นจำนวนเต็ม 10 ฐานจากนั้นส่งผ่านจำนวนเต็มและสตริงฐานใหม่ไปยังฟังก์ชัน g () ซึ่งแปลงเป็นฐานใหม่แบบเรียกซ้ำ ตอนนี้ผ่านความยาวของ OutputFormat เป็นพารามิเตอร์เพื่อ g ()

อัปเดต g () สำหรับจำนวนไบต์ที่ต่ำกว่า (ขอบคุณเดนนิส !)

ดัชนีแทนที่ () พร้อม find () (ขอบคุณMr. Xcoder !)

คำอธิบายไม่ดี

def f(n, a, b):
    # reverse the string to that the least significant place is leftmost
    # Ex: 985724 -> 427589
    n = n[::-1]
    # get the value of each place, which is its index in the InputFormat, times the base to the power of the place
    # Ex: 427589, 9876543210 -> 5*10^0, 7*10^1, 2*10^2, 4*10^3, 1*10^4, 0*10^5 -> [5,70,200,4000,10000,0]
    n = [a.find(j)*len(a)**i for i,j in enumerate(n)]
    # add all of the values together to bet the value in base 10
    # Ex: (5 + 70 + 200 + 4000 + 10000 + 0) = 14275
    n = sum(n)

    # call the convert to base function
    return g(n, b)

def g(n, c):
    # string slice, which will return an empty string if n:n+1 is not in range
    # an empty string is falsey
    if c[n:n+1]:
        return c[n:n+1]
    else:
        # get current least significant digit
        rem = c[n%len(c)]
        # get the rest of the integer
        div = n/len(c)

        # get the converted string for the rest of the integer, append the calculated least significant digit
        return g(div,c)+rem

1
คุณไม่ต้องการf=ฟังก์ชันที่ไม่ระบุชื่อจะได้รับอนุญาตตามค่าเริ่มต้น
Erik the Outgolfer

@Erik the Outgolfer อนุญาตให้ใช้เมื่อฟังก์ชั่นที่ไม่ระบุชื่อเรียกฟังก์ชันอื่นได้หรือไม่?
ตรีโกณมิติ

ตราบใดที่คุณรวมสิ่งอื่น ๆ ไว้ใน bytecount คุณก็จะได้รับอนุญาตให้กำหนดตัวแปรและนำเข้าโมดูล
Erik the Outgolfer

1
g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)]ฟังก์ชั่นผู้ช่วยที่จะกลายเป็น
Dennis

1
lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b))และอีกคนหนึ่งจะกลายเป็นหลัก
Mr. Xcoder

2

เยลลี่ 11 ไบต์

iⱮ’ḅL{ṃ⁵ṙ1¤

ลองออนไลน์!

คำสั่งอาร์กิวเมนต์: InputFormat, Number, OutputFormat อย่าลืมอ้างข้อโต้แย้งด้วยการหลบหนีที่เหมาะสม!


Hrm ไม่แน่ใจว่าฉันไม่ระบุอย่างชัดเจนคำสั่งของพารามิเตอร์ที่ ...
มาร์ตินบาร์เกอร์

@MartinBarker params ได้รับการดำเนินการตามลำดับ 2, 1, 3 ที่นี่ ฉันไม่เห็นข้อกำหนดสำหรับคำสั่งซื้อเฉพาะในสิ่งที่ท้าทายและนั่นจะทำให้หมดกำลังใจ
Erik the Outgolfer

3
@MartinBarker Pro Tip: มีความยืดหยุ่นกับสิ่งต่าง ๆ ฉันพบว่าคำสั่งของอินพุตจะไม่เกี่ยวข้องอย่างสมบูรณ์เมื่อแก้ไขงานดังนั้นฉันขอแนะนำให้คุณอนุญาตให้เรียงลำดับพารามิเตอร์ที่เลือกโดยพลการใด ๆ
Mr. Xcoder

ฉันจะปล่อยให้มันติดอยู่แค่พยายามทดสอบตอนนี้
Martin Barker

2

Pyth, 21 ไบต์

s@LeQjimx@Q1dhQl@Q1le

ชุดทดสอบ

คำอธิบาย:
s@LeQjimx@Q1dhQl@Q1le  | Code
s@LeQjimx@Q1dhQl@Q1leQ |  with implicit variables
       m               | Map the function
        x   d          |   index of d in
         @Q1           |    the second string in the input
             hQ        |  over the first string in the input
      i                | Convert the resulting list to int from base
               l@Q1    |  length of the second string in the input
     j                 | Convert the int into a list in base
                   leQ |  length of the last string in the input
 @LeQ                  | Turn each number in the list into the character from the numbers index in the last string in the input
s                      | Concatenate the strings in to one string
                       | Implicit print


2

Perl 6 , 100 97 ไบต์

{$^c.comb[(":"~$^b.chars~[$^a.comb>>.&{index $b,$_}].perl).EVAL.polymod($c.chars xx*)].join.flip}

ลองออนไลน์!

บล็อกโค้ดแบบไม่ระบุชื่อที่ใช้ 3 สตริงตามลำดับอินพุตรูปแบบอินพุตและรูปแบบเอาต์พุตจากนั้นส่งคืนสตริง

คำอธิบาย:

{  # Anonymous code block
  $^c.comb[  # Split the output format into characters
           (":"~$^b.chars~[$^a.comb>>.&{index $b,$_}].perl) # The radix syntax in a string e.g ":3[1,2,3]"
           .EVAL  # Eval'ed to produce the base 10 version
           .polymod($c.chars xx*)  # Converted to a list in the output base (reversed)
          ] # Convert the list into indexes of the output format
           .join  # Join the characters to a string
           .flip  # And unreversed
}

2

VBA ขนาด 182 ไบต์

subroutine ที่ประกาศซึ่งจะมีการป้อนข้อมูลnในภาษาและโครงการที่เป็นภาษาyz

Sub f(n,y,z)
l=Len(n)
For i=-l To-1
v=v+(InStr(1,y,Mid(n,-i,1))-1)*Len(y)^(l+i)
Next
l=Len(z)
While v
v=v-1
d=v Mod l+1
v=v\l
If d<0Then v=v+1:d=d-l
o=Mid(z,d+1,1)&o
Wend
n=o
End Sub

2

JavaScript (ES6), 90 86 ไบต์

(input_format)(output_format)(number)จะเข้าเป็น

s=>d=>g=([c,...n],k=0)=>c?g(n,k*s.length+s.search(c)):k?g(n,k/(l=d.length)|0)+d[k%l]:n

ลองออนไลน์!


ขออภัยนี่ไม่ถูกต้องเนื่องจากคุณเปลี่ยนรูปแบบการป้อนข้อมูลของสตริงเป็นอาร์เรย์ที่ไม่ใช่สิ่งที่สามารถทำได้ผ่านอินพุต CLI และจะต้องตั้งโปรแกรมให้คุณต้องแบ่งสตริงออกเป็นอาร์เรย์สำหรับพารามิเตอร์แรกเพื่อให้ถูกต้อง
Martin Barker

@MartinBarker คุณหมายถึงกฎใด อัปเดตให้ใช้ 3 สายอยู่แล้ว
Arnauld

พารามิเตอร์อินพุตทั้ง 3 ตัวระบุว่า "string" เป็น C ++ สตริงสามารถอ่านได้โดยตรงและใช้เป็นอาร์เรย์ที่มี javascript ซึ่งไม่สามารถทำได้
Martin Barker

1

C (gcc) , 130 129 ไบต์

v;c(r,i,s,t)char*r,*i,*t;{for(r[1]=v=0;*i;v=v*strlen(s)+index(s,*i++)-s);for(s=strlen(t),i=1;*r=t[v%s],v/=s;memmove(r+1,r,++i));}

ลองออนไลน์!

-1 ไบต์ใช้indexแทนstrchrแทน

นี่เป็นวิธีการทำซ้ำแบบง่าย ๆ โดยใช้ตัวแปรบางอย่างซ้ำอีกครั้ง (และการใช้sizeof(int) == sizeof(char *)TIO ในทางที่ผิด) เพื่อบันทึกไบต์

การป้อนข้อมูล:

  • i หมายเลขอินพุต
  • s ตัวละครฐานที่มา
  • t ตัวละครฐานเป้าหมาย

เอาท์พุท:

  • r หมายเลขผลลัพธ์ (ตัวชี้ไปยังบัฟเฟอร์)

คำอธิบาย:

v;                                        // value of number
c(r,i,s,t)char*r,*i,*t;{
    for(r[1]=v=0;                         // initialize value and second
                                          // character of output to 0
        *i;                               // loop while not at the end of
                                          // input string
         v=v*strlen(s)+index(s,*i++)-s);  // multiply value with source base
                                          // and add the value of the current
                                          // digit (position in the base string)
    for(s=strlen(t),i=1;                  // initialize s to the length of the
                                          // target base string, length of
                                          // result to 1
        *r=t[v%s],v/=s;                   // add character for current digit
                                          // (value modulo target base) and
                                          // divide value by target base until
                                          // 0 is reached
        memmove(r+1,r,++i));              // move result string one place to
                                          // the right
}

แนะนำbcopy(r,r+1,++i)แทนmemmove(r+1,r,++i)
ceilingcat


1

Java 10, 131 ไบต์

แลมบ์ดารับพารามิเตอร์ตามลำดับเป็นสตริงและส่งคืนสตริง

(i,f,o)->{int n=0,b=o.length();var r="";for(var c:i.split(r))n=n*f.length()+f.indexOf(c);for(;n>0;n/=b)r=o.charAt(n%b)+r;return r;}

ลองใช้ออนไลน์

Ungolfed

(i, f, o) -> {
    int n = 0, b = o.length();
    var r = "";
    for (var c : i.split(r))
        n = n * f.length() + f.indexOf(c);
    for (; n > 0; n /= b)
        r = o.charAt(n % b) + r;
    return r;
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.