0-1最大位相カウンター


21

たとえば、ビットの配列を考えます

1 1 1 0 0 0 0 1 0 0 1 0 1 1 1 1 1 0 1 0

ビットの少なくとも85%が同じであり、最初のビットと最後のビットの両方がマジョリティビットに等しい場合、長さが5以上の連続するサブアレイをフェーズと呼びます。さらに、他のフェーズの厳密なサブアレイでない場合、フェーズを最大と呼びます。

上記の例の最大フェーズは次のとおりです。

1 1 1 0 0 0 0 1 0 0 1 0 1 1 1 1 1 0 1 0
      -------------
                    -------------
                        -------------

ご覧のとおり、3最大のフェーズがあります。一方、これ

1 1 1 0 0 0 0 1 0 0 1 0 1 1 1 1 1 0 1 0
                        ---------

少なくとも1つの他のフェーズの厳密なサブアレイであるため、最大フェーズではありません。

チャレンジ

入力は、STDIN、コマンドライン、または関数引数を介した5ビット以上のシーケンスです。ビットは、文字列または配列として入ることがあります。

STDOUTを介して出力されるか、関数から返される、配列の最大位相数である単一の整数を出力します。

得点

これはコードゴルフなので、最小バイトのプログラムが勝ちます。

テストケース

0 1 0 1 0 -> 0
0 0 0 0 0 -> 1
0 0 0 0 1 0 1 1 1 1 -> 0
0 0 0 0 0 1 0 1 1 1 1 1 -> 2
1 0 0 0 0 0 0 0 0 0 0 0 0 1 0 -> 1
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 -> 2
0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 -> 1
0 1 0 1 0 0 1 0 1 0 1 0 0 0 1 1 1 1 0 1 0 0 1 1 0 0 0 1 1 0 -> 0
1 1 1 1 1 0 0 0 0 0 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 1 1 0 1 -> 4
0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 1 0 0 0 0 0 -> 5

最後のケースの説明は次のとおりです。

0 1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 1 1 1 1 1 1 1 0 1 0 0 0 0 0
---------------------------
      -------------------------
                            -----------------
                                -----------------
                                              -------------

楽しい事実:この課題は、一時的なデータの変化を検出することを目的としたデータマイニングの問題から生じました。


いつサブアレイが連続するかについての質問。長さ≥5少なくとも85%のビットが同じ場合は位相5の1 1 0 1 185%が4.25であるような長さ5があるとしましょう。
テウンプロンク

@TeunPronkすべてのビットが同じでない限り、長さ5は不可能であることを意味します
-Sp3000

私はコメントを編集してそれを追加しようとしていたので、切り捨てはありません:)
Teun Pronk

それで、あなたはできるだけ多くのサブアレイを見つけるか、可能な限り大きなアレイを見つけるつもりですか?テストケース5で1つ以上を見つけるため(コードではなく、見ることで)
Teun Pronk

@TeunPronkは、より大きなものに完全には含まれていないものをできるだけ多く見つけることです。5番目のテストケースでは、最初の配列から0最後の配列で終わる、そのような配列が1つだけあります。
マーティンエンダー

回答:



8

Python 2、149バイト

a=input()
l=len(a)
n=p=0
for i in range(l):
 for j in range(l-1,i+3,-1):
  if(j>p)>(.15<sum(a[i:j+1])/(j+1.-i)+a[i]+a[j]<2.85):n+=1;p=j;break
print n

最初のループは、配列を左から右にスキャンします。によってインデックス付けされた各ビットiは、最大フェーズの最初のビットである可能性があるかどうかを確認するためにチェックされます。

これは、右から左にスキャンする内側のループによって行われます。間のサブアレイの場合iとはj相である、我々はカウンターを増加し、上に移動します。それ以外の場合、サブアレイが小さくなりすぎる j、前の最大フェーズの終わりに達するまで続けます。

1 1 1 0 0 0 0 1 0 0 1 0 1 1 1 1 1 0 1 0
i ->                               <- j

例:

$ python phase.py
[1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0]
3

5

Python 2、144

フォームに入力を入力し[0,1,0,1,0]ます。

a=input()
o=[2];i=-1
while a[i:]:
 j=len(a);i+=1
 while j>i+4:o+=sum(j>max(o)>x==a[i]==a[j-1]for x in a[i:j])*20/(j-i)/17*[j];j-=1
print~-len(o)

