最短最長増加サブシーケンスコード


11

挑戦は最も長く増加しているサブシーケンスを見つけるために最も短い実装を書くことです。

例:Sをシーケンス1 5 7 1 8 4 3 5 [Sの長さ= 8]とする

  • 長さ0のサブシーケンスが1つあります[増加するとみなします]
  • 長さ1の6つのサブシーケンス{1,5,7,8,4,3} [これらはすべて増加していると見なされます]
  • (7 * 8)/ 2の長さ2のサブシーケンス[ただし、重複を削除します]、増加するサブシーケンスは強い黒で表示されます。
    { 15,17、11、18,14,13,57、51、58、54,53,55,71、78、74,73,75,84,83,85,43、45,35 }

[厳密に増加するサブシーケンスにのみ関心があることに注意してください]

[ シーケンス内の要素の順序は変更できないため、シーケンス例にはサブシーケンス[37]はありません]

  • 1578である長さ4のサブシーケンスが増加していますが、長さ5のサブシーケンスはありません。したがって、最大の増加サブシーケンス= 4の長さを考慮します。

入力:

a 1 a 2 ... a N (シーケンス)

すべての数値は10 3
N <= 1000 より小さい正の整数です

出力:

入力シーケンスの最も長く増加するサブシーケンスの長さを示す1つの整数。

sample input(1)
1 2 4 2 5
sample output(1)
4

sample input(2)
1 5 7 1 8 4 3 5
sample output(2)
4

コードをタイムリーに実行する必要があります。ここに送信する前に、このケースでコードをテストしてください(リンクには290バイトのc ++ 11ソリューションが含まれています)

ファイル/ stdinから、または関数パラメーターとして入力を取得し、出力をファイル/ stdoutに出力するか、関数を記述する場合に値を返すことができます。

スコアボード

  1. デニス CJam- 22
  2. isaacg Pyth- 26
  3. ハワード GolfScript- 35
  4. 誇り高きハスケラーハスケル-56
  5. レイパイソン3-66
  6. histocrat Ruby- 67
  7. DLeh C#-92
  8. YosemiteMark Clojure- 94
  9. faubiguy - Pythonの3 113

1
:)まあ、技術的にあなたは長さ0のサブシーケンスの無限の数を持っている、「私たちは、長さが0 [それは増やすことを検討します]の1サブシーケンスを持っている」
— たけた

実際には、すべての「セット」が重複を削除するようにステートメントを変更する必要があります。たとえば、{1,5,7,1,8,4,3,5}は{1,5,7,8,4 、3}そして、 "Set"には長さ0のサブシーケンスが1つあると言えます。おかげで
— モスタファ36a2 14

1
関数の場合、外部関数(function f(){...})または内部関数(ちょうど...)のバイトをカウントする必要がありますか?外部関数を数える場合、匿名関数は許可されますか?
— デニス14

私たちは、外側の関数をカウントし、匿名の機能が許可されている、しかし、(入力/出力処理との完全なバージョン)検証可能なバージョンを提供するために逃してはいけない
— 36a2ムスタファを

回答:


2

CJam、22バイト

1e3,q~{_2$<$0=(t}/$0=z

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

例

$ cjam subsequence.cjam <<< '[2 1]'; echo
1
$ cjam subsequence.cjam <<< '[1 9 2 4 3 5]'; echo
4

このテストケースのプログラムは57、0.25秒後に印刷されます。

使い方

@Rayのanswerから一般的なアイデアを取りました。

1e3,    " Push the array [ 0 ... 999 ] (J).        ";
q~      " Read from STDIN and evaluate.            ";
{       " For each integer (I) of the input array: ";
  _2$<  " Push [ J[0] ... J[I - 1] ] (A).          ";
  $0=(  " Compute min(A) - 1.                      ";
  t     " Update J[I] with the value on the stack. ";
}/      "                                          ";
$0=     " Compute abs(min(J)).                     ";

5

Python 3、66

すべての数値の範囲は[1、999]であることに注意してください。配列bを使用して、各数値で終わる最長のサブシーケンスの長さを維持できます。b[x] = dは、で終わる最長のサブシーケンスのx長さがであることを意味しdます。入力からの各番号に対して、を使用b[x] = max(b[:x]) + 1して配列を更新し、max(b)最終的に取得することでジョブを完了しました。

時間の複雑さは オン) O(mn)は、m常に1000でnあり、入力要素の数です。

def f(a):
 b=[0]*1000
 for x in a:b[x]=max(b[:x])+1
 return max(b)

うわー、すでに未ゴルフのように見える:)次の行を追加して、stdin / stdoutを使用してテストできます。

