Chuyển đổi số cơ sở tùy chỉnh


30

Các quyền hạn muốn có thể nhanh chóng chuyển đổi bất kỳ số nào họ có thành cơ sở số riêng của họ bằng bất kỳ định dạng nào họ muốn.

Đầu vào

Chương trình của bạn phải chấp nhận 3 tham số.

  1. Số: Số chuỗi cần chuyển đổi
  2. InputFormat: chuỗi cơ sở số hiện đang ở
  3. OutputFormat: chuỗi cơ sở mà số sẽ được chuyển đổi thành.

Đầu ra

Chương trình của bạn phải chuyển đổi Numbertừ cơ sở số cũ InputFormatsang cơ sở số mớiOutputFormat

Ví dụ

("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"

Bổ sung

Thử nghiệm cơ sở 77 mới không bắt buộc phải có đạo cụ nếu nó hoạt động

  1. nếu ngôn ngữ của bạn là nơi bạn phải chuyển đổi thành số trước và bị khóa trong 32Bit, bạn có thể bỏ qua ngôn ngữ đó.
  2. vì nó là một bài kiểm tra bổ sung.

Tất cả các ví dụ được tạo bởi PHP 7.2 với phần mở rộng bcmath bằng cách sử dụng đoạn mã sau (vars phút nhưng mã được định dạng). có lẽ sẽ có một cách ngắn hơn, đây chỉ là cách tôi nghĩ ra cho hệ thống mà tôi cần để làm điều này với nó sẽ rất tuyệt để xem liệu có ai có thể đưa ra một phiên bản ngắn hơn hay không.

PHP 7.2 (bcmath - phần mở rộng) 614 byte

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

Dùng thử trực tuyến

Chấm điểm

Đây là mã golf; mã ngắn nhất thắng. Tiêu chuẩn áp dụng.


5
@WindmillCookies Bằng bất cứ ký tự nào trong chuỗi định dạng.
Adám

6
Câu hỏi đầu tiên rất hay! :-)
Giuseppe


2
Nó có thể là giá trị thêm một trường hợp thử nghiệm cho một cơ sở "độc đáo" - ví dụ ["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb". (hoặc bất cứ điều gì thực sự nên, nếu điều đó không chính xác)
Vụ kiện của Quỹ Monica

2
Tôi muốn đề xuất một trường hợp thử nghiệm có hơn 36 ký tự ở các định dạng, để bắt bất kỳ ai sử dụng các phần dựng sẵn chỉ đi lên cơ sở 36
Jo King

Câu trả lời:


13

....................... bạn biết đấy, tôi đã thấy rằng Zađã chuyển đổi cơ sở nhưng các tài liệu trên matl.suever không rõ ràng rằng nó chấp nhận các ký tự của cơ sở, Vì vậy, tôi đã không thử nó. RIP tôi!
Giuseppe

@Giuseppe Haha, tôi chỉ nhớ nó bởi vì nó có vẻ như là một lệnh đã chín muồi để sử dụng trong một số hack thông minh. Trớ trêu rằng lần đầu tiên tôi sử dụng nó là một câu trả lời dựng sẵn. :)
- Phục hồi Monica

1
Suy nghĩ đầu tiên của tôi khi nhìn thấy "Za" là "chúa tể, Harry Dresden". +1.
Vụ kiện của Quỹ Monica

8

R , 124 byte

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

Hãy thử trực tuyến!

Ugh, đây là một doozy. Tôi sử dụng các thủ thuật chuyển đổi cơ sở điển hình cho R, nhưng các thao tác chuỗi trong R vẫn còn lộn xộn!


Thật không may, điều này sẽ không hoạt động với n = "0" ... đôi khi bạn nên thêm 2 byte log(N+1,T)nhưng lại tạo ra số 0 đứng đầu, ví dụ như khi bạn chuyển đổi 31 từ cơ sở 10 sang cơ sở 2 :(
digEmAll

Để tránh "vấn đề không" trên logarit mà không dẫn số 0, tôi không thấy nhiều giải pháp khác ... tất nhiên bạn có thể log(N+!N,T)sử dụng !với nghĩa gốc
digEmAll

@digEmAll Nhận xét của OP vẫn chưa rõ ràng một chút, nhưng có vẻ như không cần phải hỗ trợ.
Giuseppe

Oh well .. vậy là tốt rồi :)
digEmAll

