Compter les changements dans un tableau


20

Aujourd'hui, votre tâche consiste à écrire un programme ou une fonction qui prend un tableau d'entiers et compte le nombre de fois que la valeur change, en la lisant de gauche à droite. C'est plus facile à montrer avec un exemple:[1 1 1 2 2 5 5 5 5 17 3] => [1 1 1 **2** 2 **5** 5 5 5 **17** **3**] => 4

Cas de test:

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

C'est du , le moins d'octets gagne!


Ma réponse est-elle valide si le résultat est toujours correctement calculé, mais si c'est 0, Falseest-il imprimé à la place?
FlipTack

1
@FlipTack Cela dépend de la langue. En général, si je peux dire 2+Falseet ça fait des erreurs, ce n'est pas bien, mais si je comprends 2, c'est bien.
Pavel

@FlipTack Par défaut, c'est le consensus.
2017 totalement humain

La sortie vide est-elle 0acceptable?
Titus

@Titus oui c'est le cas.
Pavel

Réponses:



9

Python 3 , 38 octets

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

Essayez-le en ligne!


2
Huh, savait que vous pouviez utiliser un argument par défaut comme ça, belle trouvaille.
xnor


@Dennis Comment la fonction quitte-t-elle la boucle récursive lorsque le tableau est vide? Je ne vois pas comment cela ne se termine pas en un maximum recursion depth exceeded.
Ioannes

@Ioannes Une fois qu'il ne reste plus qu'un élément ( x ), il y>()sera évalué à False , donc le code suivant andne sera pas exécuté.
Dennis

7

Haskell , 33 octets

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

Essayez-le en ligne!


Bonus: version arithmétique un peu curieuse sans point (44 octets)

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

Essayez-le en ligne!

Compte tenu de l'entrée [1,1,4,3,3,3], nous avons d' abord prendre la différence des entrées adjacentes ( [0,3,-1,0,0]), la absvaleur olute: [0,3,1,0,0]. En prenant zéro à la puissance de chaque élément la première fois donne [1,0,0,1,1], et une seconde fois inverse la liste: [0,1,1,0,0]( (1-)fonctionnerait également ici au lieu de (0^)). Enfin, nous prenons sumla liste pour obtenir 2.



5

Brain-Flak , 50 octets

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

Essayez-le en ligne!

N'affiche rien pour 0, ce qui, dans brain-flak, est équivalent. Si ce n'est pas acceptable, ajoutez ceci pour les +4octets:({})

Explication:

#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 Bien joué! :)
DJMcMayhem


1
@WheatWizard J'ai essayé cela aussi, mais il boucle pour toujours sur une entrée vide. -0+1 = 1
H.PWiz

5

Brain-Flak , 50 octets

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

Essayez-le en ligne!

# 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
Félicitations pour 10k rep!
Pavel

@ Pavel Merci! Il m'a fallu une éternité pour obtenir les dernières centaines. J'ai été trop occupé avec d'autres choses :(
Riley

J'avais ça
H.PWiz

@ H.PWiz J'ai eu ça à un moment donné, mais j'aime comment la pop annule la poussée de la hauteur de pile.
Riley

5

Haskell , 35 octets

-8 octets grâce à H.PWiz.

Out-golfed par une version récursive . Haskell est à peu près le meilleur en récursivité et je l'ai raté. > _ <

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

Essayez-le en ligne!

Ce serait génial si quelqu'un savait comment utiliser cette astuce .

Solution alternative, 36 octets

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

Essayez-le en ligne!



Cette astuce manque le fait crucial que vous auriez besoin de uncurryla fonction fpour la faire fonctionner. C'est sum.map fromEnum.(zipWith(/=)=<<tail)probablement le plus proche que vous obtenez, mais cela ne fonctionnera pas []et est de 37 octets ..
ბიმო

5

Java (OpenJDK 8) , 65 octets

Pas aussi court que je le souhaiterais, mais c'est juste Java pour vous.

Testez en passant le tableau sous forme de liste séparée par des virgules.

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

Essayez-le en ligne!


2
Si le tableau vide n'était pas un cas de test (et je ne le trouve pas vraiment pertinent, en fait), on aurait pu utiliser: a->{int s=0,p=a[0];for(int n:a)s+=p==(p=n)?0:1;return s;}(57 octets).
Olivier Grégoire