print(f(map(int,input().split())))

for x in a: max(b)ほぼO(n ^ 2)に見えます。
— ハワード14

@HowardそれO(1000 n)は1000であり、定数です。としても考えることができますO(m n)。
— レイ14

3
そのような議論では、限られた入力では複雑さが常にあるため、議論全体は役に立たないO(1);-)
— ハワード14

@Howard私はACM-ICPCの世界から来ました。これはやや慣習です。O(mn)と考えることができます。まだO(n ^ 2)とは異なります。とにかく、費用は通訳者の起動時間よりも短いので、十分に速いと思います。
— レイ14

驚くほど短いアルゴリズム!(少なくともPython 2に切り替えたときは)1文字しか見つけることができません:結果を印刷できます。printはより短いreturn。
— ファルコ14

3

パイソン-113

a=[]
for i in map(int,input().split()):
 if not a or i>a[-1]:a+=[i]
 z=0
 while a[z]<i:z+=1
 a[z]=i
print(len(a))

受け入れられた解決策。あなたのコードはこことここでテストされました。
— モスタファ36a2 14

@ Mostafa36a2「受け入れられた」という言葉は、このサイトでは別の意味を持っています。あなたの言っていることは「受け入れられる」と思います。
— レイ14

申し訳ありませんが、はい、受け入れられるものを選ぶには早すぎます。
— モスタファ36a2 14

行a+=[i]*(a==[]or i>a[-1]);z=0と印刷len(a)(括弧なし)を使用すると、4文字を保存できます。
— ファルコ14

3

ピス、26 29 33 39

J*]0^T3Fkyw=@JkheS:J0k)eSJ

@rayのソリューションのポート。公式テストに合格します。関数呼び出しではなく、スペースで区切られたSTDIN入力を使用するようになりました。

次のように実行します。

./pyth.py -c "J*]0^T3Fkyw=@JkheS:J0k)eSJ" <<< "1 5 7 2 8 4 3 5"
4

説明:

J*]0^T3                 J = [0]*10^3
Fkyw                    For k in space_sep(input()):
=@Jk                    J[k]=
heS:J0k                 max(J[0:k])+1
)                       end for
eSJ                     max(J)

時間制限なし:

パイス、18

L?eS,ytbhyf>Thbbb0

技術面での注意:このゴルフを書いているときに、Pythコンパイラにバグがあることに気付きました。L動作していませんでした。それが、上記のgitリポジトリーへの最近のコミットがある理由です。


あなたのコードは、大規模なリストの場合のためにタイムリーに実行されません(と言う100要素)
— ムスタファ36a2

3
@ Mostafa36a2ランタイムを要件にしたい場合は、質問にその旨を述べ、テストケースを1つまたは2つ追加してください。それが単なるコメントである場合、私は同意します、それはかなり遅いです。
— isaacg 14

申し訳ありませんが、それはランタイムではなく少なくとも[タイムリーな方法]であり、コードに10〜20分または1時間かかる場合でも問題ありませんが、O(2 ^ n)ソリューションでは結果が得られません私たちの長寿命。
— モスタファ36a2 14

@ Mostafa36a2わかった、その行に気付いた。改善に取り組みます。
— isaacg 14

1
申し訳ありませんが、現在更新プログラムが表示されています。このケースを試して、動作するかどうかを教えてください。
— モスタファ36a2 14

3

Clojure、94文字

1000アイテムのベクトルで結果を更新する@Rayのアプローチを使用します。

