Policz zmiany w tablicy

20

Twoim dzisiejszym zadaniem jest napisanie programu lub funkcji, która pobiera tablicę liczb całkowitych i liczy liczbę razy, odczytując od lewej do prawej, że wartość się zmienia. Łatwiej to pokazać na przykładzie:[1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

Przypadek testowy:

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

To jest , wygrywa najmniej bajtów!

Pavel
źródło
Czy moja odpowiedź jest prawidłowa, jeśli wynik jest zawsze poprawnie obliczony, ale jeśli jest równy 0, Falsezamiast tego jest drukowany?
FlipTack
1
@FlipTack To zależy od języka. Ogólnie rzecz biorąc, jeśli mogę powiedzieć 2+Falsei popełniam błędy, to nie jest w porządku, ale jeśli tak 2, to w porządku.
Pavel
@FlipTack Domyślnie ten jest konsensus.
całkowicie ludzki,
Czy puste wyjście jest 0akceptowalne?
Tytus
@Titus tak to jest.
Pavel

Odpowiedzi:

9

Python 3 , 38 bajtów

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

Wypróbuj online!

Dennis
źródło
2
Huh, wiedziałem, że możesz użyć takiego domyślnego argumentu, fajne znalezisko.
xnor
@Dennis W jaki sposób funkcja wychodzi z pętli rekurencyjnej, gdy tablica jest pusta? Nie rozumiem, jak to się nie kończy maximum recursion depth exceeded.
Ioannes
@Ioannes Gdy pozostanie tylko jeden element ( x ), y>()zmieni się na False , więc poniższy kod andnie zostanie wykonany.
Dennis
7

Haskell , 33 bajty

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

Wypróbuj online!


Bonus: nieco ciekawa bezcelowa wersja arytmetyczna (44 bajty)

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

Wypróbuj online!

Biorąc pod uwagę wejście [1,1,4,3,3,3], najpierw wziąć różnicę sąsiednich wpisów ( [0,3,-1,0,0]), wówczas abswartość olute: [0,3,1,0,0]. Biorąc zero do potęgi każdego elementu za pierwszym razem [1,0,0,1,1], a drugi raz odwraca listę: [0,1,1,0,0]( (1-)działałoby tutaj również zamiast (0^)). Wreszcie bierzemy sumlistę, aby uzyskać 2.

Laikoni
źródło
5

Brain-Flak , 50 bajtów

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

Wypróbuj online!

Nie wyprowadza nic dla 0, co w uderzeniu mózgu jest równoważne. Jeśli jest to nie do przyjęcia, dodaj to do +4bajtów:({})

Wyjaśnienie:

#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
<>
DJMcMayhem
źródło
@ Riley Ładnie zrobione! :)
DJMcMayhem
1
@WheatWizard Próbowałem też, ale zapętla się na zawsze przy pustych danych wejściowych. -0+1 = 1
H.PWiz
5

Brain-Flak , 50 bajtów

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

