混合ベース変換


12

バックグラウンド

ここのほとんどの人は、10進数、2進数、16進数、8進数などのいくつかの基本システムに精通している必要があります。たとえば、16進数システムでは、番号12345 16は次を表します。

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

通常、ベース(ここでは16)が数字から数字に変わることを期待していないことに注意してください。

これらの通常の位置システムを一般化すると、数字ごとに異なる数値ベースを使用できます。たとえば、10進法と2進法を交互に使用している場合(最下位の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ベースからIベースにしますO。STDIN、ARGV、または関数引数を介して入力を取得し、結果を返すか、STDOUTに出力できます。

あなたは仮定するかもしれません:

  • Iおよびの数値Oがすべてより大きいこと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]     []

基本的な説明として無限のリストが必要な場合がありますか、それとも自分でリストを無限にする必要がありますか?
ジョンドヴォルザーク

@JanDvorakあなたは、ベースリストがすでにすべての数字をカバーするのに十分な数の繰り返しを持っていると期待できるならどうですか?いいえ、折り返しまたは自分自身を繰り返す必要があります。
マーティンエンダー

ベースがUBであるため、空のリストを取得することを想定していますが、数字のリストが空でないと想定することはできますか?また、末尾のゼロに関するポリシーは何ですか?
ジョンドヴォルザーク

つまり、私は入力に空のリストを気にしないが、私は農産物したい[]入力された場合[0]
ジョンドヴォルザーク

逆の順序(LSDが最初)で数字のリストを要求して作成できますか?
ジョンドヴォルザーク

回答:


6

CJam、45

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

最後に私はの良い使い方を見つけましたj

使い方

Long ArrayList Block jパラメータとして整数を取るブロックを実行し、ブロック内でLong jこのブロックを再帰的に呼び出します。また、ブロックによって返された値を内部配列に格納します。内部配列は、配列パラメーターによって初期化されます。入力が既に配列にある場合はブロックを実行せず、代わりに配列の値が返されます。

したがって、空の配列の配列で初期化すると、入力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. ";

CJam、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が持っているからといって、配列の回転の使用をやめなければなりません...この_{}?トリックは本当にすてきです。
デニス14

@sudo {}e|も同じです。
jimmy23013 14年

を使用してバージョンの説明を追加してもjよろしいですか?:)
マーティンエンダー14年

@MartinBüttnerできました。
jimmy23013 14年

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と区別できないため、を[]p出力することに注意してください""


4
OMG 62バイトのCJamプログラムを見たことがない:D
オプティマイザー14

@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

修繕


「無駄」と言わないでください;)
マーティンエンダー14

:あなたは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ám16年

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 14

1

K2 - 83 74 CHAR

1つの引数を取る関数。これは、JよりもKにはるかに適していたため、Jを使用していません。ボクシング/アンボクシングガベージの負荷になり、誰もそれを望みません。これはk2方言にあります(オープンソースの実装Konaで動作するには多少の適応が必要な場合があります)が、もっと短くゴルフできる場合は、これをk4に変更します。

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

ここで私はうるさいことに立ち向かい、1つの項目リストをそのように入力する必要があると言います。,2は1つのアイテムのリストで、そのアイテムはスカラー2です。多くの場合、スカラーと1アイテムのリストは交換可能ですが、このゴルフにはリスト引数の仮定に依存するロジックがあります。

ゴルフを説明するために、2つの部分に分けます。FはゴルフでLあり、出力を計算するメインループです。ループの正確なメカニズムは、L2番目の引数がゼロになるまで引数に繰り返し適用され、その結果が返されることです。(これは.[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*}

それを試してみてください

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.