配列の変更を数える


20

今日のタスクは、整数の配列を受け取り、値が変化する回数を左から右に読み取ってカウントするプログラムまたは関数を作成することです。これは例を使用して簡単に表示できます。[1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

テストケース:

Input           |   Output
[]              |   0
[0]             |   0
[0 1]           |   1
[0 0]           |   0
[1 2 3 17]      |   3
[1 1 1 2 2 3]   |   2
[-3 3 3 -3 0]   |   3

これは、最少バイトが勝ちます!


結果が常に正しく計算され、0の場合Falseは代わりに出力される場合、私の答えは有効ですか?
FlipTack

1
@FlipTackそれは言語に依存します。一般的に、言うことができ2+Falseてエラーが発生した場合、それは問題ありませんが、取得した場合は問題ありません2
パベル

@FlipTackデフォルトでは、これはコンセンサスです。
完全に人間の

空の出力は0受け入れ可能ですか?
タイタス

@Titusはい、そうです。
パベル

回答:



9

Python 3、38バイト

f=lambda x=0,*y:y>()and(x!=y[0])+f(*y)

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


2
ええと、あなたはそのようなデフォルトの引数を使用できることを知っていました、素敵な検索。
xnor


@Dennis配列が空の場合、関数はどのように再帰ループを終了しますか?これがどのように終わらないのかわかりませんmaximum recursion depth exceeded
イオアンズ

@Ioannes要素(x)が1つだけ残ったら、Falsey>()と評価されるため、次のコードは実行されません。and
デニス

7

Haskell、33バイト

f(a:b:r)=sum[1|a/=b]+f(b:r)
f _=0

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


ボーナス:やや奇妙なポイントフリー算術バージョン(44バイト)

sum.(tail>>=zipWith((((0^).(0^).abs).).(-)))

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

入力が与えられると、[1,1,4,3,3,3]まず隣接するエントリの差([0,3,-1,0,0])をabs取得し、次にolute値を取得します[0,3,1,0,0]。最初にゼロを各要素の累乗にする[1,0,0,1,1]と、が得られ、2回目はリストが反転します[0,1,1,0,0](1-)ここでもの代わりに機能します(0^))。最後sumに、リストを取得して取得し2ます。



5

Brain-Flak、50バイト

([][()]){{}({}[({})]){{}<>({}())(<>)}{}([][()])}<>

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

0については何も出力しません。これはbrain-flakでは同等です。これが受け入れられない場合、これを+4バイトに追加するよりも:({})

説明:

#Push stack-height-1
([][()])

#While true:
{

    #Pop the stack-height-1 off
    {}

    #If 'a' is the element on top of the stack, and 'b' is the element underneath it, then
    #Pop 'a' off, and push (a - b)
    ({}[({})])

    #If (a-b) is not 0...
    {
        #Pop (a-b) off
        {}

        #Switch stacks
        <>

        #Increment the value on the other stack
        ({}())

        #Push a 0 back to the main stack
        (<>)

    #Endif
    }

    #Pop either (a-b) or the 0 we pushed
    {}

    #Push stack-height-1
    ([][()])

#Endwhile
}

#Toggle to the alternate stack and display the counter
<>


@Rileyよくできました!:)
DJMcMayhem


1
@WheatWizard私もそれを試しましたが、空の入力で永遠にループします。-0+1 = 1
H.PWiz

5

Brain-Flak、50バイト

(([][()]){[{}]<({}[({})])>{(<{}>)()}{}([][()])}<>)

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

# Get ready to push the answer
(

# Push stack height - 1
([][()])

# Loop until 0 (until the stack has a height of 1)
{

  # Pop the old stack height and subtract it 
  #(cancels the loop counter from the final answer)
  [{}]

  # Pop the top of the stack and subtract the next element from that
  # Don't include this in the final answer
  <({}[({})])>

  # If not 0
  {

    # Pop the difference between the last two numbers
    # Don't include this in the final answer
    (<{}>)

    # Add 1 to the final answer
    ()

  # End if
  }{}

  # Push stack height - 1
  ([][()])

# End while
}

# Switch to the off stack so we don't print anything extra
<>

# Push the total sum. This is the number of times the if was true
)

1
おめでとうございます!
パベル

