大きなベース、小さな数字


19

J言語には、定数を指定するための非常に愚かな構文があります。特に、1つのクールな機能、つまり任意のベースで記述できる機能に焦点を当てたいと思います。

任意の数字と英数字の文字列を記述XbYするXY、JはYベースX番号として解釈されます。ここで0through 9は通常の意味を持ち、throughは10〜35 az表します。

そして、私がX数字を言うとき、私は数字を意味します。この質問の目的のためにX、正の整数に制限しますが、Jでは、負の数、分数、複素数など何でも使用できます。

奇妙な事はことであるあなただけの0から35までの数字を使用することができ、使用可能な記号のあなたのコレクションが構成されているので、お使いのベース-どんな数字としてのみ 0-9とAZの。

問題

この方法を使用して、2,933,774,030,998のようなゴルフマジックナンバーを支援するプログラムが必要です。まあ、大丈夫、そんなに大きくないかもしれません、私はあなたに簡単に行きます。そう...

あなたの仕事は(通常大きい)進数を取るプログラムまたは機能記述することですN1及び4,294,967,295(= 2との間に32の形の最短表現入力として-1)、及び出力/戻りXbYX正の整数であるとYされています英数字(0〜9およびa〜z、大文字と小文字を区別しない)で構成Yされ、X等しいと解釈される文字列N

すべての表現XbY表現の長さがの桁数以上である場合、代わりにN出力しNます。他のすべての関係では、最短表現の空でないサブセットを出力できます。

これはコードゴルフですので、短いほど良いです。

テストケース

      Input | Acceptable outputs (case-insensitive)
------------+-------------------------------------------------------
          5 | 5
            |
   10000000 | 79bkmom  82bibhi  85bgo75  99bauua  577buld
            | 620bq9k  999baka
            |
   10000030 | 85bgo7z
            |
   10000031 | 10000031
            |
   12345678 | 76bs9va  79bp3cw  82bmw54  86bjzky  641buui
            |
   34307000 | 99bzzzz
            |
   34307001 | 34307001
            |
 1557626714 | 84bvo07e  87brgzpt  99bglush  420blaze
            |
 1892332260 | 35bzzzzzz  36bvan8x0  37brapre5  38bnxkbfe  40bij7rqk
            | 41bgdrm7f  42bek5su0  45bablf30  49b6ycriz  56b3onmfs
            | 57b38f9gx  62b244244  69b1expkf  71b13xbj3
            |
 2147483647 | 36bzik0zj  38br3y91l  39bnvabca  42bgi5of1  48b8kq3qv
 (= 2^31-1) | 53b578t6k  63b2akka1  1022b2cof  1023b2661  10922bio7
            | 16382b8wv  16383b8g7  32764b2gv  32765b2ch  32766b287
            | 32767b241
            |
 2147483648 | 512bg000  8192bw00
            |
 4294967295 | 45bnchvmu  60b5vo6sf  71b2r1708  84b12mxf3  112brx8iv
 (= 2^32-1) | 126bh5aa3  254b18owf  255b14640  1023b4cc3  13107bpa0
            | 16383bgwf  21844b9of  21845b960  32765b4oz  32766b4gf
            | 32767b483  65530b1cz  65531b1ao  65532b18f  65533b168
            | 65534b143  65535b120

表現が数値と等しいかどうかわからない場合は、Try It OnlineのようなJインタープリターを使用できます。入力するだけでstdout 0":87brgzpt、Jは吐き出します1557626714。この問題は大文字と小文字を区別しませんが、Jは小文字のみを受け入れることに注意してください。

おそらく役立つ理論

  • すべてのためN未満10,000,000、小数表現は、他のような短いようであり、したがってのみ許容される出力です。何かを保存するには、新しいベースで少なくとも4桁短くする必要があり、ベースが99より大きい場合はさらに短くする必要があります。
  • の平方根の天井までのベースをチェックするだけで十分ですN。任意の大きなベースの場合はBNベースの中で最も二桁になりますBあなたは、有効な最初の数字と何かが周りにあり得るでしょう、初めてので、BN/ 35。ただし、そのサイズでは、常に少なくとも10進表現と同じ大きさになるため、試しても意味がありません。それを念頭に置いて、ceil(sqrt(この問題を解決するためにあなたに尋ねる最大数))= 65536。
  • 36未満のベースに表現がある場合、ベース36の表現は少なくとも同じくらい短くなります。したがって、36未満の35bzzzzzz基数で誤って短い解を心配する必要はありません。たとえば、1,892,332,260 の表現では、その基数に通常とは異なる数字を使用します36bvan8x0が、長さは同じです。