7

APL (Dyalog Unicode) , 22 byte

Vô danh lambda. Đưa ra InputFormatnhư đối số bên trái và đối số OutputFormatbên phải và nhắc nhở Numbertừ stdin. Giả sử ⎕IO( I ndex O rigin) 0là mặc định trên nhiều hệ thống.

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

Hãy thử trực tuyến!

{... } "DFN"; là đối số bên trái, là đối số bên phải
(mnemonic: bên trái và bên phải của bảng chữ cái Hy Lạp)

⍵[... ] chỉ số định dạng đầu ra với những điều sau đây:

   nhắc nhở cho đầu vào

  ⍺⍳thông tin về các ký tự đó ở định dạng đầu vào

  (Đánh )⊥ giá như là trong cơ sở sau đây:

   ≢⍺ độ dài của định dạng đầu vào

   mang lại (tách ¯1từ (≢⍺))

  (... )⊥⍣¯1 chuyển đổi để các cơ sở sau:

  ≢⍺ độ dài của định dạng đầu ra


7

Japt, 5 byte

Dễ dàng trở lại golf sau khi nghỉ 2 tuần

nV sW

Thử nó


Giải trình

           :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 byte

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

Điều này phải được biên dịch với

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

cờ. (Vâng, điều này cực kỳ sơ sài, đó là lý do tại sao tôi giữ câu trả lời cũ của mình bên dưới.) Điều này xác định một macro fđưa ra câu trả lời cho STDOUT.

Hãy thử trực tuyến!

C (gcc), 133 131 byte

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

Hãy thử trực tuyến!

Điều này xác định một hàm fđưa ra câu trả lời cho 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
}

Bạn có thể lưu 2 byte bằng cách sử dụng putcharthay vì writevà thay đổi vòng lặp giải mã một chút: Hãy thử trực tuyến!
ErikF

indexHàm này đã tiết kiệm cho tôi một byte cũng như cách tiếp cận của tôi, không biết về nó;)
Felix Palmen

6

05AB1E , 5 byte

ÅβIÅв

Hãy thử trực tuyến!

Điều này không hoạt động trong phiên bản kế thừa của 05AB1E. Nó chỉ hoạt động trên phiên bản mới, Elixir viết lại.

Làm thế nào nó hoạt động

ÅβIÅв - Chương trình đầy đủ.
- Chuyển đổi từ cơ sở tùy chỉnh sang thập phân.
  I - Đẩy đầu vào thứ ba.
   Åв - Chuyển đổi từ số thập phân sang cơ sở tùy chỉnh. 

Bạn nói rằng nó chỉ hoạt động trong 05AB1E v2 (không chắc đó có phải là số phiên bản chính xác không ..), nhưng bạn vẫn cung cấp liên kết TIO. Phiên bản Elixir đã có trên TIO?! : S Hoặc nó hoạt động cho hầu hết các trường hợp thử nghiệm, nhưng có một số trường hợp cạnh mà nó chỉ hoạt động trong phiên bản mới?
Kevin Cruijssen

2
05AB1E v2 hiện có sẵn trên TIO. 05AB1E (di sản) (tìm kiếm trong thanh tio) là tên của 05AB1E cũ và 05AB1E là tên của cái mới. Tuy nhiên, tôi biết rằng bạn đã thấy điều đó trong phòng chat, nhưng tôi sẽ để nó ở đây làm tài liệu tham khảo cho những người dùng khác.
Ông Xcoder

5

MATL , 5 byte

chủ nhật tìm thấy các nội dung thực sự để làm điều này! Đi lên câu trả lời thay vì câu trả lời ngu ngốc của tôi :-(

ZAwYA

Hãy thử trực tuyến!

          % 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

Than , 5 byte

⍘⍘SSS

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

  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

Các BaseStringchức năng tự động chuyển đổi giữa số lượng và chuỗi tùy thuộc vào kiểu của tham số đầu tiên.


3

Python 2 , 132 129 122 121 byte

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)]

Hãy thử trực tuyến!

