Contare le modifiche in un array


20

Il tuo compito oggi è quello di scrivere un programma o una funzione che accetta un array di numeri interi e conta il numero di volte, leggendolo da sinistra a destra, che il valore cambia. Questo è più facile da mostrare con un esempio:[1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

Caso di prova:

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

Questo è , vince meno byte!


La mia risposta è valida se il risultato è sempre calcolato correttamente, ma se è 0 Falseviene invece stampato?
FlipTack,

1
@FlipTack Dipende dalla lingua. In generale, se posso dire 2+Falseed errori, non va bene, ma se ottengo 2, va bene.
Pavel,

@FlipTack Per impostazione predefinita, questo è il consenso.
totalmente umano il

L'output vuoto è 0accettabile?
Tito

@Titus sì, lo è.
Pavel,

Risposte:



9

Python 3 , 38 byte

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

Provalo online!


2
Eh, sapevo che avresti potuto usare un argomento predefinito come quello, bella scoperta.
xnor


@Dennis In che modo la funzione esce dal ciclo ricorsivo quando l'array è vuoto? Non vedo come questo non finisca in a maximum recursion depth exceeded.
Ioannes,

@Ioannes Una volta che è rimasto solo un elemento ( x ), y>()verrà valutato Falso , quindi il codice seguente andnon verrà eseguito.
Dennis,

7

Haskell , 33 byte

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

Provalo online!


Bonus: versione aritmetica un po 'curiosa senza punti (44 byte)

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

Provalo online!

Dato un input [1,1,4,3,3,3], abbiamo prima dare la differenza di voci adiacenti ( [0,3,-1,0,0]), allora il absvalore olute: [0,3,1,0,0]. Portando zero alla potenza di ogni elemento la prima volta produce [1,0,0,1,1], e una seconda volta inverte la lista: [0,1,1,0,0]( (1-)funzionerebbe anche qui invece di (0^)). Infine prendiamo sumla lista per ottenere 2.



5

Brain-Flak , 50 byte

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

Provalo online!

Non restituisce nulla per 0, che in scaglie di cervello è equivalente. Se ciò non è accettabile, aggiungere questo per+4 byte:({})

Spiegazione:

#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 Ben fatto! :)
DJMcMayhem


1
@WheatWizard L'ho provato anche io, ma scorre all'infinito su input vuoti. -0+1 = 1
H.Piz,

5

Brain-Flak , 50 byte

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

Provalo 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
Complimenti per 10k rep!
Pavel,

@ Grazie Grazie! Mi ci è voluto un'eternità per ottenere le ultime centinaia. Sono stato troppo impegnato con altre cose :(
Riley il

Ho avuto questo
H.Piz il

@ H.PWiz L'ho avuto ad un certo punto, ma mi piace come il pop annulla la spinta dell'altezza dello stack.
Riley,

5

Haskell , 35 byte

-8 byte grazie a H.PWiz.

Fuori campo da una versione ricorsiva . Haskell è praticamente il migliore alla ricorsione e l'ho perso. > _ <

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

Provalo online!

Sarebbe fantastico se qualcuno capisse come utilizzare questo suggerimento .

Soluzione alternativa, 36 byte

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

Provalo online!



Quel suggerimento manca il fatto cruciale che avresti bisogno uncurrydella funzione fper farlo funzionare. Questo sum.map fromEnum.(zipWith(/=)=<<tail)è probabilmente il più vicino che ottieni, ma non funzionerà con []37 byte ..
ბიმო

5

Java (OpenJDK 8) , 65 byte

Non corto come vorrei, ma è solo Java per te.

Test passando la matrice come elenco delimitato da virgole.

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

Provalo online!


2
Se l'array vuoto non fosse un caso di test (e in realtà non lo trovo davvero rilevante), si sarebbe potuto usare: 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 Lo so! L'ho scritto e ho pensato di essere riuscito a ridurre i byte, ma non è riuscito in quel primo caso.
Luke Stevens,

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

4

Buccia , 3 byte

Ltg

Provalo online!

Spiegazione

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 byte

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

Provalo online!

  • -1 byte grazie a Martin Ender!
  • -2 byte grazie a JungHwan Min! buon uso di Split[].
  • -3 byte grazie a totalmente umano!

una piccola spiegazione:

Splitdividerà un array in un elenco di liste (degli stessi elementi), ovvero trasformandole {1, 2, 2, 3, 1, 1}in {{1}, {2, 2}, {3}, {1, 1}}. Quindi, Length@Split@#è la quantità di segmenti consecutivi. Max[*****-1, 0]è usato per gestire l' {}input.



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

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

4

Retina , 24 21 16 byte

Grazie a @MartinEnder per -3 byte e notando un bug
-1 byte grazie a @tsh
-4 byte grazie a @Leo

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

Provalo online!


4

Python simbolico , 120 117 byte

Golfato 3 byte rimuovendo un cast esplicito su intero (usando unario +) per la variabile contatore - questo significa che se non ci sono cambiamenti nell'array, l'output sarà Falseinvece di 0, ma questo è consentito da meta .

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

Provalo 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
=_= what is this wizardry?
totallyhuman

3

Jelly, 3 bytes

ITL

Try it online!

How it works

ITL  - Full program.

I    - Increments (deltas).
 T   - Get the indices of truthy values (gets the indexes of non-0 elements).
  L  - Length.

3

K (oK), 8 bytes

Solution:

+/1_~~':

Try it online!

Examples:

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

Explanation:

Interpreted right-to-left:

+/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())))