サブシーケンスは、初期要素を増やしてから長さを減らすことにより、順序付けでチェックされます。このように、新しいサブシーケンスは、その最後の要素のインデックスが以前に見つかったシーケンスの最後の要素のインデックスよりも大きい場合、前のサブシーケンスのサブシーケンスではないことがわかります。


4

Dyalog APL、86バイト*

{+/∨/¨∪↓∨⍀∨\{⊃({(.5>|k-⍵)∧.35≤|.5-⍵}(+/÷⍴)⍵)∧(5≤⍴⍵)∧(⊃⌽⍵)=k←⊃⍵}¨⌽∘.{(⍺-1)↓⍵↑t}⍨⍳⍴t←⍵}

ここで試してみてください。使用法:

   f ← {+/∨/¨∪↓∨⍀∨\{⊃({(.5>|k-⍵)∧.35≤|.5-⍵}(+/÷⍴)⍵)∧(5≤⍴⍵)∧(⊃⌽⍵)=k←⊃⍵}¨⌽∘.{(⍺-1)↓⍵↑t}⍨⍳⍴t←⍵}
   f 0 0 0 0 0 1 0 1 1 1 1 1
2

これはおそらく、特に位相条件がチェックされる中間部分でかなりゴルフをすることができます。

説明

まず、入力ベクトルの部分文字列を行列に収集し⌽∘.{(⍺-1)↓⍵↑t}⍨⍳⍴t←⍵ます。ここで、左上隅には入力全体が含まれます。入力の0 0 0 0 0 1 0場合、この行列は

┌───────────────┬─────────────┬───────────┬─────────┬───────┬─────┬───┬─┐
│1 0 0 0 0 0 1 0│1 0 0 0 0 0 1│1 0 0 0 0 0│1 0 0 0 0│1 0 0 0│1 0 0│1 0│1│
├───────────────┼─────────────┼───────────┼─────────┼───────┼─────┼───┼─┤
│0 0 0 0 0 1 0  │0 0 0 0 0 1  │0 0 0 0 0  │0 0 0 0  │0 0 0  │0 0  │0  │ │
├───────────────┼─────────────┼───────────┼─────────┼───────┼─────┼───┼─┤
│0 0 0 0 1 0    │0 0 0 0 1    │0 0 0 0    │0 0 0    │0 0    │0    │   │ │
├───────────────┼─────────────┼───────────┼─────────┼───────┼─────┼───┼─┤
│0 0 0 1 0      │0 0 0 1      │0 0 0      │0 0      │0      │     │   │ │
├───────────────┼─────────────┼───────────┼─────────┼───────┼─────┼───┼─┤
│0 0 1 0        │0 0 1        │0 0        │0        │       │     │   │ │
├───────────────┼─────────────┼───────────┼─────────┼───────┼─────┼───┼─┤
│0 1 0          │0 1          │0          │         │       │     │   │ │
├───────────────┼─────────────┼───────────┼─────────┼───────┼─────┼───┼─┤
│1 0            │1            │           │         │       │     │   │ │
├───────────────┼─────────────┼───────────┼─────────┼───────┼─────┼───┼─┤
│0              │             │           │         │       │     │   │ │
└───────────────┴─────────────┴───────────┴─────────┴───────┴─────┴───┴─┘

次に、その上に位相があるという条件をマッピングし、0-1-マトリックスを作成します

0 0 0 0 0 0 0 0
1 0 1 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0

最大フェーズの数を取得するには、を1使用してを右にフラッディングし∨⍀∨\

0 0 0 0 0 0 0 0
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1

一意の行を収集し∪↓

┌───────────────┬───────────────┐
│0 0 0 0 0 0 0 0│1 1 1 1 1 1 1 1│
└───────────────┴───────────────┘

を使用して、少なくとも1つ1を含むものをカウントします+/∨/¨

* APLには標準の1バイトエンコーディングがあります。


まあ、私が尋ねていることを説明するのは難しいです。コードのより良い説明があれば、言い換えることができます。今はコメントを削除します。
オプティマイザー

@Optimizer説明を拡張しました。
ズガルブ

1

Clojure、302

(defn p[v l](if(or(<(count v)5)(= 0 l))nil(if((fn[v](let[f(first v)c(apply + v)o(count v)r(/ c o)t(+ f f r)](and(= f(last v))(or(> t 2.85)(< t 0.15)))))v)0(let[r(p(vec(drop-last v))(dec l))](if r(+ r 1)r)))))(defn s[v l c](if(empty? v)c(let[n(p v l)](if n(s(vec(rest v))n(inc c))(s(vec(rest v))l c)))))