(defn g[s](apply max(reduce #(assoc % %2(inc(apply max(take %2 %))))(into[](repeat 1e3 0))s)))

要求ごとに、printステートメントを使用して(回答を出力し、nilを返します)。入力はベクトル(g [1 2 3])またはリスト(g '(1 2 3))である必要があります。

(defn g[s](prn(apply max(reduce #(assoc % %2(inc(apply max(take %2 %))))(into[](repeat 1e3 0))s))))

printステートメントを追加してテスト可能にしますか?スコアにはカウントされません。
— モスタファ36a2 14

1
更新しました。私はあなたの両方の大きな例でそれを実行しました、そして、予想通りに58と57を得ました。
— ヨセミテ

まだ関数:pを呼び出す必要があると思いますが、テストした場合はそれで十分です。
— モスタファ36a2

3

Haskell、58 57 56文字

(x:s)%v|v>x=x:s%v|0<1=v:s
_%v=[v]
l s=length$foldl(%)[]s

これは、インターネットで一度見たアルゴリズムを使用していますが、見つけることができません。GHCiを搭載したコンピューター上のテストケースでは、気付かないほどの時間がかかります(コンパイルされた場合は、さらに高速になるでしょう)。


あなたが言及したアルゴリズムは、@ faubiguyで使用されているものと同じです。
— レイ14

@Rayあなたが正しい
— 誇りに思ってhaskeller 14

2

GolfScript、35文字

~]]){1${~2$<*)}%1+$-1>[\+]+}/$-1=0=

STDINに入力された完全なプログラムとして機能する実装(指定された長さの番号なし)。長い入力の場合でも、実装は高速で合理的です(こちらをお試しください)。

例:

> 1 5 7 1 8 4 3 5
4

> 5 1 9 9 1 5
2

1
@MartinBüttner私のコンピューターでは1000個の数字に対して約5秒かかります。$O(n log n)と仮定すると、アルゴリズムはO(n ^ 2 log n)です。
— ハワード14


@ Mostafa36a2すでにやりました(前のコメントを参照)。5秒後には58を返します
— ハワード

これは別の一つであり、それは57を返す必要があり、あなたのコードはリターン57をした場合ので、それは受け入れられたのです:)おめでとう
— ムスタファ36a2

@ Mostafa36a2ああ、今、これらは2つの異なるテストケースであることがわかります。はい、この入力に関する私のソリューションと同様に、2番目のリンクは57を返します。
— ハワード14

2

ルビー、67

s=Hash.new{|s,a|f,*r=a
s[a]=f ?[1+s[r.select{|x|x>f}],s[r]].max: 0}

これは大規模な入力で30秒で実行されますが、タイムリーにカウントされますか?:p

それは野reな再帰ですが、いくつかのメモがあります。


1
はい、これはタイムリーな方法です:)
— モスタファ36a2 14

2

C#、172 92文字

特別なことは何もありませんでしたが、私はそれをしたので、私もそれを提出するかもしれないと考えました。

int a(int[] j){int c=2,m=2,i=1;for(;++i<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?c:m;}return m;}

アーミンとボブの改善に感謝します!


1
パラメーターをint []に変更すると、文字列をintにキャストする必要がないため、文字数が少なくなります。
— Armin 14

2
周りのスペース=>は不要です。i=0宣言をforループの外側に移動することもできint c=2,m=2,i=0;for(;ます。また、中にfor単一のステートメントしかないため、本体の周りに中括弧をドロップすることもできます。
— ボブ14

とc++;if(c>m)m=c;することができますm=c++>m?m:c;、そしてあなたは再びその中括弧をドロップすることができます。
— ボブ14

1
実際、ループを1から開始if(i>0)することにより、チェックを破棄することもできます。以前に提案されたものをforさらに短縮することができます。そのセクション全体をに変換することができ、残りの最後を置き換えるために、別の三元を使用して(-親指のルールは、あなたの場合は三元系は短いですボディは、単に割り当てである。int c=2,m=2,i=0;for(;i<j.Length;i++)if(i>0)int c=2,m=2,i=0;for(;i++<j.Length;)int c=2,m=2,i=0;for(;i++<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?m:c;}ifif
— ボブ

2
申し訳ありません-以前のコメントのタイプミスは、m=c>m?m:cはずですm=c>m?c:m。また、@ Arminの提案を追加すると、92バイトになり、サイズがほぼ半分になります。int a(int[] j){int c=2,m=2,i=0;for(;i++<j.Length;){c=j[i]>j[i-1]?c+1:2;m=c>m?c:m;}return m;}
— ボブ14

2

J、19バイト

[:#]`I.`[} ::,~/@|.

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

O(n log n)で実行します。実際のサブシーケンスではなく、長さのみが必要なので、修正された忍耐ソートを使用します。

説明

[:#]`I.`[} ::,~/@|.  Input: array
                 |.  Reverse
               /     Reduce right-to-left
     I.                Find the index to insert while keeping it sorted
                       (uses binary search)
         }             Amend the current search array at that index with the next value
           ::          If error (when the index is not found)
             ,           Append the value at the end
 #                   Length of that array

1

Bash + coreutils、131バイト

このソリューションは、タイムリーな要件でひどく失敗し、特に短いものではありませんが、シェルスクリプトではこの種のことが少なくとも理論的に可能であることが気に入ったので、とにかく投稿します。これは、O(2 ^ n)の永遠性を誘導する時間の複雑さで実行されます。

s=${1//,/,:\},\{}
a=`eval echo "{$s,:}"`
for s in $a;{
b="$(tr , \\n<<<$s|grep -v :)"
sort -nC<<<"$b"&&wc -w<<<$b
}|sort -nr|sed 1q

入力は、単一のコマンドライン引数として渡されるコンマ区切りリストです。

$ time ./slisc.sh 1,5,7,1,8,4,3,5
4

real    0m1.240s
user    0m0.518s
sys 0m0.689s
$ 

ブレース展開は、すべての可能なサブシーケンスのリストを作成するために使用されます。

  • 最初の行は、コンマを,:},{に置き換え、次のような文字列を生成します1,:},{5,:},{7,:},{1,:},{8,:},{4,:},{3,:},{5
  • 2行目は、この文字列を中括弧、コンマ、セミコロンで補完して、これを指定し{1,:},{5,:},{7,:},{1,:},{8,:},{4,:},{3,:},{5,:}ます。これは有効なbash brace展開であり、evaledを使用しechoてこのスペース区切りリストを生成します1,5,7,1,8,4,3,5 1,5,7,1,8,4,3,: 1,5,7,1,8,4,:,5 1,5,7,1,8,4,:,: ...
  • デフォルトでは、bashは空白で文字列を分割するため、このリストの各要素をループします。
    • コンマは改行に置き換えられ、コロンを含む行は削除され、可能なサブシーケンスごとに改行で区切られたリストが提供されます
    • 次にsort -C、昇順をテストし、もしそうならwc -w、リストの長さを印刷するために使用します
  • 結果として得られるリストの長さのリストは逆順にソートされ、最初の値が出力されて、サブシーケンスの長さが最も長くなります。

1

スタックス、21 バイト

ë/NS7Γ╥╚┌{1╤╒¬è¶²╢╦┌☼

実行してデバッグする

これには2つのテストケースがあり、そのうちの1つは1000要素のケースです。私のマシンでは24秒に1回実行されます。このタイプの問題には、従来の動的プログラミングアプローチを使用します。


0

J 34

標準入力も読むことに注意してください。

>./;+/@:*&.>(<*>.)/\&.><\.".1!:1]3

標準入力を読み取らないと、肉は26文字になります。

>./;+/@:*&.>(<*>.)/\&.><\.

大規模な入力の場合、鉱山の実行速度が遅いことに気づきました。



0

C#(.NET Core)、155バイト

配列を使用して、入力配列の各位置で終了する最長の増加サブシーケンスを計算し(動的プログラミング)、最大値を返しました。例えば、入力のための計算された配列は、[1,5,7,1,8,4,3,5]あろう[1,2,3,1,4,2,2,3]、そして最大値が4返されます。

int b(int[]x){int l=x.Length,r=1,i=0,j,c;var a=new int[l];a[0]=1;while(++i<l)for(j=0;j<i;j++){c=x[j]<x[i]?a[j]+1:1;a[i]=a[i]<c?c:a[i];r=r<c?c:r;}return r;}

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


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