混合基数转换


12

背景

这里的大多数人应该熟悉几种基本系统:十进制,二进制,十六进制,八进制。例如,在十六进制系统中,数字12345 16将代表

1*16^4 + 2*16^3 + 3*16^2 + 4*16^1 + 5*16^0

请注意,我们通常不希望基数(此处为16)从数字更改为数字。

这些常用的位置系统的一般化使您可以为每个数字使用不同的数字基础。例如,如果我们在十进制和二进制系统之间切换(从最低有效数字的底数为10开始),则数字190315 [2,10]表示

1*10*2*10*2*10 + 9*2*10*2*10 + 0*10*2*10 + 3*2*10 + 1*10 + 5 = 7675

我们将此基准表示为[2,10]。最右边的基数对应于最低有效数字。然后,当您浏览数字(左边)时,您要经过底数(左),如果位数比基数多,则四处循环。

有关更多阅读,请参阅Wikipedia

挑战

编写一个程序或函数,给定一个D由输入基数I和输出基数组成的数字列表O,将所表示的整数D从base 转换I为base O。您可以通过STDIN,ARGV或函数参数获取输入,然后返回结果或将其打印到STDOUT。

您可以假设:

  • 在数字IO都大于1
  • IO非空。
  • 输入数字在给定的基数中有效(即,没有比其基数大的数字)。

D可以为空(表示0)或可以有前导零。您的输出不应包含前导零。特别是,表示结果的结果0应作为空列表返回。

您不得使用任何内置或第三方基本转换功能。

这是代码高尔夫球,最短的答案(以字节为单位)获胜。

例子

D               I                  O        Result
[1,0,0]         [10]               [2]      [1,1,0,0,1,0,0]
[1,0,0]         [2]                [10]     [4]
[1,9,0,3,1,5]   [2,10]             [10]     [7,6,7,5]
[1,9,0,3,1,5]   [2,10]             [4,3,2]  [2,0,1,1,0,1,3,0,1]
[52,0,0,0,0]    [100,7,24,60,60]   [10]     [3,1,4,4,9,6,0,0]
[0,2,10]        [2,4,8,16]         [42]     [1,0]
[]              [123,456]          [13]     []
[0,0]           [123,456]          [13]     []

我可以要求一个无限的列表作为基本描述,还是我必须自己对其进行无限化?
John Dvorak 2014年

@JanDvorak您的意思是,如果您可以期望基本列表已经具有足够的重复次数来覆盖所有数字?不,您必须自己包装或重复自己。
Martin Ender 2014年

我假设以UB为基数得到一个空列表,但是我们可以假设数字列表是非空的吗?另外,尾随零有什么政策?
John Dvorak 2014年

即,我不在乎输入上的空列表,但是[]如果输入是,我想生成[0]
John Dvorak

我可以要求并产生相反顺序的数字列表吗(LSD在前)?
John Dvorak

Answers:


6

果酱,45岁

q~_,@m>0@{@(:T+@T*@+}/\;La{\)_@+@@md@@j@+}jp;

终于我找到了一个很好的使用j

怎么运行的

Long ArrayList Block j执行以整数为参数的块,并将在Long j该块中递归调用此块。它还会将块返回的值存储在内部数组中,该内部数组由array参数初始化。如果输入已经在数组中,它将不执行该块,而是返回数组中的值。

因此,如果我使用一个空数组的数组对其进行初始化,则该空数组将为输入0返回,并且该块将为其他任何输入执行。

q~_,@m>0@{@(:T+@T*@+}/\;     " See below. Stack: O decoded-D ";
La                           " Initialized the value with input 0 as empty list. ";
{
  \)_@+@@md@@                " See below. Stack: remainder O quotient ";
  j                          " Call this block recursively except when the same quotient has
                               appeared before, which is impossible except the 0.
                               Stack: remainder O returned_list ";
  @+                         " Append the remainder to the list. ";
}j
p;                           " Format and output, and discard O. ";

贾姆,49 48