@Pavelありがとう!最後の数百個を取得するのに永遠にかかりました。私は他のもので忙しすぎました:(
ライリー


@ H.PWiz私はある時点でそれを持っていましたが、ポップがスタックの高さのプッシュをキャンセルする方法が好きです。
ライリー

5

Haskell、35バイト

H.PWizのおかげで-8バイト。

再帰的なバージョンでアウトゴルフ。Haskellは再帰が最も優れており、私はそれを逃しました。> _ <

f l=sum[1|x<-zipWith(/=)l$tail l,x]

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

誰かがこのヒントをどのように使うかを考え出せば素晴らしいでしょう。

代替ソリューション、36バイト

f l=sum[1|True<-zipWith(/=)l$tail l]

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



このヒントでは、uncurry関数fを機能させるために必要な重要な事実を見逃しています。これsum.map fromEnum.(zipWith(/=)=<<tail)はおそらく最も近いものですが、動作しません[]。37バイトです。
ბიმო17年

5

Java(OpenJDK 8)、65バイト

私が望むほど短くはありませんが、それはあなたにとってJavaに過ぎません。

配列をコンマ区切りリストとして渡すことでテストします。

a->{int s=0,i=1;for(;i<a.length;s+=a[i-1]!=a[i++]?1:0);return s;}

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


2
空の配列がテストケースではなかった場合(実際には、実際に関連性があるとは思えません)、使用できた可能性があります:a->{int s=0,p=a[0];for(int n:a)s+=p==(p=n)?0:1;return s;}(57バイト)。
オリビエグレゴワール

@OlivierGrégoire知ってるよ!私はそれを書き留めて、バイト数を削減することができたと思ったが、最初のケースでは失敗した。
ルークスティーブンス

3
56バイト:a->{int s=0;for(int i:a)s+=a[0]!=(a[0]=i)?1:0;return s;}
Nevay



4

Wolfram言語(Mathematica)、2324 26 29 バイト

Length@Split@#~Max~1-1&

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

  • マーティン・エンダーのおかげで-1バイト!
  • -JungHwan Minのおかげで2バイト!のいい使い方Split[]
  • 完全に人間のおかげで-3バイト!

少し説明:

Splitは、配列を(同じ要素の)リストのリストに分割{1, 2, 2, 3, 1, 1}{{1}, {2, 2}, {3}, {1, 1}}ます。つまり、になります。だから、Length@Split@#連続したsegementsの量です。入力Max[*****-1, 0]を処理するために使用され{}ます。



1
24バイト:Max[Length@Split@#-1,0]&
ジョンファンミン

23:Length@Split@#~Max~1-1&
マーティン・エンダー


4

シンボリックPython120 117バイト

+カウンター変数の整数への明示的なキャスト(単項を使用)を削除して3バイトをゴルフします。これは、配列に変更がない場合、出力がFalse代わりになることを意味しますが0、これはmeta許可されます。

___=-~(_==_)
__('___=~-'+`_>_`[___::___]+`__`[-~___]+'(_)')
__('__=___=_>_'+';___+=_[__]!=_[-~__];__=-~__'*___)
_=___

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

# LINE 1: Generate value '2' for utility
___=-~(_==_)

# LINE 2: Get len(input) - 1
__('___=~-'+`_>_`[___::___]+`__`[-~___]+'(_)')
   '___=~-'+`_>_`[___::___]+`__`[-~___]+'(_)'     # Generate string '___=~-len(_)'
            `_>_`[___::___]                       #    'le' spliced from 'False'
                           +`__`[-~___]           #    'n' indexed from '<function ...>'
   '___=~-'+                           +'(_)'     #    Remaining characters in plaintext
__(                                          )    # Execute this to get len(input) - 1

# LINE 3: Main calculation loop
__('__=___=_>_'+';___+=_[__]!=_[-~__];__=-~__'*___) 
__(                                               ) # Execute:
   '__=___=_>_'                                     #   Set var1, var2 to 0
               +';                           '*___  #   len(input) - 1 times do:
                       _[__]!=_[-~__]               #   Compare input[var1, var1 + 1]
                  ___+=              ;              #   Add this to var2
                                      __=-~__       #   Increment var1

# LINE 4: Set output variable ('_') to the result calculated.
_=___                                       

2
= _ =この魔法は何ですか?
完全に人間の





3

R、24バイト

cat(sum(!!diff(scan())))

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

MATLの答えと同じ、ちょうど使用していないsum(!!diff))何がありますので、nnz


+1使用rleすると短くなると思いましたが、いや、length(rle()$v)使用する文字が多すぎて1つずれています。
ニールフルツ

@NealFultzそれはおそらく答えとして投稿する価値があるでしょう!別のアプローチを見るのは常に良いことです。とにかくsum(rle()$v|1)代わりに使用する必要がありlengthます。:)
ジュゼッペ

3

Cubix、24バイト

UpO@0I>I!^-u>q.uvv$!^;)p

オンラインで試す

Cubixは0を使用して入力がもうないことを示すため、0をリストに含めることはできません。

説明

展開:

    U p
    O @
0 I > I ! ^ - u
> q . u v v $ !
    ^ ;
    ) p

で開始し、0カウンター(で初期化された0)と最初の入力(I)をスタックにプッシュします。

次に、ループに入ります。ループの各反復で、次の入力を取得しIます。0の場合、入力が不足しているので、カウンターを上に回転させ(p)、Output、exit(@)します。

それ以外の場合は、上位2つの要素の差を取ります。ゼロ以外の場合、カウンタを上に回転させ、増分し、で下に回転させp)qます。次に;、次の反復に移る前に、差をポップします。

