简化数字


16

怎么不记得电视屏幕上出现的6或7位数字电话号码?使用下面描述的特殊技术,您将变成步行式电话簿!

显然,数字402110010010数字337377更容易记住,数字比数字更容易记住957472。这意味着,存储的数字一方面应包含尽可能少的数字,另一方面,希望该数字包含尽可能多的重复数字。

作为记忆困难的标准,我们将数字位数与不同数字位数的总和。记忆的号码可以写在另一个号码系统中,也许这样会更容易记住。例如,65535十六进制表示法中的数字看起来像FFFF

任务

您需要编写一个用于选择数字系统基数的程序,以最小化复杂度标准。数字系统的基数必须在2到36的范围内选择,然后数字0-9和英文字母A-Z可以用来表示数字。

输入值

输入包含从1到999999999的十进制整数。

输出量

输出必须包含数字系统的基数(从2到36),以最小化存储复杂性的标准,并且所选数字系统中的数字以一个空格分隔。如果多个基准为标准提供相同的值,则选择其中最小的一个。

笔记

  • 字母必须为大写(A-Z)。

测试用例

输入输出

1              2 1

2              3 2

65535       16 FFFF

123          12 A3


16
挑战很大,但需要更多的测试用例。
Grimmy

7
另外,输出格式有点太严格,您可能希望允许例如两个元素组成的数组,即基数和字符串,或者允许它们以相反的顺序或由另一个字符分隔。另外,我假设您将位数的总和加到位数上,但是您可能需要澄清一下。
暴民埃里克(Erik the Outgolfer)

8
我可以a-z代替使用A-Z吗?
尼尔,

5
我们可以使用相应的数字代替A-Z吗?
瑕疵的

8
@VerNick下次您编写类似的挑战时,我建议允许这两个请求,因为这只是不必要的复杂性,不建议使用:请参见此处
瑕疵的

Answers:



5

Python 2中150个 149 127 144字节

lambda n:min((len(c(n,b))+len(set(c(n,b))),b,c(n,b))for b in range(2,37))[1:]
c=lambda n,b,s='':n and c(n/b,b,chr(n%b+48+7*(n%b>9))+s)or s or'0'

在线尝试!


Python 3,136字节

lambda n:min((len((*c(n,b),*{*c(n,b)})),b,c(n,b))for b in range(2,37))[1:]
c=lambda n,b,s='':n and c(n//b,b,chr(n%b+48+7*(n%b>9))+s)or s

在线尝试!


Python 3.8(预发布),131字节

lambda n:min((len((*(x:=c(n,b)),*{*x})),b,x)for b in range(2,37))[1:]
c=lambda n,b,s='':n and c(n//b,b,chr(n%b+48+7*(n%b>9))+s)or s

在线尝试!


c 将以10为底的数字转换为以2至6为基的数字,并且第一个(匿名)函数得出的结果最小。


5

05AB1E16 14字节

-1字节感谢Kevin Cruijssen

₆LBāøΣнDÙìg}1è

在线尝试!

在最后添加R)»以完全符合指定的输出格式,但是大多数其他答案都没有打扰。

说明:

₆L          # range 1..36
  B         # convert the input to each of those bases
   āø       # enumerate (pair each element with its 1-based index)
Σ     }     # sort by
     g      # length
 н          # of the first element
    ì       # concatenated to
  DÙ        # itself, uniquified
1è          # take the second entry (first will always be base 1)

1
通过使用-1字节₆L©B®ø代替₆LεBy‚}
Kevin Cruijssen

1
@KevinCruijssen谢谢!通过使用-1 ā,似乎您总是忘了那个。
Grimmy

哈哈,我确实做到了。.我记得今天早些时候的挑战,并不是说它有任何帮助,哈哈xD
Kevin Cruijssen

@recursive您似乎还没有阅读答案。我链接了一个符合严格输出要求的版本,并解释了为什么我没有将其作为主要版本。
Grimmy

@被判有罪的有罪。抱歉打扰你。
递归

4

JavaScript(ES6), 87 85  101字节

编辑:+ 16个无用的字节以符合严格的输出格式

n=>(g=m=>--b>2?g(m<(v=new Set(s=n.toString(b)).size+s.length)?m:(o=b+' '+s.toUpperCase(),v)):o)(b=37)

在线尝试!


啊,我错过了那部分
TFeld 19'Aug

4

Japt v2.0a0 -gS24的23个字节

不漂亮,但能胜任。+2字节是完全不必要的要求,输出为大写。

37o2@sX u ¸iXÃñÈÌiXÌâ)l

尝试一下

37o2@sX u ¸iXÃñÈÌiXÌâ)l     :Implicit input of integer
37o2                        :Range [2,37)
    @                       :Map each X
     sX                     :  Convert the input to a base-X string
        u                   :  Uppercase
          ¸                 :  Split on spaces (there are none, so this returns a singleton array)
           iX               :  Prepend X
             Ã              :End map
              ñ             :Sort by
               È            :Pass each X through the following function
                Ì           :  Last element of X
                 i          :  Prepend
                  XÌâ       :    Last element of X, deduplicated
                     )      :  End prepend
                      l     :  Length
                            :Implicit output of the first sub-array, joined with spaces

是的,它很好用,但是字母必须是大写的。
Ver Nick说恢复Monica

1
@VerNick,为什么?这绝对没有增加任何挑战。
毛茸茸的

...我想下一件事将是“一个空格分隔”。看起来输出格式已经非常严格地应对了这一挑战,并且从注释看来它不会改变。
乔纳森·艾伦,

@JonathanAllan,幸运的是,我可以更改标志来“修复”该对象。
毛茸茸的

3

PHP124 119字节