わずかに手放したバージョン

(defn is-phase [vector]
  (let [f (first vector)
        c (apply + vector)
        o (count vector)
        r (/ c o)
        t (+ f f r)]
    (and (= f (last vector))
         (or (> t 2.85) (< t 0.15)))))
(defn phase-index [vector last]
  (if (or (<(count vector)5)(= 0 last)) nil
    (if (is-phase vector) 0
      (let [r (phase-index (vec(drop-last vector)) (dec last))]
        (if r (+ r 1) r)))))
(defn phase-count [vector last count]
  (if (empty? vector) count
    (let [n (phase-index vector last)]
         (if n (phase-count (vec(rest vector)) n (inc count))
             (phase-count (vec(rest vector)) last count)))))

このように呼び出し可能:(s [0 1 0 1 0] 10 0)。いくつかの追加の引数が必要ですが、余分な20文字の引数を取り除くことができます。


0

JavaScript(ES6)141

JavaScript
入力に移植される@grcのアルゴリズムは、文字列または配列にすることができます

F=b=>
  (l=>{
    for(c=e=i=0;i<l;++i)
      for(j=l;j>i+4&j>e;--j)
        (k=0,[for(d of b.slice(i,j))k+=d==b[i]],k<(j-i)*.85)|b[i]-b[j-1]||(++c,e=j)
  })(b.length)|c

FireFox / FireBugコンソールでテストする

;['01010', '00000', '0000101111',
'000001011111', '100000000000010',
'0000010000010000010', '00000100000100000100',
'010100101010001111010011000110',
'111110000011111001000000001101',
'011000000000001011111110100000'].forEach(t => console.log(t,F(t)))

出力

01010 0
00000 1
0000101111 0
000001011111 2
100000000000010 1
0000010000010000010 2
00000100000100000100 1
010100101010001111010011000110 0
111110000011111001000000001101 4
011000000000001011111110100000 5


0

JavaScript(ECMAScript 6)、148 139バイト

f=(s,l=0,e=0,p=0)=>{for(n=s.length,o=[j=0,y=0],i=l;i<n;++j>4&x==s[l]&i>e&c>=.85‌​*j&&(e=i,y=1))c=++o[x=s[i++]];return l-n?f(s,l+1,e,p+y):p}

配列を再帰的に処理し、最後の再帰インデックスで反復を開始します。引数は配列または文字列のいずれかです。

f('011000000000001011111110100000'); //5

1
ゴルフのコツ:-11。f=(s,l=0,e=0,p=0)=>{for(n=s.length,o=[j=0,y=0],i=l;i<n;++j>4&x==s[l]&i>e&c>=.85*j&&(e=i,y=1))c=++o[x=s[i++]];return l-n?f(s,l+1,e,p+y):p}
-edc65

0

ウルフラム-131

{x_, X___}⊕{Y__, x_, y___}/;MemberQ[t={x, X, Y, x}, 1-x] && t~Count~x > .85 Length@t := 
  1 + {X, Y, x}⊕{y} 
{_, X___}⊕y_ := {X}⊕y
{}⊕{y_, Y__} := {y}⊕{Y}
_⊕_ := 0

{}⊕{1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0}
> 3
{}⊕{0,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,0,1,0,0,0,0,0}
> 5

0

Java:771バイト

import java.util.*;public class A{static int[]a;static class b{int c,d,e,f,g,h;b(int i,int j){this.c=i;this.d=j;this.h=j-i+1;this.e=k();this.f=this.h-this.e;this.g=e>f?1:0;}
boolean l(b n){return this.c>=n.c&&this.d<=n.d;}
int k(){int o=0;for(int i=c;i<=d;i++){if(a[i]==1){o++;}}
return o;}
public boolean equals(Object o){b x=(b)o;return x.c==this.c&&x.d==this.d;}
float p(){if(g==0){return(float)f/h;}else{return(float)e/h;}}
boolean q(){float r=p();return a[c]==a[d]&&a[d]==g&&r>=0.85F;}}
static int s(int[]t){a=t;List<b>u=new ArrayList<>();for(int v=0;v<t.length-4;v++){int x=v+4;while(x<t.length){b y=new b(v,x);if(y.q()){u.add(y);}
x++;}}
List<b>a=new ArrayList<>();for(b c:u){for(b d:u){if(!c.equals(d)&&c.l(d)){a.add(c);break;}}}
u.removeAll(a);return u.size();}}

メソッドs(int [] input)を呼び出して実行する

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