@ OlivierGrégoire je sais! J'ai écrit cela et j'ai pensé que j'avais réussi à réduire les octets, mais cela a échoué dans ce premier cas.
Luke Stevens

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

4

Husk , 3 octets

Ltg

Essayez-le en ligne!

Explication

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 octets

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

Essayez-le en ligne!

  • -1 octet merci à Martin Ender!
  • -2 octets grâce à JungHwan Min! bonne utilisation de Split[].
  • -3 octets grâce à totalement humain!

une petite explication:

Splitdivisera un tableau en une liste de listes (des mêmes éléments), c'est-à-dire se transformant {1, 2, 2, 3, 1, 1}en {{1}, {2, 2}, {3}, {1, 1}}. Donc, Length@Split@#c'est la quantité de segments consécutifs. Max[*****-1, 0]est utilisé pour gérer les {}entrées.



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

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

4

Rétine , 24 21 16 octets

Merci à @MartinEnder pour -3 octets et avoir remarqué un bug
-1 octet grâce à @tsh
-4 octets grâce à @Leo

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

Essayez-le en ligne!


4

Python symboliques , 120 117 octets

Golfé 3 octets en supprimant un transtypage explicite en entier (en utilisant unaire +) pour la variable de compteur - cela signifie que s'il n'y a aucun changement dans le tableau, la sortie sera à la Falseplace de0 , mais cela est autorisé par la méta .

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

Essayez-le en ligne!

# 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
= _ = quelle est cette magie?
2017 totalement humain

3

Gelée , 3 octets

ITL

Essayez-le en ligne!

Comment ça fonctionne

ITL - Programme complet.

I - Incréments (deltas).
 T - Récupère les indices des valeurs véridiques (récupère les indices des éléments non-0).
  L - Longueur.

3

K (oK) , 8 octets

Solution:

+/1_~~':

Essayez-le en ligne!

Exemples:

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

Explication:

Interprété de droite à gauche:

+/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 octets

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

Essayez-le en ligne!

Identique à la réponse MATL, juste utilisée sum(!!diff))car il n'y a pas nnz.


+1 Je pensais que l'utilisation rleserait plus courte, mais non, length(rle()$v)utilise trop de caractères et est désactivée par un.
Neal Fultz

@NealFultz ça vaut probablement toujours la peine d'être publié comme réponse! Toujours bon de voir une autre approche. Et vous devez utiliser à la sum(rle()$v|1)place de lengthtoute façon. :)
Giuseppe

3

Cubix , 24 octets

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

Essayez-le en ligne

Notez que Cubix utilise 0 pour indiquer qu'il n'y a plus d'entrées, donc 0 ne peut pas être dans la liste.

Explication

Déplié:

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

Nous commençons par le 0, poussant le compteur (initialisé avec 0) et la première entrée ( I) sur la pile.

On entre alors dans la boucle. À chaque itération de la boucle, nous obtenons l'entrée suivante avec I. Si c'est 0, nous n'avons plus d'entrées, nous faisons donc tourner le compteur vers le haut ( p), l' Output et l'exit ( @).

Sinon, nous prenons la différence des deux premiers éléments. S'il est différent de zéro, nous faisons pivoter le compteur vers le haut, l'incrémentons et le faisons pivoter vers le bas avec p)q. Nous faisons ensuite apparaître la différence avec ;avant de passer à l'itération suivante.

Tous les personnages non mentionnés ici ne sont que des flux de contrôle. Il y en a beaucoup dans les programmes Cubix.