for($i=36;$b=strtoupper(base_convert($argn,10,--$i));$o[strlen($b.count_chars($b,3))]="$i $b");krsort($o);echo end($o);

在线尝试!

遗憾的是,PHP中+12个字节使输出大写...但是...无论如何。


3

Zsh,85个字节

for b ({36..2})x=$[[#$b]$1]&&x=${x#*\#}&&a[$#x+${#${(us::)x}}]=$b\ $x
a=($a)
<<<$a[1]

对于for循环内的此语句数量,using ...&&...&&...短于{...;...;...;}

for b ({36..2})                   # order decreasing: smaller bases overwrite larger ones
    x=$[[#$b]$1] && \             # set x to [base]#[num] 
    x=${x#*\#} && \               # strip leading [base]#
    a[$#x+${#${(us::)x}}]=$b\ $x  # use score as index to store "[base] [number]"
#            ${(us::) }           # (s::)plit into characters, take (u)nique
a=($a)                            # remove empty elements from array
<<<$a[1]                          # print out the first element (smallest score)

在线尝试!

这是一个81字节的解决方案,它以表格形式打印[base]#[num]

for b ({36..2})x=$[[#$b]$1]&&y=${x#*\#}&&a[$#y+${#${(us::)y}}]=$x
a=($a)
<<<$a[1]

在线尝试!



2

木炭,38字节

Nθ≔EE³⁴↨θ⁺²ιL⁺ιΦι⁼λ⌕ικη≔⁺²⌕η⌊ηηIη ↥⍘θη

在线尝试!链接是详细版本的代码。说明:

Nθ

输入整数。

≔EE³⁴↨θ⁺²ι

将其从2转换为36

L⁺ιΦι⁼λ⌕ικη

...重复数据删除,连接并占用长度。

≔⁺²⌕η⌊ηη

取最小复杂度的索引并加2得出基数。

Iη ↥⍘θη

打印基数和以大写形式转换为该基数的整数。



2

果冻,25个字节

bⱮ36µQL+LN)Mḟ1Ḣ,ị‘ịØBʋ¥⁸K

在线尝试!

以整数为参数并返回所需格式的Jelly字符串的单子链接。如果两个项目的列表是可接受的输出(按照大多数挑战),则可以节省2个字节。如果对于1的边缘情况而言,以1为底是可接受的,则可以再节省2个字节。



1

Perl 5,161个字节

sub f{$X=99;for$b(2..36){$_=c($_[0],$b);$x=uniq(/./g)+y///c;($X,$B,$C)=($x,$b,$_)if$x<$X}$B,$C}
sub c{my($n,$b)=@_;$n?c(int$n/$b,$b).chr(48+$n%$b+7*($n%$b>9)):''}

在线尝试!



1

Perl 5中 -Minteger -MList::Util=uniq,first -ap123个 112字节

$"=$,;map{@r=();$t="@F";do{unshift@r,(0..9,A..Z)[$t%$_]}while$t/=$_;$a[@r+uniq@r]||="$_ @r"}2..36;$_=first{$_}@a

在线尝试!


1

Wolfram语言(Mathematica)109111字节

Print[a=OrderingBy[#~IntegerDigits~Range@36,Tr[1^#]+Tr[1^Union@#]&,1][[1]]," ",ToUpperCase[#~IntegerString~a]]&

+2:固定。感谢@Roman的收获

OrderingBy 是在Mathematica 12.0中引入的,TIO似乎尚未更新。


“如果多个基准为标准提供相同的值,则在其中选择最小的基准。”:OrderingBy不符合此要求。
罗马

也许用的东西MinimalBy喜欢这个
罗马,

@罗马不是吗?据我所知,它保留了两个具有相同值的索引的相对顺序
。– attinat

2
使用参数123,您的解决方案将打印出来,36 3F而不是必需的12 A3。从OrderingBy[123~IntegerDigits~Range@36, Tr[1^#] + Tr[1^Union@#] &]我得到的答案中{36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, 12, 6, 5, 11, 10, 9, 8, 7, 4, 3, 2, 1},所以这里似乎没有忽略对等价条目进行重新排序的通常假设。我$Version的名字是“适用于Mac OS X x86(64位)的12.0.0(2019年4月7日)”。
罗马,

啊,你是对的。我不好注意到这一点。
attinat

1

C(clang),165个字节

n,i=2,j,p=99,r,m,x;char*g,*_,b[74][37];t(n){for(;g=b[i],i<37;r=j<p?_=g,p=j,i:r,++i)for(j=0,m=n;m;m/=i,*--g=x+=x>9?87:48)j+=b[i+36][x=m%i]++?1:2;printf("%i,%s",r,_);}

在线尝试!

n //输入

,i = 2 //迭代器从2到36

,j //当前复杂度

,p = 99 //最佳复杂度

,r // result =迭代器

,m // n的临时副本

,x; // m%i

char * g //当前字符串ptr

,* _ //最佳str ptr

,b [74] [37]; //缓冲区

/ * [37 + 37] = [获得的字符串+测试使用过的字符] * /

t(n){

for(; g = b [i],//移动点

   i<37 ; 
   r=j<p?_=g,p=j,i:r, // save best solution

   ++i){//for every base

for(j = 0,m = n; m; m / = i,//提取数字

   *--g=x+=x>9?87:48)
   // move ptr backward for printf use and transform to ascii value

j + = b [i + 36] [x = m%i] ++?1:2; //相对于字符的增量字节

//如果为0,则将使用的新字符的j值以2:1递增,以1的位数计数

//否则只增加数字计数+移动指针

// printf(“%s-”,g); //测试

// printf(“ r%ip%ij%i \ n”,r,p,j); //测试

}

printf(“%i,%s”,r,_); //输出

}


1
163个字节可以被调用多次。
ceilingcat '19

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.