Wypróbuj 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
)
Riley
źródło
1
Gratulacje za 10k powtórzeń!
Pavel
@Pavel Thanks! Zdobycie ostatnich kilkuset zajęło mi wieczność. Byłem zbyt zajęty innymi rzeczami :(
Riley
Miałem to
H.PWiz
@ H.PWiz Miałem to w pewnym momencie, ale podoba mi się, jak pop anuluje wzrost wysokości stosu.
Riley,
5

Haskell , 35 bajtów

-8 bajtów dzięki H.PWiz.

Wyprzedzony przez rekurencyjną wersję . Haskell jest prawie najlepszy w rekurencji i mi tego brakowało. > _ <

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

Wypróbuj online!

Byłoby wspaniale, gdyby ktoś wymyślił, jak zastosować tę wskazówkę .

Alternatywne rozwiązanie, 36 bajtów

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

Wypróbuj online!

całkowicie ludzki
źródło
1
Również 35
H.PWiz
Ta wskazówka pomija kluczowy fakt, że aby uncurryfunkcja działała , potrzebujesz funkcji f. Jest sum.map fromEnum.(zipWith(/=)=<<tail)to prawdopodobnie najbliższe, ale nie będzie działać []i ma 37 bajtów ..
ბიმო
5

Java (OpenJDK 8) , 65 bajtów

Nie tak krótki, jak bym chciał, ale to po prostu Java dla Ciebie.

Testuj, przekazując tablicę jako listę rozdzielaną przecinkami.

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

Wypróbuj online!

Luke Stevens
źródło
2
Gdyby pusta tablica nie była przypadkiem testowym (a tak naprawdę nie uważam tego za istotne), można by użyć: a->{int s=0,p=a[0];for(int n:a)s+=p==(p=n)?0:1;return s;}(57 bajtów).
Olivier Grégoire
@ OlivierGrégoire Wiem! Napisałem to i pomyślałem, że udało mi się zmniejszyć bajty, ale to nie powiodło się w pierwszym przypadku.
Luke Stevens
3
56 bajtów:a->{int s=0;for(int i:a)s+=a[0]!=(a[0]=i)?1:0;return s;}
Nevay
4

Łuska , 3 bajty

Ltg

Wypróbuj online!

Wyjaśnienie

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
Lew
źródło
4

Ohm v2 , 3 bajty

ΔyΣ

Wypróbuj online!

Wyjaśnienie

Δ     absolute differences between consecutive elements
 y    sign: 1 if positive, -1 if negative, 0 if zero
  Σ   sum
Cinaski
źródło
Sprytne użycie signwbudowanego!
Nick Clifford
@NickClifford Thanks!
Cinaski
4

Wolfram Language (Mathematica) , 2324 26 29 bajty

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

Wypróbuj online!

  • -1 bajt dzięki Martin Ender!
  • -2 bajty dzięki JungHwan Min! niezłe wykorzystanie Split[].
  • -3 bajty dzięki totalnie ludzkiemu!

małe wyjaśnienie:

Splitpodzieli tablicę na listę list (tych samych elementów), czyli zamienia się {1, 2, 2, 3, 1, 1}w {{1}, {2, 2}, {3}, {1, 1}}. Tak więc Length@Split@#jest ilość kolejnych segmentów. Max[*****-1, 0]służy do radzenia sobie z {}danymi wejściowymi.

Keyu Gan
źródło
1
26 bajtów.
całkowicie ludzki,
1
24 bajty:Max[Length@Split@#-1,0]&
JungHwan Min
23:Length@Split@#~Max~1-1&
Martin Ender
4

Siatkówka , 24 21 16 bajtów

Dzięki @MartinEnder za -3 bajty i zauważenie błędu
-1 bajt dzięki @tsh
-4 bajty dzięki @Leo

m`^(\S+)¶(?!\1$)

Wypróbuj online!

ovs
źródło
4

Symboliczny Python , 120 117 bajtów

Zmieniono w golfa 3 bajty, usuwając jawny rzut na liczbę całkowitą (przy użyciu unary +) dla zmiennej licznika - oznacza to, że jeśli nie ma żadnych zmian w tablicy, wyjście będzie Falsezamiast 0, ale jest to dozwolone przez meta .

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

Wypróbuj 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.
_=___                                       
FlipTack
źródło
2
= _ = co to za magia?
całkowicie ludzki,
3

Galaretka , 3 bajty

ITL

Wypróbuj online!

Jak to działa

ITL - Pełny program.

I - Przyrosty (delty).
 T - Uzyskaj indeksy prawdziwych wartości (pobiera indeksy elementów innych niż 0).
  L - długość.
Pan Xcoder
źródło
3

K (oK) , 8 bajtów

Rozwiązanie:

+/1_~~':

Wypróbuj online!

Przykłady:

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

Wyjaśnienie:

Interpretowane od prawej do lewej:

+/1_~~': / the solution
     ~': / equal each-previous
    ~    / not (ie differ)
  1_     / 1 drop, remove first as this is different to null
+/       / sum up trues
Streetster
źródło
3

R , 24 bajty

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

Wypróbuj online!

Taki sam jak odpowiedź MATL, po prostu użyty, sum(!!diff))ponieważ nie ma nnz.

Giuseppe
źródło
+1 Myślałem, że użycie rlebędzie krótsze, ale nie, length(rle()$v)używa zbyt wielu znaków i jest wyłączone o jeden.
Neal Fultz
@NealFultz prawdopodobnie nadal warto opublikować jako odpowiedź! Zawsze dobrze jest widzieć inne podejście. I tak powinieneś użyć sum(rle()$v|1)zamiast tego length. :)
Giuseppe
3

Cubix , 24 bajty

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

Wypróbuj online

Zauważ, że Cubix używa 0, aby wskazać, że nie ma już żadnych danych wejściowych, więc 0 nie może być na liście.

Wyjaśnienie

Rozłożony:

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

Zaczynamy od 0, wypychając licznik (zainicjowany za pomocą 0) i pierwsze wejście ( I) na stos.

Następnie wchodzimy w pętlę. Przy każdej iteracji pętli otrzymujemy kolejne dane wejściowe za pomocą I. Jeśli wynosi 0, zabrakło nam danych wejściowych, więc obracamy licznik do góry ( p), Output i exit ( @).

W przeciwnym razie bierzemy różnicę z dwóch górnych elementów. Jeśli jest niezerowy, obracamy licznik do góry, zwiększamy go i obracamy z powrotem do dołu za pomocą p)q. Następnie zaznaczamy różnicę ;przed przejściem do następnej iteracji.

Wszystkie postacie niewymienione tutaj są tylko kontrolą. W programach Cubix jest ich wiele.


źródło
@MickyT Dobre podejście, ale wydaje się, że jesteś licytujący o 1. Możesz zamienić 0na (, ale to się nie powiedzie przy pustym wejściu.
przeprosiny,
popatrzę
3

Brain-Flak , 50 bajtów

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

Wypróbuj online!

Ponieważ wszyscy publikują swoje 50-bajtowe rozwiązania tutaj są moje (mam 48-bajtowe, ale była to prosta modyfikacja DjMcMayhem, więc czułem, że warto opublikować)

Wyjaśnienie

Ta odpowiedź w szerokim zakresie wykorzystuje anulowanie wartości.

Wygląda na to, że nie grał w golfa

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

Tutaj obliczamy deltę, aż na stosie pozostanie jeden element, za każdym razem, gdy gromadzimy jedną wartość z wewnętrznej pętli, jeśli delta nie jest równa zero.

Jest to dość prosty sposób na zrobienie tego.

Aby uczynić tego golfa, zaczynamy anulować wartość. Pierwszym i tym, który powinien być oczywisty dla każdego zahartowanego golfisty, jest wysokość stosu. Jest to dobrze znany fakt

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

jest taki sam jak

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

Gdy wartości są modyfikowane o jeden, to samo obowiązuje. To nam daje

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

Możesz zauważyć, że to nawet nie uratowało nam bajtów, ale nie przejmuj się, że stanie się to bardziej przydatne w miarę upływu czasu.

Możemy wykonać kolejną redukcję, jeśli zobaczysz oświadczenie

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

możesz to zredukować do

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

Działa to, ponieważ jeśli wejdziemy w pętlę [(...)]i {}anulujemy, a jeśli nie, wartość [(...)]już była zero na pierwszym miejscu i nie trzeba jej anulować. Ponieważ w kodzie mamy ten wzorzec, możemy go zmniejszyć.

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

To zaoszczędziło nam 2 bajty, ale także umieściło obok siebie dwa neg. Można je połączyć, aby uratować nam kolejne 2.

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

I to jest nasz kod.

Kreator pszenicy
źródło
3

Perl 6 , 18 bajtów

{sum $_ Z!= .skip}

Sprawdź to

Rozszerzony:

{ # 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 「$_」
}
Brad Gilbert b2gills
źródło
3

Gaia , 2 bajty

ėl

Wypróbuj online!

To nadużywa błędu (lub funkcji?) Gai, że kodowanie długości przebiegu nie bierze pod uwagę ostatniego ciągu elementów. Pamiętaj, że dwukrotnie sprawdziłem, działa dla wszystkich przypadków testowych.

  • ė - Kodowanie długości przebiegu (z wadą opisaną powyżej).
  • l - długość
Pan Xcoder
źródło
2

JavaScript (ES6), 35 bajtów

a=>a.filter((e,i)=>e-a[i+1]).length
Neil
źródło
Zastanawiam się, czy można to skrócić za pomocą rekurencji. Ale moja najlepsza próba to również 35:f=([a,...b])=>1/a?!!(a-b[0])+f(b):0
Arnauld
@Arnauld Też tego próbowałem, ale przeliczyłem się i pomyślałem, że to 36 bajtów, w przeciwnym razie dodałbym to jako alternatywę.
Neil
2

Pyth, 5 bajtów

l #.+

Zestaw testowy.

Wyjaśnienie:

   .+  Deltas
  #    Filter on identity (space)
l      Get length 
Steven H.
źródło
2

APL (Dyalog) , 8 bajtów

+/2≠/⊃,⊢

Wypróbuj online!

W jaki sposób?

⊃,⊢ - lista, z pierwszą wartością powtarzaną dla przypadku pojedynczego elementu

2≠/ - lista zmian, nie równa dla każdych 2 elementów

+/ - suma

Uriel
źródło
2

J, 10 bajtów

[:+/2~:/\]

Infiksy o długości 2 ... czy są nierówne? 2 ~:/\ ]

Zsumuj wynikową listę 0s i1 s:+/

Wypróbuj online!

Jonasz
źródło
[:+/0=-/\ powinien działać dla Myślę, że 9 bajtów.
cole
2

Ruby , 31 bajtów

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

Wypróbuj online!

Jordania
źródło
Zamiast tego .drop(1)możesz zrobić[1..-1]
Cyoce
@Cyoce Niestety dropzwraca Enumerator, a nie Array, więc to nie działa.
Jordan
hę Zwraca tablicę w mojej wersji.
Cyoce
@Cyoce Która wersja?
Jordan
Jestem na wersji 1.9.3, ale dlaczego mimo to nie możesz wziąć sizetablicy?
Cyoce
2

C (gcc 5.4.0), 61 bajtów

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

Wypróbuj online!

f jest funkcją przenoszącą długość tablicy i wskaźnik do pierwszego elementu tablicy i zwracającą liczbę zmian w tablicy;

To przesłanie wykorzystuje nieokreślone zachowanie (*p++!=*p , p jest używane dwukrotnie w wyrażeniu, w którym zostało zmienione), które działa na moim komputerze (gcc 5.4.0) i na TIO, ale może nie działać na innych implementacjach lub wersjach.

Wyjaśnienie:

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
}
pizzapanty184
źródło
Czy mógłbyś dodać link do środowiska testowego online?
Jonathan Frech
@JonathanFrech Dodano
pizzapants184
2

05AB1E , 3 bajty

γ¦g

Wypróbuj online!

Alternatywa dla odpowiedzi Erika.

γ¦g ~ Pełny program.

γ ~ Grupuj w serie równych sąsiadujących elementów.
 Remove ~ Usuń pierwszą grupę (jeśli istnieje).
  g ~ Długość.
Pan Xcoder
źródło
Ach, przegapiłem, że to był przypadek.
Magic Octopus Urn