大底,小数位


19

J语言的语法非常笨拙,无法指定常量。我想特别关注一个很酷的功能:以任意基础编写的能力。

如果编写XbY用于X任何数量和Y字母数字的任意字符串,则J将解释Y作为基础X数,其中0通过9具有其通常的含义,a通过z通过35表示10。

当我说X任何数字时,我的意思是任何数字。出于这个问题的目的,我将约束X为正整数,但是在J中,您可以使用任何东西:负数,分数,复数,等等。

奇怪的是,您只能使用0到35之间的数字作为基数,因为所有可用符号的集合都只包含0-9和az。

问题

我想要一个程序来使用这种方法帮助我像2,933,774,030,998这样的魔术数字打高尔夫球。好吧,好吧,也许没那么大,我会很轻松的对待你。所以...

您的任务是编写一个程序或函数,该程序或函数将一个(通常是较大的)十进制数N在1到4,294,967,295(= 2 32 -1)之间作为输入,并输出/返回该形式的最短表示形式XbY,其中X正整数Y是一个字符串,由字母数字组成(0-9和az,不区分大小写),并Y以base Xequals 解释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

如果您不确定某个表示形式是否等于某个数字,则可以使用任何J解释器,例如Try It Online上的解释器。只需输入,stdout 0":87brgzptJ就会吐出来1557626714。请注意,即使此问题不区分大小写,J也只接受小写字母。

一些可能有用的理论

  • 对于所有N小于10,000,000的数据,十进制表示形式与其他任何形式的表示形式一样短,因此是唯一可接受的输出。要保存任何内容,您需要在新的基数中至少短四位,如果基数大于99,则至少四位。
  • 只需检查基数,直到的平方根的上限即可N。对于任何较大的基地N将在基地最两位数,所以第一次你会得到一个有效的第一个数字是什么在左右N/ 35。但是以这种大小,您将始终至少与小数表示形式一样大,因此尝试没有任何意义。请记住,ceil(sqrt(我会问您最大的数字来解决这个问题))= 65536。
  • 如果基数小于36的任何表示形式,则基数36的表示形式将至少短。因此,您不必担心基数小于36的情况下意外地短解决方案。例如,35bzzzzzz1,892,332,260 的表示使用该基数的不寻常数字,但36bvan8x0长度相同。

大声笑,1557626714 = 420blaze ^ _ ^
DrQuarius

Answers:


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

ñ<232

“色情号码”查询,2136894800297704。–
FrownyFrog

@FrownyFrog您可以通过增加迭代次数使用Math.floor(x/b)代替来处理它x/b|0。(但我没有对其进行测试。)
Arnauld,

1
有效!谢谢。
FrownyFrog

3

红宝石,118字节

这是另一个问题,我注意到这里答案不多,所以我决定试一试。

遍历所有基础,直至包括构建所有有效J编号构造的输入。但是它会跳过1-8,因为无论如何它们都不会比以10为基数的表示形式短。从所有方面考虑,这是一个非常幼稚的解决方案,因为它调用了digits内置函数来获取数字,但是由于首先要从最低有效数字开始,因此我们必须reverse获取实际数字,因此可以对其进行改进。

太慢了 因此,太慢了。例如,TIO在34307000上超时。我们可以采用平方根,甚至可以选择Arnauld 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形式的长度都大于或等于的位数N,则N改为输出。” 尽管您确实覆盖了前1000万个数字,但我怀疑输入10000031会返回类似的信息26blmoof。该数字有效,但长度与输入相同,因此应改为返回输入。
价值墨水

@ValueInk哎呀。感谢您的关注!现在应该以几个字节为代价进行修复。
凯文·克鲁伊森
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.