Zählen Sie die Änderungen in einem Array


20

Ihre heutige Aufgabe ist es, ein Programm oder eine Funktion zu schreiben, die ein Array von ganzen Zahlen enthält und zählt, wie oft sich der Wert von links nach rechts ändert. Dies lässt sich leichter anhand eines Beispiels zeigen:[1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

Testfall:

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

Das ist , die wenigsten Bytes gewinnen!


Ist meine Antwort gültig, wenn das Ergebnis immer korrekt berechnet wird, aber wenn es 0 ist, Falsewird stattdessen gedruckt?
FlipTack

1
@FlipTack Das kommt auf die Sprache an. Im Allgemeinen, wenn ich sagen kann, 2+Falseund es Fehler, ist das nicht in Ordnung, aber wenn ich es bekomme 2, ist das in Ordnung.
Pavel

@FlipTack Dies ist standardmäßig der Konsens.
Totalhuman

Ist eine leere Ausgabe 0akzeptabel?
Titus

@Titus ja das ist es.
Pavel

Antworten:



9

Python 3 , 38 Bytes

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

Probieren Sie es online!


2
Huh, ich wusste, dass du so ein Standardargument verwenden könntest, nice find.
26.


@Dennis Wie verlässt die Funktion die rekursive Schleife, wenn das Array leer ist? Ich verstehe nicht, wie das nicht in einem endet maximum recursion depth exceeded.
Ioannes

@Ioannes Wenn nur noch ein Element ( x ) übrig ist, y>()wird es mit False ausgewertet , sodass der folgende Code andnicht ausgeführt wird.
Dennis

7

Haskell , 33 Bytes

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

Probieren Sie es online!


Bonus: Etwas merkwürdige punktfreie Rechenversion (44 Bytes)

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

Probieren Sie es online!

Ein Eingang gegeben [1,1,4,3,3,3], nehmen wir zuerst die Differenz benachbarter Einträge ( [0,3,-1,0,0]), dann der absquenten Wert: [0,3,1,0,0]. Wenn Sie beim ersten Mal die Potenz jedes Elements auf Null setzen, wird die [1,0,0,1,1]Liste beim zweiten Mal umgekehrt: [0,1,1,0,0]( (1-)würde auch hier funktionieren (0^)). Zum Schluss nehmen wir die sumvon der Liste, um sie zu bekommen 2.



5

Brain-Flak , 50 Bytes

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

Probieren Sie es online!

Gibt nichts für 0 aus, was in brain-flak äquivalent ist. Wenn dies nicht akzeptabel ist, hängen Sie dies für +4Bytes an:({})

Erläuterung:

#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 Schön gemacht! :)
DJMcMayhem


1
@ WheatWizard Ich habe das auch versucht, aber es wiederholt sich für immer bei leerer Eingabe. -0+1 = 1
H.PWiz

5

Brain-Flak , 50 Bytes

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

Probieren Sie es online!

# 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
Herzlichen Glückwunsch zu 10k rep!
Pavel

@Pavel Danke! Es hat ewig gedauert, bis ich die letzten paar hundert bekommen habe. Ich war zu beschäftigt mit anderen Sachen :(
Riley

Ich hatte diese
H.PWiz

@H.PWiz Ich hatte das einmal, aber ich mag, wie der Pop den Stapelhöhenschub aufhebt.
Riley

5

Haskell , 35 Bytes

-8 Bytes dank H.PWiz.

Ausgolfen durch eine rekursive Version . Haskell ist so ziemlich der Beste in Rekursion und ich habe es verpasst. > _ <

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

Probieren Sie es online!

Es wäre fantastisch, wenn jemand herausfinden würde, wie man diesen Tipp einsetzt .

Alternative Lösung, 36 Bytes

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

Probieren Sie es online!



In diesem Tipp fehlt die entscheidende Tatsache, dass Sie uncurrydie Funktion benötigen f, um sie zum Laufen zu bringen. Dies sum.map fromEnum.(zipWith(/=)=<<tail)ist wahrscheinlich die nächstgelegene, die Sie erhalten, aber es funktioniert nicht mit []und ist 37 Bytes ..
27.

5

Java (OpenJDK 8) , 65 Byte

Nicht so kurz wie ich möchte, aber das ist nur Java für Sie.

Testen Sie, indem Sie das Array als kommagetrennte Liste übergeben.

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

Probieren Sie es online!


2
Wenn das leere Array kein Testfall wäre (und ich finde es eigentlich nicht wirklich relevant), hätte man Folgendes verwenden können: a->{int s=0,p=a[0];for(int n:a)s+=p==(p=n)?0:1;return s;}(57 Byte).
Olivier Grégoire

@ OlivierGrégoire Ich weiß! Ich schrieb das auf und dachte, ich hätte es geschafft, die Bytes zu reduzieren, aber es schlug in diesem ersten Fall fehl.
Luke Stevens

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

4

Schale , 3 Bytes

Ltg

Probieren Sie es online!

Erläuterung

Ltg    Input: [1,1,1,2,2,3]
  g    Group equal elements together: [[1,1,1],[2,2],[3]]
 t     Drop the first group (if any): [[2,2],[3]]
L      Return the length of the list: 2


4

Wolfram Language (Mathematica) , 2324 26 29 Bytes

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

Probieren Sie es online!

  • -1 Byte Danke an Martin Ender!
  • -2 Bytes dank JungHwan Min! netter Gebrauch von Split[].
  • -3 Bytes dank totalhuman!

eine kleine Erklärung:

Splitteilt ein Array in eine Liste von Listen (gleicher Elemente), das heißt {1, 2, 2, 3, 1, 1}in {{1}, {2, 2}, {3}, {1, 1}}. So Length@Split@#ist die Anzahl der aufeinanderfolgenden Segmente. Max[*****-1, 0]wird verwendet, um mit {}Eingaben umzugehen .



1
24 Bytes:Max[Length@Split@#-1,0]&
JungHwan Min

23:Length@Split@#~Max~1-1&
Martin Ender


4

Symbolisches Python , 120 bis 117 Bytes

Golfed 3 Bytes durch Entfernen einer expliziten Umwandlung in eine Ganzzahl (unter Verwendung von unary +) für die Zählervariable. Dies bedeutet, dass die Ausgabe Falsestattdessen erfolgt , wenn keine Änderungen im Array vorgenommen wurden. 0Dies ist jedoch durch Meta zulässig .

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

Probieren Sie es online!

# 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
= _ = was ist das für eine Zauberei?
Totalhuman

3

Gelee , 3 Bytes

ITL

Probieren Sie es online!

Wie es funktioniert

ITL - Volles Programm.

I - Inkremente (Deltas).
 T - Liefert die Indizes der Wahrheitswerte (Liefert die Indizes von Nicht-0-Elementen).
  L - Länge.

3

K (oK) , 8 Bytes

Lösung:

+/1_~~':

Probieren Sie es online!

Beispiele:

+/1_~~':1 1 1 2 2 5 5 5 5 17 3
4
+/1_~~':()
0
+/1_~~':-3 3 3 -3 0
3

Erläuterung:

Interpretation von rechts nach links:

+/1_~~': / the solution
     ~': / equal each-previous
    ~    / not (ie differ)
  1_     / 1 drop, remove first as this is different to null
+/       / sum up trues



3

R , 24 Bytes

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

Probieren Sie es online!

Entspricht der MATL-Antwort, wird nur verwendet, sum(!!diff))da es kein gibt nnz.


+1 Ich dachte mit rlewäre kürzer, aber nein, length(rle()$v)verwendet zu viele Zeichen und ist um eins aus.
Neal Fultz

@ NealFultz es lohnt sich wohl noch als Antwort zu posten! Es ist immer gut, einen anderen Ansatz zu sehen. Und Sie sollten verwenden sum(rle()$v|1)statt lengthsowieso. :)
Giuseppe

3

Cubix , 24 Bytes

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

Probieren Sie es online aus

Beachten Sie, dass Cubix mit 0 angibt, dass keine weiteren Eingaben vorhanden sind, sodass 0 nicht in der Liste enthalten sein kann.

Erläuterung

Entfaltet:

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

Wir beginnen beim 0, indem wir den Zähler (initialisiert mit 0) und die erste Eingabe ( I) auf den Stapel legen.

Wir betreten dann die Schleife. Bei jeder Iteration der Schleife erhalten wir die nächste Eingabe mit I. Wenn es 0 ist, haben wir keine Eingaben mehr, also drehen wir den Zähler nach oben ( p), Output und exit ( @).

Ansonsten nehmen wir die Differenz der beiden obersten Elemente. Wenn es nicht Null ist, drehen wir den Zähler nach oben, inkrementieren ihn und drehen ihn mit nach unten zurück p)q. Wir machen dann den Unterschied mit, ;bevor wir zur nächsten Iteration übergehen.