@MickyT Bonne approche, mais vous semblez sur-compter de 1. Vous pouvez échanger le 0pour un (, mais cela échoue sur l'entrée vide.

mes excuses, je le reverrai
mes

3

Brain-Flak , 50 octets

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

Essayez-le en ligne!

Étant donné que tout le monde publie ses solutions de 50 octets, voici la mienne (j'en ai une de 48 octets, mais c'était une simple modification de DjMcMayhem, donc j'ai senti que cela valait la peine d'être publié)

Explication

Cette réponse utilise largement l'annulation de valeur.

Sans golf, il ressemble

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

Ici, nous calculons les delta jusqu'à ce qu'il reste un élément à la pile, chaque fois que nous accumulons une valeur de la boucle interne si le delta n'est pas nul.

C'est une façon assez simple de le faire.

Pour faire ce golf, nous commençons à annuler la valeur. Le premier et celui qui devrait être évident pour tout golfeur endurci de flak de cerveau est la hauteur de la pile. C'est un fait bien connu que

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

est le même que

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

Lorsque les valeurs sont modifiées par un, il en va de même. Cela nous donne

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

Vous remarquerez peut-être que cela ne nous a même pas sauvé des octets, mais ne vous inquiétez pas, cela deviendra plus utile au fur et à mesure.

Nous pouvons effectuer une autre réduction, si vous voyez une déclaration

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

vous pouvez réellement le réduire à

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

Cela fonctionne parce que si nous entrons dans la boucle [(...)]et que {}nous annulerons, et si nous ne le faisons pas, la valeur de [(...)]déjà était zéro en premier lieu et n'a pas besoin d'être annulée. Puisque nous avons une occurrence de ce modèle dans notre code, nous pouvons le réduire.

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

Cela nous a permis d'économiser 2 octets, mais cela a également mis deux négatifs l'un à côté de l'autre. Ceux-ci peuvent être combinés pour nous sauver encore 2.

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

Et c'est notre code.


3

Perl 6 , 18 octets

{sum $_ Z!= .skip}

Essaye-le

Étendu:

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

ėl

Essayez-le en ligne!

Cela abuse d'un bogue (ou d'une fonctionnalité?) De Gaia, que l'encodage de la longueur de l'exécution ne prend pas en compte la dernière exécution des éléments. Notez que j'ai revérifié, cela fonctionne pour tous les cas de test.

  • ė - Codage de longueur de course (avec la faille décrite ci-dessus).
  • l - Longueur.

2

JavaScript (ES6), 35 octets

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

Je me demande si cela pourrait être raccourci en utilisant la récursivité. Mais ma meilleure tentative est aussi 35:f=([a,...b])=>1/a?!!(a-b[0])+f(b):0
Arnauld

@Arnauld J'avais essayé cela aussi, mais je me suis trompé et je pensais que c'était 36 ​​octets, sinon je l'aurais ajouté comme alternative.
Neil


2

APL (Dyalog) , 8 octets

+/2≠/⊃,⊢

Essayez-le en ligne!

Comment?

⊃,⊢ - la liste, avec la première valeur répétée pour le cas d'un élément unique

2≠/ - liste des changements, pas égal pour tous les 2 éléments

+/ - somme



2

J, 10 octets

[:+/2~:/\]

Les infixes de longueur 2 ... sont-ils inégaux? 2 ~:/\ ]

Additionnez la liste résultante de 0s et 1s:+/

Essayez-le en ligne!


[:+/0=-/\ devrait fonctionner pour je pense que 9 octets.
cole

2

Rubis , 31 octets

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

Essayez-le en ligne!


Au lieu de .drop(1)vous pouvez le faire[1..-1]
Cyoce

@Cyoce droprenvoie malheureusement un énumérateur, pas un tableau, donc cela ne fonctionne pas.
Jordan

hein. Il renvoie un tableau sur ma version.
Cyoce

@Cyoce Quelle version?
Jordan

Je suis sur 1.9.3 mais pourquoi ne pouvez-vous pas prendre le contrôle sized'un tableau de toute façon?
Cyoce

2

C (gcc 5.4.0), 61 octets

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

Essayez-le en ligne!

f est une fonction prenant la longueur du tableau et un pointeur sur le premier élément du tableau, et renvoyant le nombre de changements dans le tableau;

Cette soumission utilise un comportement non défini ( *p++!=*p, p est utilisé deux fois dans une expression dans laquelle il est modifié), qui fonctionne sur ma machine (gcc 5.4.0) et sur TIO, mais peut ne pas fonctionner sur d'autres implémentations ou versions.

Explication:

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
}

Pourriez-vous peut-être ajouter un lien vers un environnement de test en ligne?
Jonathan Frech

@JonathanFrech Ajouté
pizzapants184

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.