カスタム数値ベースコンバーター


30

自分の好きな形式を使用して、自分の持っている数字を自分の数字ベースにすばやく変換できるようにしたい力。

入力

プログラムは3つのパラメーターを受け入れる必要があります。

  1. 番号:変換される文字列番号
  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. 追加のテストなので。

すべての例は、次のコード(vars mins、ただしコードはフォーマット済み)を使用して、bcmath拡張を使用してPHP 7.2によって生成されました。おそらくもっと短い方法がありますが、これは私がこれを行う必要があるシステムのために思いついた方法であり、誰かが短いバージョンを思い付くことができるかどうかを確認するのは良いことです。

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"。(または、それが正しくない場合、実際にあるべきことは何でも)
Fund Monicaの訴訟

2
私はベース36に上がるビルトインを使用してキャッチ誰にでも、フォーマット以上36文字でテストケースをお勧めしたい
ジョー・キング

回答:


13

.......................ご存知のように、Zaベース変換が行われたことがわかりましたが、matl.sueverのドキュメントでは、ベースの文字を受け入れるかどうかは明確ではありませんでした。だから私はそれを試しませんでした。リップ!
ジュゼッペ

@Giuseppe Haha、それはいくつかの巧妙なハックで(ab)useするのに熟したコマンドのように思えたからだけ覚えていました。皮肉なことに、私が最初にそれを使用するのは、直接的な組み込みの答えとしてです。:)
スンダ-復活モニカ

1
「ザ」を見たときの私の最初の考えは「ロード、ハリー・ドレスデン」でした。+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)ますが、ベース2にベース10から31を変換するときなど、時々先頭にゼロを引き起こしたが:(
digEmAll

先行ゼロなしで対数の「ゼロ問題」を回避するために、私は他の多くのソリューションを見ません... log(N+!N,T)もちろん!、元の意味で使用することができます
-digEmAll

@digEmAll OPのコメントはまだ少し不明瞭ですが、ゼロをサポートする必要はないようです。
ジュゼッペ

まあまあ..それは大丈夫です:)
digEmAll

7

APL(Dyalog Unicode)、22バイト

匿名中置ラムダ。InputFormat左引数およびOutputFormat右引数として取りNumber、標準入力からのプロンプトを出します。想定している⎕IOI NDEX OであることをRIGIN)0多くのシステムではデフォルトです。

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

オンラインでお試しください!

{} "dfn"; 左引数、右引数
(ニーモニック:ギリシャ語のアルファベットの左端と右端)

⍵[] 出力形式に次のインデックスを付けます。

   入力を促す

  ⍺⍳input入力形式のそれらの文字のndices

  ()⊥ 次のベースにあると評価します。

   ≢⍺ 入力形式の長さ

   その結果(¯1から分離(≢⍺)

  ()⊥⍣¯1 次のベースに変換します。

  ≢⍺ 出力形式の長さ



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)

フラグ。(はい、これは信じられないほど大雑把です。だからこそ、古い答えを以下に残しています。)これは、fSTDOUTに答えを出力するマクロを定義します。

オンラインでお試しください!

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

オンラインでお試しください!

これは、fSTDOUTに答えを出力する関数を定義します。

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関数は私のアプローチで1バイトも節約しましたが、それについては知りませんでした;)
フェリックスパルメン

6

05AB1E、5バイト

ÅβIÅв

オンラインでお試しください!

これは、旧バージョンの05AB1E では機能しませ。Elixirの書き換えである新しいバージョンでのみ機能します。

使い方

ÅβIÅв–完全プログラム。
Åβ–カスタムベースから10進数に変換します。
  I – 3番目の入力をプッシュします。
   Åв– 10進数からカスタムベースに変換します。 

05AB1E v2でしか機能しないと述べています(正しいバージョン番号かどうかはわかりません)。ElixirバージョンはすでにTIOにありますか?!:Sまたはほとんどのテストケースで動作しますが、新しいバージョンでのみ動作するエッジケースがありますか?
ケビンクルーッセン

2
05AB1E v2がTIOで利用可能になりました。05AB1E(レガシー)(tioバーで検索)は古い05AB1Eの名前で、05AB1Eは新しい名前です。ただし、チャットルームで既に見たことがあることは知っていますが、他のユーザーの参考としてここに残しておきます。
Mr Xcoder

5

MATL、5バイト

スンダーはこれを行うための本当のビルトインを見つけました!私の愚かなものの代わりにその答えに賛成してください:-(

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

パイソン2132の 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)]

オンラインでお試しください!

無名関数(ありがとう、 元の数値を基数10の整数に変換し、整数と新しい基数文字列を関数g()に渡す Erik the Outgolfer!)は再帰的に新しい基数に変換します。OutputFormatの長さをパラメーターとしてg()に渡すようになりました。

小さいバイト数のg()を更新しました。(ありがとう、デニス!)

index()をfind()に置き換えました。(ありがとう、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無名関数が別の関数を呼び出すときに許可されますか?
トリガー測定

バイトカウントに他のものを含める限り、はい、変数を定義してモジュールをインポートできます。
エリックアウトゴルファー

1
ヘルパー関数はになりg=lambda n,c:c[n:n+1]or g(n/len(c),c)+c[n%len(c)]ます。
デニス

1
そして、メインの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は確かに私は明示的に...のparamsの順序を述べたのではない
マーティン・バーカー

@MartinBarkerここでは、パラメーターは2、1、3の順序で取得されます。チャレンジで特定の順序の要件が表示されないため、推奨されません。
エリックアウトゴルファー

3
@MartinBarker Proヒント:そのようなことには柔軟に対応してください。私はあなたがいずれかのパラメータ任意に選択された順序付けを許可することを示唆しているので、私は、タスクを解決する際に、入力の順序は完全に無関係であることを見つける
氏Xcoder

とにかくテストしてみます。
マーティンバーカー

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の6100の 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に投影する宣言されたサブルーチン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つすべては、文字列を直接読み込むことができ、javascriptで配列として使用できないC ++として「文字列」と言います。
マーティンバーカー

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

オンラインで試す

非ゴルフ

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