Alle hier nicht erwähnten Zeichen sind nur Kontrollflüsse. In Cubix-Programmen gibt es in der Regel viele davon.


@MickyT Guter Ansatz, aber Sie scheinen um 1 zu viel zu zählen. Sie könnten die 0gegen eine tauschen (, aber das schlägt bei der leeren Eingabe fehl.

Entschuldigung, ich werde es mir noch einmal
ansehen

3

Brain-Flak , 50 Bytes

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

Probieren Sie es online!

Da jeder seine 50-Byte-Lösungen hier veröffentlicht, ist es meine (ich habe eine 48- Byte-Lösung, aber es war eine einfache Modifikation von DjMcMayhem, so dass ich es für sinnvoll hielt, sie zu veröffentlichen)

Erläuterung

In dieser Antwort wird häufig die Wertekompensation verwendet.

Ohne Golf sieht es aus

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

Hier berechnen wir die Deltas, bis der Stapel ein Element übrig hat, jedes Mal, wenn wir einen Wert aus der inneren Schleife akkumulieren, wenn das Delta nicht Null ist.

Dies ist ein ziemlich direkter Weg, dies zu tun.

Um diesen Golf zu spielen, beginnen wir mit der Wertaufhebung. Der erste und derjenige, der für gehärtete Brain-Flak-Golfer offensichtlich sein sollte, sind die Stapelhöhen. Es ist eine bekannte Tatsache, dass

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

ist das gleiche wie

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

Wenn die Werte um eins geändert werden, gilt dasselbe. Das gibt uns

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

Sie werden vielleicht bemerken, dass uns dies nicht einmal Bytes erspart hat, aber ärgern Sie sich nicht, dass es im weiteren Verlauf nützlicher wird.

Wir können eine weitere Reduktion durchführen, wenn Sie eine Aussage sehen

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

Sie können es tatsächlich reduzieren

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

Dies funktioniert, weil, wenn wir in die Schleife eintreten [(...)]und {}abbrechen, und wenn wir dies nicht tun, der Wert von [(...)]bereits an erster Stelle Null war und nicht abgebrochen werden muss. Da dieses Muster in unserem Code vorkommt, können wir es reduzieren.

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

Das hat uns 2 Bytes gespart, aber auch zwei Negative nebeneinander gelegt. Diese können kombiniert werden, um uns weitere 2 zu ersparen.

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

Und das ist unser Code.


3

Perl 6 , 18 Bytes

{sum $_ Z!= .skip}

Probier es aus

Erweitert:

{ # 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

Gaia , 2 Bytes

ėl

Probieren Sie es online!

Dies missbraucht einen Fehler (oder eine Funktion?) Von Gaia, bei dem die Lauflängencodierung den letzten Lauf von Elementen nicht berücksichtigt. Beachten Sie, dass ich doppelt geprüft habe, es funktioniert für alle Testfälle.

  • ė - Lauflängencodierung (mit dem oben beschriebenen Fehler).
  • l - Länge.

2

JavaScript (ES6), 35 Byte

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

Ich frage mich, ob es durch Rekursion verkürzt werden könnte. Aber mein bester Versuch ist auch 35:f=([a,...b])=>1/a?!!(a-b[0])+f(b):0
Arnauld

@Arnauld Ich habe das auch versucht, aber falsch gezählt und dachte, es wären 36 Bytes, sonst hätte ich es als Alternative hinzugefügt.
Neil


2

APL (Dyalog) , 8 Bytes

+/2≠/⊃,⊢

Probieren Sie es online!

Wie?

⊃,⊢ - die Liste, wobei der erste Wert für den Fall eines einzelnen Elements wiederholt wird

2≠/ - Änderungsliste, nicht für alle 2 Elemente gleich

+/ - Summe



2

J 10 Bytes

[:+/2~:/\]

Infixe der Länge 2 ... sind sie ungleich? 2 ~:/\ ]

Summiere die resultierende Liste von 0s und 1s:+/

Probieren Sie es online!


[:+/0=-/\ sollte funktionieren, ich denke 9 Bytes.
Cole

2

Ruby , 31 Bytes

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

Probieren Sie es online!


Anstelle von .drop(1)Ihnen können[1..-1]
Cyoce

@Cyoce gibt leider dropeinen Enumerator zurück, kein Array, so dass dies nicht funktioniert.
Jordanien

huh. Es gibt ein Array in meiner Version zurück.
Cyoce

@Cyoce Welche Version?
Jordanien

Ich bin auf 1.9.3, aber warum kannst du sizesowieso nicht die eines Arrays nehmen?
Cyoce

2

C (gcc 5.4.0), 61 Bytes

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

Probieren Sie es online!

f ist eine Funktion, die die Länge des Arrays und einen Zeiger auf das erste Element des Arrays nimmt und die Anzahl der Änderungen im Array zurückgibt;

Diese Übermittlung verwendet undefiniertes Verhalten ( *p++!=*p, p wird zweimal in einem Ausdruck verwendet, in dem es geändert wird), das auf meinem Computer (gcc 5.4.0) und in TIO funktioniert, jedoch möglicherweise nicht auf anderen Implementierungen oder Versionen funktioniert.

Erläuterung:

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
}

Könnten Sie vielleicht einen Link zu einer Online-Testumgebung hinzufügen?
Jonathan Frech

@JonathanFrech Hinzugefügt
pizzapants184

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.