Lol、1557626714 = 420blaze ^ _ ^
DrQuarius

回答:


9

JavaScript(ES6)、103 101バイト

入力を文字列として受け取ります。

n=>[...Array(7e4)].reduce(p=>p[(r=++b+(g=x=>x?g(x/b|0)+(x%b).toString(36):'b')(n)).length]?r:p,n,b=2)

テストケース

注:スニペット関数の反復回数は600回に制限されているため、テストケースはより速く完了します。(それ以外の場合は数秒かかります。)


私の番号が大きすぎてこれを処理できない場合、どうすれば修正できますか?反復を増やすことは役に立たないようです。
FrownyFrog

N<232

「悪性番号」のルックアップ、2136894800297704.
FrownyFrog

@FrownyFrog反復回数増やし、のMath.floor(x/b)代わりに使用することで処理できる場合がありx/b|0ます。(しかし、私はそれをテストしませんでした。)
アーナウルド

1
出来た!ありがとうございました。
FrownyFrog

3

ルビー、118バイト

これは別の質問にリンクされており、ここには多くの答えがないことに気づいたので、試してみることにしました。

すべての有効なJ番号構成を構築するための入力までのすべてのベースをウォークスルーします。ただし、1〜8をスキップします。とにかく、これらが10進表記よりも短くなる方法はないからです。それdigitsは数字を取得するためにビルトインを呼び出すため、すべてが考慮されたかなり単純な解決策ですが、それは最初に最下位の数字から始まるため、reverseするため、実際の数字を取得する必要があるため、改善される可能性があります。

遅いです。とても遅いです。たとえば、TIOは34307000でタイムアウトします。我々は可能性が平方根で行くかさえのアルノーの選択は7e4、時間を節約するために、しかし、そのコスト、余分なバイト、なぜわざわざ?

->n{([n.to_s]+(9..n).map{|b|d=n.digits b;"#{b}b"+d.reverse.map{|i|i.to_s 36}*''if d.all?{|i|i<36}}-[p]).min_by &:size}

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

sqrtでオンラインで試して、すべてが時間通りに終了するようにします


1

05AB1E、37 バイト

[¼35ݾãvtîEyNβQižhA«yèJ'bìNìDgIg@i\}q

10000000ã4

最終if文がDgIg@i\}なくても、実際に機能することを確認するために、より低い値をテストできます。オンラインで試してください。

(おそらくもっと長いですが)より効率的なソリューションを後で思いつくことができるかどうかを確認します。

説明:

[              # Start an infinite loop:
 ¼             #  Increase the counter variable by 1 (0 by default)
 35Ý           #  Push a list in the range [0, 35]
 ¾ã            #  Take the cartesian product of this list with itself,
               #  with chunks-sizes equal to the counter variable
 v             #  Loop `y` over each of these lists:
  t            #   Take the square-root of the (implicit) input-integer
   î           #   Ceil it
  E            #   Loop `N` in the range [1, ceil(square(input))]:
   yNβ         #    Convert list `y` to base-`N`
   Qi          #    If it's equal to the (implicit) input-integer:
     žh        #     Push string "0123456789"
       A«      #     Append the lowercase alphabet
     yè        #     Index each value in list `y` into this string
     J         #     Join the characters to a single string
     'bì      '#     Prepend a "b"
        Nì     #     Prepend the number `N`
     D         #     Duplicate it
      g        #     And pop and push the length of this string
       Ig      #     Also push the length of the input
         @i }  #     If the length of the string is >= the input-length:
           \   #      Discard the duplicated string
     q         #     Stop the program
               #     (after which the result is output implicitly;
               #      or if the string was discarded and the stack is empty, it will
               #      implicitly output the implicit input as result instead)

1
印象的な答え!ただし、「すべての表現XbY表現の長さがの桁数以上である場合はNN代わりに出力する」というルールが欠落していると思います。最初の1,000万個の数字はカバーされていますが、の入力はの10000031ようなものを返すと思われ26blmoofます。数値は有効ですが、長さは入力と同じであるため、代わりに入力を返す必要があります。
バリューインク

@ValueInkああ。気づいてくれてありがとう!数バイトのコストで今すぐ修正する必要があります。
ケビンクルーッセン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.