自定义号码基础转换器


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"

额外

如果可以,新的base 77测试不是必需的道具

  1. 如果您使用的语言必须先转换为数字并且被锁定在32Bit以内,则可以跳过它。
  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
不错的第一个问题!:-)
朱塞佩


2
可能需要为“独特的”基础添加测试用例-例如["zX", "tXdsyqzSDRP02", "brFNC02bc"] => "cb"。(或者,如果不正确的话,实际上应该是什么)
基金莫妮卡的诉讼

2
我建议您使用一个格式超过36个字符的测试用例,以捕获仅使用基数不超过36的内置程序的任何人
Jo King

Answers:


13

.......................您知道,我看到它Za进行了基准转换,但是关于matl.suever的文档尚不清楚它是否接受了基准字符,所以我没有尝试。撕我!
朱塞佩

@Giuseppe哈哈,我之所以记得它,只是因为它看起来像是在一些聪明的技巧中使用(滥用)的成熟命令。具有讽刺意味的是,我第一次使用它是一种直接的内置答案。:)
sundar-恢复莫妮卡

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

在线尝试!

gh,这真是个笨蛋。我对R使用了典型的基本转换技巧,但是R中的字符串操作仍然很杂乱!


不幸的是,这不适用于n =“ 0” ...您应该添加2个字节,log(N+1,T)但是有时会导致前导零,例如,当您将31从10转换为2时:(
digEmAll

为了避免对数中没有前导零的“零问题”,我没有看到很多其他解决方案……您log(N+!N,T)当然可以使用!原始含义
digEmAll

@digEmAll OP的注释仍然不清楚,但是似乎不需要支持零。
朱塞佩

哦,好..那很好:)
digEmAll

7

APL(Dyalog Unicode),22字节

匿名中缀lambda。注意到InputFormat左参数,OutputFormat作为右边的参数,并提示Number从标准输入。假设⎕IOI ndex O rigin)为0,这在许多系统上都是默认的。

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

在线尝试!

{…… } “ dfn”;是左参数,是右参数
(助记符:希腊字母的左右两端)

⍵[] 使用以下内容索引输出格式:

   提示输入

  ⍺⍳这些字符在输入格式中的索引

  ()⊥ 评估为基于以下基准:

   ≢⍺ 输入格式的长度

   得到的是(分离¯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),133131字节

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
}

您可以使用putchar代替write并稍微更改解码循环来节省2个字节:在线尝试!
ErikF

这个index功能也为我节省了一个字节,我不知道;)
Felix Palmen 18/08/17

6

05AB1E,5个字节

ÅβIÅв

在线尝试!

这并不会在05AB1E遗留下来的版本。它仅适用于新版本的Elixir重写。

怎么运行的

ÅβIÅв–完整程序。
Åβ–从自定义基数转换为十进制。
  I –按第三个输入。
   Å–从十进制转换为自定义基数。 

您声明它仅适用于05AB1E v2(不确定该版本号是否正确..),但是您仍然提供了TIO链接。TIO上已经有Elixir版本吗?:S或者它适用于大多数测试用例,但是在某些边缘情况下它仅在新版本中起作用?
凯文·克鲁伊森

2
现在可以在TIO上使用05AB1E v2。05AB1E(旧版)(在tio栏中搜索)是旧05AB1E的名称,而05AB1E是新05AB1E的名称。我知道您已经在聊天室中看到了,但是我将其留在这里作为其他用户的参考。
Xcoder先生18年

5

MATL,5个字节

sundar找到了真正的内置方法!投票赞成这个答案,而不是我的愚蠢的答案:-(

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

在线尝试!

匿名函数(感谢Outgolfer Erik)将原始数字转换为以10为底的整数,然后将该整数和新的基础字符串传递给函数g(),该函数递归转换为新的基础。现在将OutputFormat的长度作为参数传递给g()。

将g()更新为一个较低的字节数。(谢谢,丹尼斯!)

用find()替换了index()。(谢谢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 Outgolfer当匿名函数调用另一个函数时可以吗?
Triggernometry '18

只要在字节数中包含其他内容,是的,您就可以定义变量和导入模块。
暴民埃里克(Erik the Outgolfer)'18年

1
辅助功能可以变为g=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)]
丹尼斯

1
而且主要的可以成为lambda n,a,b:g(sum(len(a)**i*a.find(j)for i,j in enumerate(n[::-1])),b,len(b))
Xcoder先生18年

2

果冻,11字节

iⱮ’ḅL{ṃ⁵ṙ1¤

在线尝试!

参数顺序:InputFormat,Number,OutputFormat。请务必在引号中加上适当的转义!


rm不确定我是否明确声明了参数的顺序...
Martin Barker

@MartinBarker在这里,参数按顺序2、1、3进行。我看不到挑战中对特定顺序的要求,因此不建议这样做。
暴民埃里克

3
@MartinBarker Pro提示:应对此类事情要灵活。我发现解决任务时输入的顺序完全不相关,因此我建议您允许任意选择参数的顺序
Xcoder先生,18年

我只是想立即对它进行测试就让它坚持下去。
马丁·巴克

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字节

一个已声明的子例程,该例程接受n语言的输入,y并将其投影为language 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字节

将输入作为(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输入完成的操作。并且必须进行编程,您需要将字符串拆分为第一个参数的数组,此参数才有效。
马丁·巴克

@MartinBarker您指的是哪个规则?更新后无论如何都需要3个字符串。
阿纳尔德

所有3个输入参数都说“ string”,因为C ++可以直接读取一个字符串,并使用javascript不能将其用作数组。
马丁·巴克

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 '18 / 08/21

1

Python 2中97个 95字节

感谢Chas Brown提供了-2个字节。

n,s,t=input()
k=0;w='';x=len(t)
for d in n:k=len(s)*k+s.find(d)
while k:w=t[k%x]+w;k/=x
print w

在线尝试!


1

Java 10,131个字节

一个lambda,将参数按顺序作为字符串并返回字符串。

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

在线试用

不打高尔夫球

(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;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.