Hàm ẩn danh (cảm ơn, Erik Outgolfer !) Chuyển đổi số gốc thành số nguyên 10, sau đó chuyển số nguyên và chuỗi cơ sở mới sang hàm g (), chuyển đổi đệ quy sang cơ sở mới. Bây giờ chuyển chiều dài của OutputFormat làm tham số cho g ().

Đã cập nhật g () cho một bytecount thấp hơn. (cảm ơn, Dennis !)

Thay thế chỉ mục () bằng find (). (cảm ơn, ông Xcoder !)

Giải thích bất đắc dĩ:

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
Bạn không cần f=, các chức năng ẩn danh được cho phép theo mặc định.
Erik the Outgolfer

@Erik the Outgolfer Có được phép khi hàm ẩn danh gọi hàm khác không, tho?
Triggernometry

Miễn là bạn bao gồm các nội dung khác trong tài khoản phụ của mình, có, bạn được phép xác định các biến và nhập mô-đun.
Erik the Outgolfer

1
Hàm helper có thể trở thành g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)].
Dennis

1
Và cái chính có thể trở thành lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b)).
Ông Xcoder

2

Thạch , 11 byte

iⱮ’ḅL{ṃ⁵ṙ1¤

Hãy thử trực tuyến!

Thứ tự đối số: InputFormat, Number, OutputFormat. Hãy chắc chắn để trích dẫn các đối số với thoát thích hợp!


Hrm không chắc chắn tôi đã nói rõ thứ tự của các thông số ...
Martin Barker

@MartinBarker Các thông số được lấy theo thứ tự 2, 1, 3 tại đây. Tôi không thể thấy một yêu cầu cho một thứ tự cụ thể trong thử thách, và điều đó sẽ không được khuyến khích.
Erik the Outgolfer

3
@MartinBarker Pro Mẹo: Hãy linh hoạt với những điều như vậy. Tôi thấy thứ tự của các đầu vào là hoàn toàn không liên quan khi giải quyết một nhiệm vụ, vì vậy tôi khuyên bạn nên cho phép bất kỳ thứ tự nào được chọn tùy ý của các tham số
Ông Xcoder

tôi sẽ để cho nó dính dù sao chỉ cố gắng để kiểm tra nó bây giờ.
Martin Barker

2

Bình thường, 21 byte

s@LeQjimx@Q1dhQl@Q1le

Bộ kiểm tra

Giải trình:
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 byte

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

Hãy thử trực tuyến!

Khối mã ẩn danh có 3 chuỗi theo thứ tự, đầu vào, định dạng đầu vào và định dạng đầu ra, sau đó trả về một chuỗi

Giải trình:

{  # 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 byte

Một chương trình con được khai báo sẽ nhận đầu vào n, bằng ngôn ngữ yvà các dự án thành ngôn ngữ z.

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 byte

Đưa đầu vào là (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

Hãy thử trực tuyến!


Xin lỗi, điều này không hợp lệ vì việc bạn thay đổi định dạng đầu vào của chuỗi thành một mảng không phải là điều có thể được thực hiện thông qua đầu vào CLI. và phải được lập trình, bạn cần chia chuỗi thành mảng để tham số đầu tiên có hiệu lực.
Martin Barker

@MartinBarker Bạn đang đề cập đến quy tắc nào? Cập nhật để có 3 chuỗi nào.
Arnauld

Tất cả 3 tham số đầu vào đều nói "chuỗi" là C ++, một chuỗi có thể được đọc trực tiếp và được sử dụng như một mảng với javascript.
Martin Barker

1

C (gcc) , 130 129 byte

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

Hãy thử trực tuyến!

-1 byte sử dụng indexthay vì strchr.

Đây là một cách tiếp cận lặp đơn giản, sử dụng lại một số biến (và do đó lạm dụng sizeof(int) == sizeof(char *) trên TIO) để lưu byte.

Đầu vào:

  • i số đầu vào
  • s ký tự cơ sở nguồn
  • t nhân vật cơ sở mục tiêu

Đầu ra:

  • r số kết quả (con trỏ tới bộ đệm)

Giải trình:

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
}

Đề xuất bcopy(r,r+1,++i)thay vìmemmove(r+1,r,++i)
trần


1

Java 10, 131 byte

Một lambda lấy các tham số theo thứ tự như chuỗi và trả về một chuỗi.

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

Dùng thử trực tuyến

Ung dung

(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;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.