ここで言及されていないすべてのキャラクターは、単なる制御フローです。Cubixプログラムには多くの人がいる傾向があります。


@MickyT良いアプローチが、あなたはあなたが交換可能性1で過大計測しているように見える0ために(、それは空の入力に失敗しました。

謝罪、もう一度見ます
MickyT

3

Brain-Flak、50バイト

(([][()]){[{}({}[({})])]{{}()(<()>)}{}([][()])}<>)

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

誰もがここに50バイトのソリューションを投稿しているので私のものです(48バイトのものがありますが、それはDjMcMayhemの簡単な修正でしたので、投稿する価値があると感じました)

説明

この回答では、値のキャンセルを広く使用しています。

ゴルフされていないように見える

([][()])({<{}({}[({})])>{<{}>()(<()>)}{}<([][()])>}<>)

ここでは、スタックに1つの項目が残るまで、デルタが計算されます。デルタがゼロでない場合、内側のループから1つの値を蓄積するたびに。

これは非常に簡単な方法です。

これをゴルフっぽくするために、値のキャンセルを開始します。最初の1つであり、どんな脳みそのゴルファーにとっても明らかなはずの1つは、スタックの高さです。それはよく知られている事実です

([])({<{}>...<([])>}{})

と同じです

(([]){[{}]...([])}{})

値が1つ変更されると、同じことが成り立ちます。これは私たちに与えます

(([][()]){[{}]<({}[({})])>{<{}>()(<()>)}{}([][()])}<>)

これでバイトを節約できなかったことにお気づきかもしれませんが、先に進むにつれて便利になると心配しないでください。

ステートメントが表示された場合、別の削減を実行できます

<(...)>{<{}> ...

あなたは実際にそれを減らすことができます

[(...)]{{} ...

この作品、私たちはループを入力すると、理由[(...)]{}キャンセルされます、そして、私たちがいない場合の値[(...)]既にが最初の場所でゼロだったし、キャンセルする必要はありません。コード内でこのパターンが発生しているため、これを減らすことができます。

(([][()]){[{}][({}[({})])]{{}()(<()>)}{}([][()])}<>)

これにより2バイト節約できましたが、2つのネガも隣り合わせに配置されました。これらを組み合わせて、さらに2を節約できます。

(([][()]){[{}({}[({})])]{{}()(<()>)}{}([][()])}<>)

それが私たちのコードです。


3

Perl 6、18バイト

{sum $_ Z!= .skip}

試して

拡張:

{ # bare block lambda with implicit parameter 「$_」

  sum         # count the number of True values

      $_      # the input
    Z!=       # zip using &infix:«!=»
      .skip   # the input, but starting from the second value
              # (implicit method call on 「$_」
}

3

ガイア、2バイト

ėl

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

これは、Gaiaのバグ(または機能?)を悪用します。つまり、run-length-encodingは要素の最後の実行を考慮していません。私はダブルチェックしたことに注意してください、それはすべてのテストケースで動作します。

  • ė -長さエンコードを実行します(上記の問題を含む)。
  • l -長さ。

2

JavaScript(ES6)、35バイト

a=>a.filter((e,i)=>e-a[i+1]).length

再帰を使用することで短縮できるのだろうか。しかし、私の最善の試みも35ですf=([a,...b])=>1/a?!!(a-b[0])+f(b):0
。-アーナルド

@Arnauld私もそれを試してみましたが、誤って数えて36バイトだと思いました。
ニール





2

Ruby、31バイト

->a{a.chunk{|x|x}.drop(1).size}

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


代わりに.drop(1)できること[1..-1]
チョイス

@Cyoceは残念ながらdrop、配列ではなく列挙子を返すため、機能しません。
ヨルダン

ハァッ 私のバージョンでは配列を返します。
チョイス

@Cyoceどのバージョン?
ヨルダン

私は1.9.3を使用していますが、なぜsize配列を使用できないのですか?
チョイス

2

C(gcc 5.4.0)、61バイト

f(c,v)int*v;{int*p=v,s=0;for(;p<v+c-1;s+=*p++!=*p);return s;}

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

f 配列の長さと配列の最初の要素へのポインタを取得し、配列の変更数を返す関数です。

この送信では、未定義の動作(*p++!=*p、pが変更される式で2回使用されます)を使用します。これは私のマシン(gcc 5.4.0)およびTIOで動作しますが、他の実装またはバージョンでは動作しない場合があります。

説明:

f(c,v)int*v;{ // old-style declaration for v, and implicit-int for c and return value
    int*p=v,s=0; // p is a pointer to the current item, s is the number of changes
    for(;p<v+c-1;s+=*p++!=*p); // for each consecutive pair of integers, if they are different, add one to the number of changes
    return s; // return the number of changes
}

オンラインテスト環境へのリンクを追加してもらえますか?
ジョナサンフレッチ

@JonathanFrech追加
pizzapants184

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