q~_,@m>0@{@(:T+@T*@+}/\;{\)_@+@@md@@}h;;_{}?]W%`

输入应为O I D

例子:

$ while read; do <<<$REPLY ./cjam-0.6.2.jar <(echo 'q~_,@m>0@{@(:T+@T*@+}/\;{\)_@+@@md@@}h;;_{}?]W%`');echo; done
[2] [10] [1 0 0]
[10] [2] [1 0 0]
[10] [2 10] [1 9 0 3 1 5]
[4 3 2] [2 10] [1 9 0 3 1 5]
[10] [100 7 24 60 60] [52 0 0 0 0]
[42] [2 4 8 16] [0 2 10]
[13] [123 456] []
[13] [123 456] [0 0]
[1 1 0 0 1 0 0]
[4]
[7 6 7 5]
[2 0 1 1 0 1 3 0 1]
[3 1 4 4 9 6 0 0]
[1 0]
""
""

怎么运行的

q~           “ Read the input and evaluate. ";
_,@m>        " Rotate I to the right by the length of D. ";
0@{          " For each item in D, with the result initialized to 0: ";
  @(:T+      " Rotate I to the left, and set the original first item to T. ";
  @T*@+      " Calculate result * T + current. ";
}/
\;           " Discard I. ";
{            " Do: ";
  \)_@+      " Rotate O to the right, and get a copy of the original last item. ";
  @@md       " Calculate divmod. ";
  @@         " Move O and the quotient to the top of the stack. ";
}h           " ...while the quotient is not 0. ";
;;           " Discard O and the last 0. ";
_{}?         " If the last item is still 0, discard it. ";
]W%          " Collect into an array and reverse. ";
`            " Turn the array into its string representation. ";

我必须停止使用数组旋转仅仅是因为CJam拥有了它_{}?
丹尼斯

@sudo {}e|相同。
jimmy23013

您介意使用添加版本说明j吗?:)
马丁·恩德

@MartinBüttner完成。
jimmy23013 2014年

3

CJam,62 61 59 57字节

q~Wf%~UX@{1$*@+\@(+_W=@*@\}/;\;{\(+_W=@\md@@}h;;]W%_0=!>p

[O I D]从STDIN 读取输入数组。在线尝试。

怎么运行的

q~         " Read from STDIN and evaluate the input. Result: [O I D]                      ";
Wf%~       " Reverse each of the three arrays and dump them on the stack.                 ";
UX@        " Push U (0) and X (1); rotate D on top of both.                               ";
{          " For each N in D:                                                             ";
  1$*      "   N *= X                                                                     ";
  @+       "   U += N                                                                     ";
  \@(+     "   I := I[1:] + I[:1]                                                         ";
  _W=@*    "   X *= I[-1]                                                                 ";
  @\       "   ( U I X ) ↦ ( I U X )                                                      ";
}/         "                                                                              ";
;\;        " Discard I and X.                                                             ";
{          " R := []; Do:                                                                 ";
  \(+      "   O := O[1:] + O[:1]                                                         ";
  _W=@\md  "   R += [U / O[-1]], U %= O[-1]                                               ";
  @@       "   ( O U R[-1] ) ↦ ( R[-1] O U )                                              ";
}/         " While U                                                                      ";
;;]        " Discard U and O.                                                             ";
W%         " Reverse R.                                                                   ";
_0=!>      " Execute R := R[!R[0]:] to remove a potential leading zero.                   ";
p          " Print a string presentation of R.                                            ";

测试用例

$ cjam mixed-base.cjam <<< '[ [2]     [10]             [1 0 0]       ]'
[1 1 0 0 1 0 0]
$ cjam mixed-base.cjam <<< '[ [10]    [2]              [1 0 0]       ]'
[4]
$ cjam mixed-base.cjam <<< '[ [10]    [2 10]           [1 9 0 3 1 5] ]'
[7 6 7 5]
$ cjam mixed-base.cjam <<< '[ [4 3 2] [2 10]           [1 9 0 3 1 5] ]'
[2 0 1 1 0 1 3 0 1]
$ cjam mixed-base.cjam <<< '[ [10]    [100 7 24 60 60] [52 0 0 0 0]  ]'
[3 1 4 4 9 6 0 0]
$ cjam mixed-base.cjam <<< '[ [42]    [2 4 8 16]       [0 2 10]      ]'
[1 0]
$ cjam mixed-base.cjam <<< '[ [13]    [123 456]        []            ]'
""
$ cjam mixed-base.cjam <<< '[ [13]    [123 456]        [0 0]         ]'
""

请注意,空字符串和空数组与CJam是无法区分的,因此[]pprints ""


4
OMG从未见过62字节的CJam程序:D
Optimizer

@Optimizer 可能是我最长的CJam提交。
硕果累累


@Dennis那不是代码高尔夫,是吗?
硕果累累

@ Challenger5并非如此,但我怀疑高尔夫版本是否会少于200个字节。
丹尼斯,

2

Python 2-318

from operator import *
d,i,o=input()
c=len
def p(l):return reduce(mul,l,1)
n=sum(x[1]*p((i[-x[0]%c(i)-1:]+x[0]/c(i)*i)[1:]) for x in enumerate(d[::-1]))
r=[]
j=1
t=[]
k=c(o)
while p(t)*max(o)<=n:t=(o[-j%k-1:]+j/k*o)[1:];j+=1
while j:j-=1;t=(o[-j%k-1:]+j/k*o)[1:];r+=[n/p(t)];n%=p(t)
print (r if r[0] else [])

我不小心弄乱了论证的顺序,所以我不得不将其推翻。我将在slice-fu上工作,以使列表在以后的另一个方向上工作,我已经浪费了整个午餐时间:p

固定


不要说“浪费”;)
马丁·恩德

你应该能够高尔夫它下降到286个字节:repl.it/JbIk
扎卡里

@Zacharý我想这是我的第一个高尔夫,我敢肯定它会比那更短!Feersum的回答很好地证明了这一点。如果您愿意,可以编辑此答案,但是恐怕我没有特别动力去改进它。
FryAmTheEggman

2

APL,78

{1↓(⊃1⌷⍺)({t←⍺[(⍴⍺)|⍴⍵]
(⌊0⌷⍵÷t)(t|0⌷⍵),1↓⍵}⍣{0=0⌷⍵}),+/(0,⍵)×⌽×\1,(⍴⍵)⍴⌽⊃0⌷⍺}

例子:

f←{1↓(⊃1⌷⍺)({t←⍺[(⍴⍺)|⍴⍵]
  (⌊0⌷⍵÷t)(t|0⌷⍵),1↓⍵}⍣{0=0⌷⍵}),+/(0,⍵)×⌽×\1,(⍴⍵)⍴⌽⊃0⌷⍺}
(,10)(,2) f 1 0 0
1 1 0 0 1 0 0
(,2)(,10) f 1 0 0
4
(2 10)(,10) f 1 9 0 3 1 5
7 6 7 5
(2 10)(4 3 2) f 1 9 0 3 1 5
2 0 1 1 0 1 3 0 1
(100 7 24 60 60)(,10) f 52 0 0 0 0
3 1 4 4 9 6 0 0
(2 4 8 16)(,42) f 0 2 10
1 0
(123 456)(,13) f ⍬

⍴(123 456)(,13) f ⍬
0
(123 456)(,13) f 0 0

⍴(123 456)(,13) f 0 0
0

仅用于普通教育–内置:{{⍵↓⍨1⍳⍨×⍵}(99⍴⎕)⊤⍵⊥⍨⎕⍴⍨⍴⍵}将D作为正确的论证,然后要求I和O。
Adám2016年

2

Python 2-122

非常简单,没有找到关于此的任何特殊高尔夫技巧。

def f(D,I,O):
 n,i,l=0,-len(D),[]
 for d in D:n=n*I[i%len(I)]+d;i+=1
 while n:i-=1;b=O[i%len(O)];l=[n%b]+l;n/=b
 return l

取消高尔夫:

def f(D,I,O):
    n = 0
    for i in range(len(D)):
        dn = len(D) - i
        n = n * I[-dn % len(I)] + D[i]
    l = []
    i = 0
    while n:
        i -= 1
        b = O[i%len(O)]
        l = [n%b] + l
        n /= b
    return l

编辑:由于FryAmTheEggman,116字节的程序版本

D,I,O=input()
n,i,l=0,-len(D),[]
for d in D:n=n*I[i%len(I)]+d;i+=1
while n:i-=1;b=O[i%len(O)];l=[n%b]+l;n/=b
print l

此版本接受逗号分隔的输入,例如 [1,9,0,3,1,5], [2,10], [10]


@FryAmTheEggman我不确定它如何接受带引号的输入,但是用逗号分隔数组是可行的。
feersum

1

K2 - 83 74炭

函数采用一个参数。这比K更适合K,这就是为什么我不使用J。这就是装箱/拆箱垃圾的负担,没人愿意。这是在k2方言中的(可能需要进行一些修改才能在开源实现Kona中工作),但是如果我可以在这里打短一点的话,我会将其更改为k4。

{:[#x@:|&~&\~x;|*{x 1}.[{_(x,y!*z;y%*z;1!z)}]/(();+/x*1*\(1-#x)#y;|z);()]}

我会注意到,我在这里表示挑剔,并说必须这样输入一项清单。,2是一个项目的列表,该项目是标量2。标量列表和1项列表通常可以互换,但是在这种高尔夫中,逻辑依赖于列表参数的假设。

为了解释高尔夫,我将其分为两部分。F是高尔夫,L是计算输出的主循环。循环的确切机制是L反复应用于其自变量,直到第二个自变量为零,然后返回结果。(这是.[L]/一部分。)

L: {_(x,y!*z;y%*z;1!z)}
F: {:[#x@:|&~&\~x;|*{x 1}.[L]/(();+/x*1*\(1-#x)#y;|z);()]}

爆炸:

{_(x,y!*z;y%*z;1!z)}  /function, args x y z
  (      ;    ;   )   / update each arg as follows:
               1!z    /  new z: rotate z left
            *z        /  head of z (current base digit)
          y%          /  y divided by that
 _                    /  new y: floor of that
     y!*z             /  y modulo head of z
   x,                 /  new x: append that to old x

{:[#x@:|&~&\~x;|*{x 1}.[L]/(();+/x*1*\(1-#x)#y;|z);()]}  /function, args x y z
            ~x                                           /find the 0s in x
          &\                                             /find leading zeros
        &~                                               /indices of digits that aren't
    x@ |                                                 /those items from x, reverse order
    x :                                                  /assign to x
 :[#          ;                                      ]   /if length is 0:
                                                   ()    / return empty list
                                                  ;      /else:
                      .[L]/                              / loop L repeatedly
                 {x 1}                                   / until y = 0
                           (  ;               ;  )       / starting with args:
                            ()                           /  Lx: empty list
                                       1-#x              /  number of input digits, minus 1
                                      (    )#y           /  cyclically extend base leftward
                                   1*\                   /  running product, start at 1
                                 x*                      /  multiply digits by these
                               +/                        /  Ly: sum of the above
                                               |z        /  Lz: out base, reverse order
               |*                                        / first elem of result, reversed

实际上:

  {:[#x@:|&~&\~x;|*{x 1}.[{_(x,y!*z;y%*z;1!z)}]/(();+/x*1*\(1-#x)#y;|z);()]}[1 0 0; ,10; ,2]
1 1 0 0 1 0 0
  f:{:[#x@:|&~&\~x;|*{x 1}.[{_(x,y!*z;y%*z;1!z)}]/(();+/x*1*\(1-#x)#y;|z);()]}
  f[1 0 0; ,2; ,10]
,4
  f .' ((1 9 0 3 1 5; 2 10;           ,10)  /f apply each
>       (1 9 0 3 1 5; 2 10;           4 3 2)
>       (52 0 0 0 0;  100 7 24 60 60; ,10)
>       (0 2 10;      2 4 8 16;       ,42)
>       (();          123 456;        ,13)
>       (0 0;         123 456;        ,13))
(7 6 7 5
 2 0 1 1 0 1 3 0 1
 3 1 4 4 9 6 0 0
 1 0
 ()
 ())

0

Perl 6、67字节

{[R,] [+]([R,](@^a)Z*1,|[\*] |[R,](@^b)xx*).polymod: |[R,](@^c)xx*}

尝试一下

展开:

{  # bare block lambda with placeholder parameters @a,@b,@c

  [R,]    # reduce the following using reverse meta op 「R」 combined with 「,」 op
          # (shorter than 「reverse」)

    [+](  # sum

        [R,](@^a) # reverse of first argument

      Z[*]        # zipped using &infix:<*> with the following

        1,
        |                    # slip the following in (flattens)
          [\*]               # triangle reduce

            |[R,](@^b) xx*   # reverse of second argument repeated infinitely
    )

    .polymod: |[R,](@^c) xx* # moduli the reverse of third argument repeated
}

如果您不确定哪个三角形减少了:

[\*] 1,2,3,4,5
# 1, 1*2, 1*2*3, 1*2*3*4, 1*2*3*4*5
# 1,   2,     6,      24,       120

如果我可以颠倒输入,然后反向输出,那将是47个字节。

{[+](@^a Z*1,|[\*] |@^b xx*).polymod: |@^c xx*}

尝试一下

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.