将数字转换为“不太地方价值的系统”


11

让我们创建一个数字系统,其中数字长度m的第n位值(从右到左)中的最大数字始终等于m-n +1。例如,在此系统中可表示的最大5位数字是写在12345。除了在特定位置可用的位数受限制外,其他所有增量都是标准的。即,当一个数字超过其数字限制时,我们在下一个数字上加一个。

这是此系统中计数的表示方式:

1; 10; 11; 12; 100; 101; 102; 103; 110; 111; 112; 113; 120; 121; 122; 123; 1000; 1001 ...

您的任务是编写一个函数,该函数采用标准的以10为底的数字,并将其转换为我的编号系统。

较短的代码是可取的。波恩机会!

**如果需要9(必须)之后的数字,则可以选择使用字母,也可以返回2位数字作为列表的元素。

测试用例

10 -> 111
20 -> 1003
30 -> 1023
50 -> 1123
100 -> 10035
23116 -> 1234567
21977356 -> 123456789A

根据您的实现方式,最后一种情况运行起来可能会非常慢。如果它花费的时间太长或使用了太多的内存,则无需运行它。但是请注意,有一些方法可以使其快速运行并且使用很少的内存。


考虑到您的最后评论,如果我们总是返回带有数字的列表,可以吗?
格雷格·马丁

是的,只要数字正确,这就是给出输出的一种合理方法
Ando Bando

1
我得到的100 -> 10035不是100 -> 10033,您可以验证吗?
格雷格·马丁

@GregMartin 10035似乎正确。我用笔而不是程序进行计算,因此出现了计算错误。我想我们有一台计算机可以应对
Ando Bando

Answers:


4

Mathematica,64个字节

Part[Join@@Array[Tuples@Join[{{1}},Array[Range,#-1,3]-1]&,#],#]&

未命名函数采用正整数参数并返回整数列表。

Join[{{1}},Array[Range,#-1,3]-1]返回嵌套列表{ {1}, {0,1,2}, {0,1,2,3}, ..., {0,1,...,#} }。然后Tuples返回第一个元素位于{1},第二个元素位于的所有元组的(排序的)集合{0,1,2},依此类推;这些是#此编号系统中的- 位数字。Join@@Array[...,#]返回此编号系统中所有数字最多包含一个#数字的数组,并Part[...,#]提取该#数字。

这真是太慢了!它运行用于将输入到9。对于较大的输入,通过更换结束测试细,#],#]&,Ceiling[0.9Log[#]]],#]&; 这为在编号系统中找到足够的位数以找到我们想要的位数提供了更为现实的上限。


3

Mathematica,93个字节

Nest[#/.{x___,y_}:>{x,y+1}//.x:{y___,z_:0,w_,v___}/;w>Tr[1^x]-Tr[1^{v}]:>{y,z+1,0,v}&,{0},#]&

具有第一个参数的纯函数#。如果给出一个非负整数,它将输出正确的数字列表(甚至0正确处理!)。

说明

Nest[f,expr,n]给出适用fexpr n时间的结果。在这种情况下,expr是列表,{0}并且n是输入integer #。功能f很复杂:

# (* Starting with the input # *)
 /. (* Apply the following rule *)
   {x___,y_} (* If you see a list of the form {x___,y} *)
            :> (* replace it with *)
              {x,y+1} (* this *)
                     //. (* Now apply the following rule repeatedly until nothing changes *)
                        x:{y___,z_:0,w_,v___} (* If you see a list x starting with a sequence y of 0 or more elements, 
                                                 followed by an optional element z (default value of 0),
                                                 followed by an element w,
                                                 followed by a sequence v of 0 or more elements *)
                                             /; (* such that *)
                                               w>Tr[1^x]-Tr[1^{v}] (* w is greater than the length of x minus the length of {v} *)
                                                                  :> (* replace it with *)
                                                                    {y,z+1,0,v}& (* this *)

很好的使用,y___,z_:0以增加列表的长度!
格雷格·马丁

2
@GregMartin JungHwan Min 昨天在类似的问题中使用了它。
ngenisis '17

3

Perl 6、38个字节

{map({|[X] 1,|map ^*,3..$_},1..*)[$_]}

取一个正整数,并输出代表数字的整数列表。

说明:

{                                    }  # a lambda

 map({                    },1..*)       # for each number length from 0 to infinity,
                                        # offset by 1 to avoid a +1 in next step...

           1,|map ^*,3..$_              # generate the digit ranges, e.g.:
                                        #     length 0  ->  (1)  # bogus, but irrelevant
                                        #     length 1  ->  (1)
                                        #     length 2  ->  (1, 0..2)
                                        #     length 3  ->  (1, 0..2, 0..3)
                                        #     length 4  ->  (1, 0..2, 0..3, 0..4)

       [X]                              # take the cartesian product

      |                                 # slip the results into the outer sequence

                                 [$_]   # Index the sequence generated this way


1

Haskell,65个字节

i(x:r)|x>length r=0:i r|1<2=1+x:r
i[]=[1]
reverse.(iterate i[]!!)

i在数字系统中按相反的顺序增加数字。iterate创建以0开头的所有这些数字的无限列表,该列表由表示[]。然后,剩下要做的就是取(!!)所需的数字及其reverse

最后一行是函数,而不是函数定义,因此它不能像在源代码文件中一样显示。相反,仅将其他行放在源代码中,并在解释器中使用最后一行(或通过f=在最后一行之前将函数绑定到名称)。

使用示例:

*Main> reverse.(iterate i[]!!) $ 100
[1,0,0,3,5]

(如果[5,3,0,0,1]允许的结果表示形式,则可以节省8个字节。)


1

Haskell,49个字节

x=[1]:[n++[d]|n<-x,d<-[0..length n+1]]
(x!!).pred

第一行是辅助定义,第二行是函数。它需要一个整数并返回一个整数列表。 在线尝试!

说明

我将其定义x为挑战文本中提到的表示形式的无限列表;main函数只是减少其参数并索引到中x。第一行是这样的:

x=                     -- The list of lists x contains
 [1]:                  -- the list [1], followed by
 [n++[d]|              -- integer d appended to list n, where
  n<-x,                -- n is drawn from x, and
  d<-[0..length n+1]]  -- the new "digit" d is drawn from this range.

您会看到它x是根据自身定义的,但是Haskell很懒,因此这不是问题。

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.