最小数の連続する単調サブシーケンス


23

チャレンジの説明

単調なサブシーケンスは数字の列である[a1, a2, ..., an]ように

a1 <= a2 <= ... <= anまたはa1 >= a2 >= ... >= an[1, 3, 3, 7, 9, 13, 13, 100]は、単調な(減少しない)サブシーケンスであると同時に[9, 4, 4, 3, 0, -10, -12](これは増加しない)サブシーケンス[1, 3, 6, 9, 8]ですが、そうではありません。整数のリスト(任意の妥当な形式)が与えられNたら、これらの整数のシーケンスがN単調シーケンスに分割できるように、最小数を出力します。

[1, 3, 7, 5, 4, 2] -> [[1, 3, 7], [5, 4, 2]] -> 2
[1, 2, 3, 4, 5, 6] -> [1, 2, 3, 4, 5, 6]     -> 1
[3, 1, 5, 5, 6]    -> [[3, 1], [5, 5, 6]]    -> 2
[4, 6, 8, 9, 1, 6] -> [[4, 6, 8, 9], [1, 6]] -> 2
[3, 3, 3, 3]       -> [[3, 3, 3, 3]]         -> 1
[7]                -> [[7]]                  -> 1
[]                 -> []                     -> anything (you don't actually have to handle an empty list case)
[1, 3, 2, -1, 6, 9, 10, 2, 1, -12] -> [[1, 3], [2, -1], [6, 9, 10], [2, 1, -12]] -> 4

明確にするために、サブシーケンスは連続している必要がありますよね?
ズガルブ

@Zgarbはい、そうです。
shooqie

3
私は、シーケンスは常に逆方向に行っていないテストケースを追加することをお勧めしたい: [4,4,8,8,1,4,5] -> 2
ネイサン・メリル

@NathanMerrill:良い点です。
shooqie

空の文字列に対してそれを書くと、結果は0 / undefined、それは0またはundefined私たちの言語の表現のいずれかであるように聞こえますが、ジョナサン・アランのジェリーの答えに対するあなたのコメントから、それはundefined手段のように見えanythingます... ?2番目のケースでは、anything代わりに書くことをお勧めしますundefined
ダダ

回答:


6

Brachylog、12バイト

~c:{<=|>=}al

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

これはfalse.空のリストを返します[]

説明

(?)~c                 Take a list of sublists which when concatenated result in the Input
     :{<=|>=}a        Each sublist must be either increasing or decreasing
              l(.)    Output is the length of that list

これは~c、最小数のサブリストから最大数までの選択ポイントを生成するため、最小のものを返します。


TIOリンクの引数「Z」とは何ですか?(コマンドライン引数のようにプログラムの一部であるようです)。
ジョナサンアラン

@JonathanAllanこの引数は出力です。TIOのインターフェイスをカスタマイズできれば、入力と出力があり、引数がないことが理想です。引数は変数名であるZためZです。そのため、「変数として出力を使用してこのプログラムを呼び出す」と言っています。あなたは変更することができますZ、他の大文字。それは単なる変数名です。この引数が存在する理由は、出力を変数ではなく何かに実際に設定できるようにするためです。
16年

(たとえば4、その例で出力をに設定すると、それが正しいかどうかが
わかり

1
@JonathanAllan Prologのような言語は次のようなものです。述語は成功または失敗するだけで、値を返しません。したがって、出力を取得するには、結果に統合される述語への可変引数が必要です。
16年

1
@JonathanAllan 3すべてが単調で長さのあるサブリストのリストを見つけられないため、最終的に失敗します3。リストを見つけた後に長さがチェックされるため、実際には3要素より長いサブリストのすべての可能なリストを試すため、長い時間がかかります。なぜなら5true実際には5単調なサブリストを持つ長さのリストが少なくとも1つあるからです。そのため、このプログラムは、出力が変数であり、出力が整数の場合に機能するその長さのリストがあるかどうかで、最小の長さを返します。
16年

4

Perl、65バイト

コードの62バイト+ -nフラグ用の3バイト。

monot_seq.pl:

#!perl -n
s/\S+ /($_<=>$&)*($&<=>$')-$g>=0?$g=1:$.++;$g--;$_=$&/ge,$_=$.

スペースで区切られた数字を使用して、最後の改行なしで入力を行います。

$ echo -n "1 3 2 -1 6 9 10 2 1 -12" | perl -M5.010 monot_seq.pl
4

@Gabriel Benamyのおかげで-5バイト。


回して5つのバイトを保存($&<=>$1)*($1<=>$2)||$1==$2($&<=>$1)*($1<=>$2)>=0
ガブリエルBenamy

@GabrielBenamy確かに、ありがとう。
ダダ

2

Mathematica、111バイト

d=#[[2]]-#[[1]]&;r=Rest;f@{n_}:=1;f@k__:=If[d@k==0,f@r@k,g[k Sign@d@k]];g@{n_}:=1;g@k__:=If[d@k>0,g@r@k,1+f@r@k]

f空でない数のリスト(整数または実数)をとる名前付き関数。前から後ろまで機能し、最初の要素を繰り返し破棄し、必要なサブシーケンスの数を追跡します。より詳細:

d = #[[2]] - #[[1]] &;         function: difference of the first two elements
r = Rest;                      function: a list with its first element dropped
f@{n_} := 1;                   f of a length-1 list equals 1
f@k__ := If[d@k == 0, f@r@k,   if the first two elements are equal, drop one
                                 element and call f again ...
            g[k Sign@d@k]];  ... otherwise call the helper function g on the
                                 list, multiplying by -1 if necessary to ensure
                                 that the list starts with an increase
g@{n_} := 1;                   g of a length-1 list equals 1
g@k__ := If[d@k > 0, g@r@k,    if the list starts with an increase, drop one
                                 element and call g again ...
            1 + f@r@k];        ... otherwise drop one element, call f on the
                                 resulting list, and add 1

d=#2-#&@@#&;また、いずれかfまたはg単項演算子として定義する±と、おそらくいくつかのバイトが節約されます。
マーティンエンダー

2

ゼリー、19 バイト

IṠḟ0E
ŒṖÇ€€0e$Ðḟḅ1Ṃ

TryItOnline!またはすべてのテストを実行します(空のリストの結果は1

どうやって?

IṠḟ0E - Link 1, test for monotonicity: a sublist
I     - incremental differences
 Ṡ    - sign {fall:-1; same:0; rise:1}
  ḟ0  - filter out the zeros
    E - all equal?

ŒṖÇ€€0e$Ðḟḅ1Ṃ - Main link
ŒṖ            - all partitions of the input list
  Ç€€         - call last link (1) as a monad for €ach for €ach
        Ðḟ    - filter out results:
       $      -    last two links as a monad
     0e       -        contains zero?
          ḅ1  - convert from unary (vectorises)
            Ṃ - minimum

(ただし、これがバイト数を最小化するのに最適な方法であるとは確信していません)


@shooqie- 「未定義」のコメントが与えられた場合、空のリストに値を返すことができますか?これは戻ります1(実際には、これよりも理にかなっていると思います0)。
ジョナサンアラン

1
つまり、それが意味するものですundefined-結果は無関係です。
shooqie

2

Perl、98 97 96 79バイト

($a,$b)=($a<=>$b)*($b<=>$c)<0?($c,shift,$d++):($b,$c)while$c=shift;say$d+1 if$a

入力は、実行時に提供される、スペースで区切られた数値のリストとして提供されます。

perl -M5.010 monotonic.pl 1 3 2 -1 6 9 10 2 1 -12
4

(4は出力です)

読みやすい:

($a,$b)=($a<=>$b)*($b<=>$c)<0
    ?($c,shift,$d++)
    :($b,$c)
  while$c=shift;
say$d+1
  if$a

「宇宙船演算子」<=>は、LHS <RHSの場合は-1、LHS = RHSの場合は0、LHS> RHSの場合は+1を返します。3つの連続した要素を比較するとき$a,$b,$c、彼らがしている単調かどうかを判断するために、正確に一つのがいる場合ではないということを決定することだけが必要だ$a<=>$b$b<=>$c1、その他である-1 -彼らの製品がある場合にのみ起こるどの-1。もしどちらか$a==$bまたは$b==$c、シーケンスは単調で、積は0です。の場合$a < $b < $c、両方とも-1と-1 * -1 = 1になります。の場合$a > $b > $c、両方とも1と1 * 1 = 1になります。どちらの場合でも、シーケンスは単調であり、継続したいと思います。

積が0より小さい場合、シーケンスが単調ではないことがわかり、次の値を破棄します。 $a,$b現在保持しているサブシーケンスカウンターをインクリメントします。それ以外の場合は、1つの数字を進めます。

入力が空の場合は何も返しません。そうでない場合は、連続する単調なサブシーケンスの最小数を返します


1との間にスペースは必要ありませんif(または、古いperlでは必要ですが、最近のperlでは必要ありません)。また、あなたは(おそらく)を置き換えることができますshiftによってpop。ただし、コードが機能しないテストケースがいくつかあります:6 3 6 3(2の代わりに3を印刷)、4 3 2 1(1の代わりに2を印刷)。それらpopshift解決する代わりに使用して、新しいものを作成します(1 2 3 41ではなく3を出力します)
ダダ

1

C#6、297 209バイト

using System.Linq;int G(int[] a)=>a.Any()?a.SkipWhile((x,i)=>i<1||x>=a[i-1]).Count()<a.SkipWhile((x,i)=>i<1||x<=a[i-1]).Count()?G(a.Select(x=>-x).ToArray()):G(a.SkipWhile((x,i)=>i<1||x<=a[i-1]).ToArray())+1:0;

説明なしでゴルフ

int G(int[] a)=>
    a.Any()
        ?a.SkipWhile((x,i)=>i<1||x>=a[i-1]).Count()<a.SkipWhile((x,i)=>i<1||x<=a[i-1]).Count()   // If a begins by decreasing (including whole a decreasing)...
            ?G(a.Select(x=>-x).ToArray())   // ... Then flip sign to make a begins by increasing
            :G(a.SkipWhile((x,i)=>i<1||x<=a[i-1]).ToArray())+1   // ... Else skip the increasing part, recursively find the remaining part number, then add 1
        :0;   // Return 0 if a is empty

1

JavaScript(ES6)、69バイト

f=(d,c,b,...a)=>1/b?(d>c)*(b>c)+(d<c)*(b<c)?1+f(b,...a):f(d,b,...a):1

入力を複数のパラメーターとして受け取ります。最初の3つの要素を再帰的に比較して、それらが単調であるかどうかを確認します。そうであれば、中間の要素は役に立たないので削除します。


0

Clojure、97バイト

#((reduce(fn[[C i]s](let[S(conj C s)](if(or(apply <= S)(apply >= S))[S i][[s](inc i)])))[[]1]%)1)

reduce現在のサブシーケンスを追跡し、失敗する回数<=>=条件を計算します。最後1は、結果から2番目の要素を取ります(counterになりますi)。

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