番号のソートされた字句分割


17

課題は実に簡単です。数字が与えられたら、その数字を小さな数字の配列に分割し、結果の数字が減少しないようにします。キャッチは、配列の長さが最大になるように分割する必要があるということです。

混乱した?

  • STDIN(または最も近い代替)、コマンドライン引数、または便利で明白な入力形式の関数引数を介して正の整数が与えられます。
  • 数値の10進数を連続した互いに素なグループに分割する必要があります。
  • これらの数字グループで表される数値の配列は、グループを再配置せずに(通常の減少しない順序で)ソートする必要があります
  • そのようなパーティションが複数存在する場合は、入力をできるだけ多くの数にパーティション分割する必要があります。同数の場合、そのような結果を1つ返します。
  • 配列をSTDOUT(または最も近い代替)に出力するか、関数の戻り値として出力できます。STDOUT(または最も近い代替)の場合、配列は便利で明確なリスト形式で印刷する必要があります。
  • 分割番号の先頭にゼロを付けないでください。そのため、たとえば1002003[1, 002, 003]またはとして印刷することはできず[1, 2, 3]、それに対する唯一の有効な答えは[100, 2003]です。

テストケース:

123456 -> [1, 2, 3, 4, 5, 6]
345823 -> [3, 4, 5, 8, 23]
12345678901234567890 -> [1, 2, 3, 4, 5, 6, 7, 8, 90, 123, 456, 7890]
102 -> [102]
302 -> [302]
324142 -> [3, 24, 142] OR [32, 41, 42]
324142434445 -> [32, 41, 42, 43, 44, 45]
1356531 -> [1, 3, 5, 6, 531]
11121111111 -> [1, 1, 1, 2, 11, 11, 111]
100202003 -> [100, 202003]

得点

これはコードゴルフなので、バイト単位の最短コードが優先されます。

回答:


10

Pyth、34

FNyUz#aYmv:zhdedC,+0N+NlzB)efqSTTY

こちらからオンラインでお試しください。これには、O(n)の時間(およびスペース)複雑さがあります。そのため、12345678901234567890オンラインコンパイラではテストケースに時間がかかりすぎます。代わりにオフラインのものを使用します(ラップトップで1分)。

これは私の初めての試みです。改善の余地があるかもしれません。

最初に、私のアルゴリズムがどのように機能するかをいくつか考えます。

  • 入力を数値ではなく文字列として解釈します。
  • 次に、可能なすべてのサブセットを作成します [0, 1, 2, ..., len(n-1)]
  • これらのサブセット(letを取得[1, 4, 5])ごとに、これらの数値を使用して入力文字列を部分に分割します。[input[0:1], input[1, 4], input[4,5], input[5,len(input)]]
  • その後、これらの数値を文字列に変換しようとします。2つの問題があります。Pyth(またはPython)は、空の文字列、およびで始まる数字の文字列に対して例外をスローし0ます。したがって、try - catchブロックを使用します(実際には、即時ブレークのある無限ループ)。変換が成功した場合、結果をリストに追加しますY
  • すべてのサブセットを処理した後Y、結果のリストをフィルター処理します。結果は既に並べ替えられており、最後のリストが印刷されます(最後のグループのグループが最も多くなります)。

今、詳細な説明:

                            Implicit: z = input() (z is a String!)
                                      Y = empty list
FNyUz                       for each subset N of [0, 1, 2, ..., len(z)-1]:

     #                         start try-catch block (actually an infinite loop, 
                               but the Python implementation uses a try catch. 

      aY                          append to Y:
                C,+0N+Nlz            zip([0] + N, N + [len(z)])
        m                            map each element d to
          :zhded                     z[d[0]:d[-1]]
         v                           evaluated
                         B        if this didn't throw an exception already, end the infinite loop
                          ) end for loop   

 f    Y      filter Y for elements T, for which
  qSTT           sorted(T) == T
e            and print the last one (the subsets generated with yUz are sorted 
             by length, so the last one has the most groups)

aY代わりに使用できます~Y]
-FryAmTheEggman

@FryAmTheEggman私はいつも忘れていaます。理由がわからない。
ジャクベ

@Jakubeおそらくドキュメントにないのですか?
Sp3000

45文字までの解決策がありました。int("01")Pythでエラーが発生するという事実を知りませんでした(これはPythonでは発生しません)。
orlp

3
@Jakube haha​​、論理的に見えますが、一般的にnは入力の長さです。
オプティマイザー

6

Mathematica、134 127バイト

有効なパーティションよりもはるかに多くのパーティションを生成するため、これはかなり非効率的です。324142434445テストケースは、数秒以内に実行されますが、私がしようとしないでしょう12345678901234567890

f/@Last@Select[Needs@"Combinatorica`";f=FromDigits;SetPartitions[d=IntegerDigits@#],0<=##&@@f/@#&&Join@@#==d&&#~FreeQ~{0,__}&]&

これは、整数を取り、整数のリストを返す名前のない関数を定義します。

説明

このコードの読み取り順序は、いたるところにあるので、読み取ることを意図した順序で分類します(ほとんどの場合は評価します)。

  • d=IntegerDigits@#入力の10進数を取得し、このリストをに割り当てdます。
  • SetPartitions(これにはが必要ですNeeds@"Combinatorica`";)このパーティションがすべて提供されます。ただし、入力をセットとして扱うため、実際に必要なものよりも多くの結果が返さます。これが非効率的な理由ですが、すべてのリストパーティションを取得する最短の方法がはるかに長いため、これを使用しています。例として、リストが{1, 2, 3}関数の場合は次を返します。

    {{{1, 2, 3}}, {{1}, {2, 3}}, {{1, 2}, {3}}, {{1, 3}, {2}}, {{1}, {2}, {3}}}
    

    a)連続したパーティションはすべて正しい順序であり、b)パーティションは最も粗いものから最高のものにソートされることに注意してください。

  • Select[...,...&] 次に、2番目の引数として渡された匿名関数によってこのリストをフィルタリングします。
    • Join @@ # == d 一般的なセットパーティションではなくリストパーティションが実際にあることを確認します。
    • #~FreeQ~{0, __} 先頭のゼロで始まるパーティションがないことを確認します。
    • 0 <= ## & @@ f /@ #少しあいまいです。まずFromDigits、パーティションの各リストにマッピングして、数字で表される数値を復元します。次に0 <= ##、それらの番号に適用し##ます。ここで、すべての番号を指します。パーティションがの場合、{1, 23, 45}これはに展開される0 <= 1 <= 23 <= 45ため、配列がソートされていることを確認します。
  • Last@その後、フィルタリング後に残った最後のパーティションを私に与えます-これSetPartitionsは、最も素晴らしいパーティションが最後になるようにパーティションをすでにソートしているため機能します。
  • 最後に、f/@数字リストから数字を回復します。

