数値を「まったく価値のないシステム」に変換する


11

数値の長さmのn番目の値(右から左にカウント)の最大桁が常にm-n + 1に等しい数値のシステムを作成します。例を挙げると、このシステムで表現可能な最大5桁の数値12345と書かれています。特定の場所で使用できる桁数が制限されていることを除けば、他のすべての増分は標準です。つまり、桁がその桁制限を超える場合、次の桁に1を追加します。

このシステムでカウントがどのように表示されるかを次に示します。

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

最後のケースは、実装方法によっては実行が非常に遅くなる場合があります。時間がかかりすぎたり、メモリを使いすぎる場合は、実行する必要はありません。ただし、迅速に実行し、メモリをほとんど使用しない方法が存在することに注意してください。


あなたの最後のコメントを考えると、数字を含むリストを常に返しても大丈夫ですか?
グレッグマーティン

はい、数値が正しい限り、それは出力を提供する合理的な方法です
安藤坂東

1
100 -> 10035ではなく取得してい100 -> 10033ます、確認できますか?
グレッグマーティン

@GregMartin 10035は正しいようです。プログラムではなくペンで計算したため、計算エラーが発生しました。私たちには理由があるコンピュータがあると思います
安藤坂東

回答:


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}にある2番目の要素がにあるなど{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]時間に適用fした結果を与えexpr nます。この場合、exprはリスト{0}nあり、入力整数#です。関数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

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で表されるゼロから始まるこれらすべての数の無限リストを作成し[]ます。あとは!!、要求された数と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

最初の行は補助的な定義であり、2番目の行は関数に評価されます。整数を受け取り、整数のリストを返します。 オンラインでお試しください!

説明

xチャレンジテキストで言及されている表現の無限リストとして定義します。メイン関数は引数とインデックスをデクリメントするだけ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は遅延しているため、これは問題ではありません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.