Try it online!

Same as the MATL answer, just used sum(!!diff)) since there's no nnz.


+1 I thought using rle would be shorter, but nope, length(rle()$v) uses too many characters and is off by one.
Neal Fultz

@NealFultz it's probably still worth posting as an answer! Always good to see another approach. And you should use sum(rle()$v|1) instead of length anyway. :)
Giuseppe

3

Cubix, 24 bytes

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

Try it online

Note that Cubix uses 0 to indicate that there are no more inputs, so 0 cannot be in the list.

Explanation

Unfolded:

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

We start at the 0, pushing the counter (initialized with 0) and the first input (I) onto the stack.

We then enter the loop. At each iteration of the loop, we get the next input with I. If it's 0, we've run out of inputs, so we rotate the counter to the top (p), Output, and exit (@).

Otherwise, we take the difference of the top two elements. If it's nonzero, we rotate the counter to the top, increment it, and rotate it back to the bottom with p)q. We then pop the difference with ; before moving to the next iteration.

All the characters not mentioned here are just control flow. There tend to be a lot of those in Cubix programs.


@MickyT Good approach, but you seem to be overcounting by 1. You could swap the 0 for a (, but that fails on the empty input.

apologies, will look at it again
MickyT

3

Brain-Flak, 50 bytes

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

Try it online!

Since everyone is posting their 50 byte solutions here is mine (I have a 48 byte one but it was a simple modification of DjMcMayhem's so I did feel it worth posting)

Explanation

This answer extensively uses value canceling.

Un-golfed it looks like

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

Here we compute the delta's until the stack has one item left, each time we accumulate one value from the inner loop if the delta is non zero.

This is a pretty straight forward way of doing it.

To make this golfy we begin value canceling. The first one and the one that should be obvious to any hardened brain-flak golfer is the stack heights. It is a well known fact that

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

is the same as

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

When the values are modified by one, the same holds. This gives us

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

You may notice this didn't even save us bytes, but don't fret it will become more useful as we go on.

We can perform another reduction, if you see a statement

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

you can actually reduce it to

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

This works because if we enter the loop [(...)] and {} will cancel, and if we don't the value of [(...)] already was zero in the first place and doesn't need to be canceled. Since we have an occurrence of this pattern in our code we can reduce it.

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

That saved us 2 bytes but it also put two negs next to each other. These can be combined to save us another 2.

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

And that's our code.


3

Perl 6, 18 bytes

{sum $_ Z!= .skip}

Test it

Expanded:

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

Try it online!

This abuses a bug (or feature?) of Gaia, that run-length-encoding doesn't take the last run of elements into account. Note that I have double checked, it works for all test cases.

  • ė - Run length encoding (with the flaw described above).
  • l - Length.

2

JavaScript (ES6), 35 bytes

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

I wonder if it could be shortened by using recursion. But my best attempt is 35 as well: f=([a,...b])=>1/a?!!(a-b[0])+f(b):0
Arnauld

@Arnauld I'd tried that too, but miscounted and thought it was 36 bytes, otherwise I'd have added it in as an alternative.
Neil


2

APL (Dyalog), 8 bytes

+/2≠/⊃,⊢

Try it online!

How?

⊃,⊢ - the list, with the first value repeated for the case of single element

2≠/ - changes list, not equal for every 2 elements

+/ - sum



2

J, 10 bytes

[:+/2~:/\]

Infixes of length 2... are they unequal? 2 ~:/\ ]

Sum the resulting list of 0s and 1s: +/

Try it online!


[:+/0=-/\ ought to work for I think 9 bytes.
cole

2

Ruby, 31 bytes

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

Try it online!


Instead of .drop(1) you can do [1..-1]
Cyoce

@Cyoce Unfortunately drop returns an Enumerator, not an Array, so that doesn't work.
Jordan

huh. It returns an Array on my version.
Cyoce

@Cyoce Which version?
Jordan

I'm on 1.9.3 but why can't you take the size of an Array anyway?
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;}

Try it Online!

f is a function taking the length of the array and a pointer to the first element of the array, and returning the number of changes in the array;

This submission utilizes undefined behavior (*p++!=*p, p is used twice in an expression in which it is changed), which works on my machine (gcc 5.4.0) and on TIO, but may not work on other implementations or versions.

Explanation:

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
}

Could you maybe add a link to an online testing environment?
Jonathan Frech

@JonathanFrech Added
pizzapants184

2

05AB1E, 3 bytes

γ¦g

Try it online!

An alternative to Erik's answer.

γ¦g  ~ Full program.

γ    ~ Group into runs of equal adjacent elements.
 ¦   ~ Remove the first group (if there are any).
  g  ~ Length.

Ah, missed that that was a case.
Magic Octopus Urn
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.