5

Python 3、134バイト

def f(s,n=0,L=[],R=[],i=0):
 while s[i:]:i+=1;m=int(s[:i]);R=max([f(s[i:],m,L+[m]),R][m<n or"1">s[i:]>"":],key=len)
 return[L,R][s>""]

少し面倒ですが、まあまあです。プログラムはすべての有効なパーティションを再帰的に生成します。興味深い部分は、先行ゼロを許可しないために必要なのは追加のor "1">s[i:]>""条件だけだったことです。

のような入力を受け取りf("12345678901234567890")、intのリストを返します。


4

Pyth、 62 61 60

JlzKkef&qJsml`dTqTSTolNmmibTcjKsC,z+m>Ndt>+*J]0jk2_JKNU^2-J1

説明

アルゴリズムは、入力の長さである0(包括的)と2^(n-1)(排他的)の間のすべての2進数を生成することによって機能しnます。

それぞれの2進数は、1の場合はセパレーター(N)にマッピングされ、0の場合は何にもマッピングされません。

次に、これらの文字が各入力文字の間に挿入され、結果がで分割されNてリストが生成されます。

リスト内の値は整数に解析され、リストは長さでソートされます。残っているのは、ソートされていないものと、先頭のゼロで分割されたものを除外することです。その後、最長のリストが選択されます。

Jlz                                                   set J to len(input)
Kk                                                    set K to ""
e                                                     take the last of:
 f&                                                    only take lists where:
   qJsml`dT                                             sum of string lengths of items
                                                        is equal to length of input and
           qTST                                         list is in order
               olN                                       sort by length
                  m                                       map k over...
                   mibT                                    convert items to int (base-10)
                       c                        N           split by N
                        jK                                   join by ""
                          s                                   sum to combine tuples
                           C,z                                 zip input with
                              +                K                append [""] for equal lengths
                               m>Nd                              replace 1 with N, 0 with ""
                                   t                              take all but first
                                    >        _J                    take len(input) last values
                                     +                              pad front of binary with
                                      *J]0                           [0] times input's length
                                          jk2                        current k in binary
                                                 U^2-J1  range 0..2^(len(input)-1)-1

1

(非互換)Pyth、25バイト

ef&&Fmnhd\0T.A<V=NsMTtN./

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

使い方:

ef&&Fmnhd\0T.A<V=NsMTtN./  Q = eval(input())
                         ./  all partitions of Q
 f                       ./  filter all partitions of Q where:
  &                            both:
   &Fmnhd\0T                     neither substring starts with "0"
                               and:
            .A<V=NsMTtN          all entries are less than their proceeding ones
e                            returns the last amongst the filtered partitions

0

J、109バイト

非常に長いですが、少なくともO(n *(2n)!)のメモリとO(n * log(n)*(2n)!)の時間を消費します。nは入力の長さです。(したがって、5桁以上で実行しないでください。)

f=.3 :0
>({~(i.>./)@:(((-:/:~)@(#$])*#)@>))<@".(' 0';' _1')rplc"1~(#~y-:"1' '-."#:~])(i.!2*#y)A.y,' '#~#y
)

この関数は入力を文字列として受け取ります。

例:

   f every '5423';'103';'1023'
  5 423
103   0
 10  23

方法:

  • 同じ長さのスペースを入力に追加します。
  • あらゆる方法でそれを変更します。
  • スペースレス文字列が入力と同じかどうか(つまり、そのパーティション)を確認します。
  • '0'を '_1'に置き換えて、先行ゼロソリューションを無効にします。
  • 各文字列を評価します。
  • ソートされている最長のリストを見つけます。これは戻り値です。

0

Haskell、161バイト

(#)=map
f[x]=[[[x]]]
f(h:t)=([h]:)#f t++(\(a:b)->(h:a):b)#f t
g l=snd$maximum[(length x,x::[Int])|x<-[read#y|y<-f l,all((/='0').head)y],and$zipWith(>=)=<<tail$x]

テスト走行:

*Main> mapM_ (print . g) ["123456","345823","12345678901234567890","102","302","324142","324142434445","1356531","11121111111","100202003"]
[1,2,3,4,5,6]
[3,4,5,8,23]
[1,2,3,4,5,6,7,8,90,123,456,7890]
[102]
[302]
[32,41,42]
[32,41,42,43,44,45]
[1,3,5,6,531]
[1,1,1,2,11,11,111]
[100,202003]

仕組み:ヘルパー関数fは、入力リストをサブリストのすべての可能なリストに分割します。g最初にサブリストが始まるものを破棄し0、次に適切な順序のないものを破棄します。残りのすべてのリストをその長さとペアにし、最大値を取り、長さの部分を再度破棄します。

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