Réduire les doublons adjacents


22

Défi

Étant donné une liste d'entiers, renvoyez la liste de ces entiers après avoir supprimé à plusieurs reprises toutes les paires d'éléments égaux adjacents.

Notez que si vous avez un nombre impair de longueurs égales, l'un d'eux restera, ne faisant pas partie d'une paire.

Exemple:

[0, 0, 0, 1, 2, 4, 4, 2, 1, 1, 0]

Tout d' abord, vous devez retirer 0, 0, 4, 4et 1, 1d'obtenir:

[0, 1, 2, 2, 0]

Maintenant, vous devez supprimer 2, 2:

[0, 1, 0]

Et c'est le résultat final.

Cas de test

[] -> []
[1] -> [1]
[1, 1] -> []
[1, 2] -> [1, 2]
[11, 11, 11] -> [11]
[1, 22, 1] -> [1, 22, 1]
[-31, 46, -31, 46] -> [-31, 46, -31, 46]
[1, 0, 0, 1] -> []
[5, 3, 10, 10, 5] -> [5, 3, 5]
[5, 3, 3, 3, 5] -> [5, 3, 5]
[0, -2, 4, 4, -2, 0] -> []
[0, 2, -14, -14, 2, 0, -1] -> [-1]
[0, 0, 0, 1, 2, 4, 4, 2, 1, 1, 0] -> [0, 1, 0]
[3, 5, 4, 4, 8, 26, 26, 8, 5] -> [3]
[-89, 89, -87, -8, 8, 88] -> [-89, 89, -87, -8, 8, 88]

Notation

C'est le , donc la réponse la plus courte dans chaque langue gagne!


Sandbox pour ceux qui peuvent voir les messages supprimés
musicman523

Ce n'est pas grave, ils sont tous égaux. Le sens de cette phrase est qu'elle [14, 14, 14]s'effondre pour[14]
musicman523

J'ai mal lu le défi, désolé. Vous pensiez que dû enlever toutes les paires d' un nombre croissant de 1 ( 1,2, 11,12, etc.)
Stephen

Pouvons-nous prendre l'entrée comme une chaîne délimitée?
Shaggy

2
Pourriez-vous ajouter un cas de test tel que -89,89,-87,-8,-88? Ma solution Japt (non publiée) et la solution Retina de Fry échouent là-bas, en sortie --87,8.
Shaggy

Réponses:


5

Gelée , 10 octets

Œgœ^/€FµÐL

Essayez-le en ligne!

Comment ça marche

Œgœ^/€FµÐL  Main link. Argument: A (array)

       µ    Combine all links to the left into a chain.
Œg              Group all adjacent equal items.
    /€          Reduce each group by...
  œ^                symmetric multiset difference.
                In each step, this maps ([], n) to [n] and ([n], n) to [], so the
                group is left with a single item if its length is odd, and no items
                at all if its length if even.
      F         Flatten the resulting array of singleton and empty arrays.
        ÐL  Apply the chain until the results are no longer unique. Return the last
            unique result.

Utiliser au lieu de vous Fferait également prendre en charge les listes dans votre liste.
Erik the Outgolfer du

Non, œ^repose ici sur la promotion d'entier vers tableau. Étant donné que les tableaux 1D ne sont pas promus en tableaux 2D, cela ne fonctionnera que pour un tableau de nombres.
Dennis

Hé ... Je veux dire que tu aurais pu juste utiliser ŒgWẎ$œ^/$€ẎµÐL... oh attends c'est trop naïf. : P
Erik the Outgolfer

4

Retina ,17 15 octets

+m`^(.+)¶\1$¶?

Essayez-le en ligne!

Sauvegardé 2 octets grâce à Neil et Martin!

Remplace chaque paire de chiffres par rien. Ce processus se boucle jusqu'à ce qu'aucune modification ne soit apportée.


A travaillé sur une solution identique dans Japt avant de repérer cela. Malheureusement, nous échouons tous les deux sur des entrées telles que les -89 89 -87 -88 -88sorties --87.
Shaggy

1
@Shaggy Merci, je l'ai corrigé en ajoutant une vérification des limites et en utilisant _pour désigner les négatifs, comme cela est courant dans certaines langues.
FryAmTheEggman

J'ai depuis découvert que cela échouera également lors de la _89 89 _87 _8 _88sortie _89 89 _87 8. Désolé: \
Shaggy

@Shaggy Ne soyez pas désolé! Merci d'avoir trouvé le problème! J'ai ajouté une autre vérification des limites pour corriger ce cas.
FryAmTheEggman

1
@FryAmTheEggman Je ne sais pas si c'est ce que Neil voulait dire, mais vous pouvez également utiliser mpour transformer les \bs en ^et $.
Martin Ender

3

Mathematica 29 octets

Cela supprime à plusieurs reprises des paires d'éléments adjacents égaux, a_,a_jusqu'à ce qu'il n'en reste plus.

#//.{b___,a_,a_,c___}:>{b,c}&

3

Python 2 , 57 octets

r=[]
for x in input():r+=x,;r[-2:]*=r[-2:-1]!=[x]
print r

Essayez-le en ligne!

Construit de manière itérative la liste de sortie en ajoutant l'élément suivant, puis en coupant la fin si l'élément ajouté est égal à celui qui le précède. La vérification de l'avant-dernier élément r[-2:-1]!=[x]s'avère maladroite car il est possible que la liste ait une longueur de 1 seulement.


Réponse
géniale

2

Gelée , 15 octets

Œr;ṪḂ$$€x/€FµÐL

Essayez-le en ligne!

Explication

Œr;ṪḂ$$€x/€FµÐL  Main Link
Œr               Run-length encode
  ;              Concatenate (?)
       €         For each element
   ṪḂ$$          Is the last element odd?
          €      For each element    // Non-breaking alternative
        x/       Reduce by repeating // for run-length decode
           F     Flatten
            µ    (New monadic link)
             ÐL  Repeat until results are no longer unique

-1 octet grâce aux miles, et fixe :)


@FryAmTheEggman Fixed; Merci!
HyperNeutrino

Je ne sais pas si lancer une erreur et laisser la sortie vide compte comme une solution correcte. Vous programmez des lancers ValueError: not enough values to unpack (expected 2, got 0)pour le cas de test [1,2,2,1]. Notez également que la sortie vide est différente []et 2différente de [2].

13 octets avec Œr;ṪḂ$$€ŒṙµÐL. Pour éviter l'erreur, remplacez Œṙparx/€F puisque le décodage de longueur d'exécution génère une erreur lorsqu'il reçoit une liste vide. Pour voir la sortie sous forme de liste, le virement de bord ŒṘl'affichera.
miles

La représentation de @ThePirateBay Jelly d'une liste vide est - vide, d'un élément - juste cet élément, et de plusieurs éléments - une liste entre crochets et séparés par des virgules. La soumission est d'un lien (fonction) pas un programme complet (un peu comme un lambda serait en Python) - pour voir une vue plus "normale" ÇŒṘdans le pied de page pour appeler le dernier lien ( Ç) et imprimer une représentation Python ( ŒṘ) . L'erreur peut cependant ne pas être acceptable.
Jonathan Allan

@JonathanAllan. Ok, j'ai réalisé que la représentation sous forme de chaîne d'une liste par Jelly est acceptable. Le point principal de mon premier commentaire est de mentionner que l'erreur est levée lorsque la liste devient vide.

2

JavaScript (ES6), 54 53 octets

1 octet enregistré grâce à @ThePirateBay

f=a=>1/a.find(q=>q==a[++i],i=-2)?f(a,a.splice(i,2)):a

Solution récursive naïve, peut être améliorable.


Vous pouvez vérifier l'élément actuel et précédent au lieu de l'élément actuel et suivant, vous pouvez donc remplacer i=0par i=-2et i-1avec ilequel est -1 octet au total.

@ guest44851 Merci, mais ... cela ne voudrait-il pas dire que je devrais le changer en i+1? (J'ai déjà essayé cela en déplaçant le ++et je n'ai pas pu le comprendre, même si je n'avais qu'une minute pour le faire)
ETHproductions

Vous pouvez voir que cela fonctionne correctement .

@ThePirateBay Par golly, vous avez raison! Mais comment?
ETHproductions

2

Python 2 , 73 octets

Comme je n'ai pas assez de réputation pour commenter: je viens de changer la réponse de @officialaimm pour utiliser r! = [] Au lieu de len (r) pour enregistrer un octet. Solution très intelligente pour vous, @officialaimm!

r=[]                            # create list that will hold final results. A new list is important because it needs to be removable.
for i in input():               
 if r!=[]and r[-1]==i:r.pop()   # Ensure that we have at least 1 char added to the list (r!=[])... or that the last character of our final result isn't the current character being scanned. If that is, well, remove it from the final list because we do not want it anymore
 else:r+=[i]                    # Shorthand for r.append(i). This adds i to the final result
print r

Essayez-le en ligne!

Il est, encore une fois, trop tard ... pourquoi suis-je encore debout?



2

MATL , 7 octets

t"Y'oY"

Pour certains des cas de test où le résultat est vide, le programme se termine avec une erreur, mais dans tous les cas, il produit la sortie (vide) correcte.

Essayez-le en ligne! Ou vérifiez les cas de test avec une sortie non vide .

Explication

t     % Implicit input. Duplicate
"     % For each (i.e. do as many times as input size)
  Y'  %   Run-length encode. Gives array of values and array of run lengths
  o   %   Parity, element-wise. Reduces run-lengths to either 0 or 1
  Y"  %   Run-length decode. Gives array of values appearing 0 or 1 times;
      %   that is, removes pairs of consecutive values
      % Implicit end. Implicit display

Tenez compte des commentaires

0 0 0 1 2 4 4 2 1 1 0

Chaque itération supprime des paires de paires consécutives. La première itération réduit le tableau à

0 1 2 2 0

Les deux valeurs 2qui sont maintenant adjacentes n'étaient pas adjacentes dans le tableau initial. C'est pourquoi une deuxième itération est nécessaire, ce qui donne:

0 1 0

De nouvelles itérations laisseront cela inchangé. Le nombre d'itérations requises est limité par la taille d'entrée.

Un résultat intermédiaire vide entraîne une Y"erreur de la fonction de décodage de longueur d'exécution ( ) dans la version actuelle du langage; mais la sortie est vide comme requis.


Pourriez-vous ajouter une explication? J'aimerais comprendre comment tu m'as battu si fort. : P
Dennis

@Dennis Sure! J'avais oublié. Fait :-)
Luis Mendo

1
Ah, RLE pousse deux tableaux. C'est utile.
Dennis

2

Code machine x86 (mode protégé 32 bits), 36 octets

52
8B 12
8D 44 91 FC
8B F9
8D 71 04
3B F0
77 10
A7
75 F9
83 EF 04
4A
4A
A5
3B F8
75 FB
97
EB E7
58
89 10
C3

Les octets ci-dessus de code machine définissent une fonction qui prend un tableau en entrée, réduit les doublons adjacents en place et retourne à l'appelant sans renvoyer de résultat. Il suit la __fastcallconvention d'appel , en passant les deux paramètres dans le ECXetEDX registres, respectivement.

Le premier paramètre ( ECX) est un pointeur vers le premier élément du tableau d'entiers 32 bits (si le tableau est vide, il peut pointer n'importe où dans la mémoire). Le deuxième paramètre (EDX ) est un pointeur sur un entier 32 bits qui contient la longueur du tableau.

La fonction modifiera les éléments du tableau sur place, si nécessaire, et mettra également à jour la longueur pour indiquer la nouvelle longueur du tableau réduit. C'est un peu une méthode inhabituelle pour prendre des entrées et retourner des sorties, mais vous n'avez vraiment pas d'autre choix en langage assembleur. Comme en C, les tableaux sont en fait représentés dans le langage comme un pointeur vers le premier élément et une longueur . La seule chose un peu bizarre ici est de prendre la longueur par référence , mais si nous ne le faisions pas, il n'y aurait aucun moyen de raccourcir le tableau. Le code fonctionnerait bien, mais la sortie contiendrait des ordures, car l'appelant ne savait pas où arrêter l'impression des éléments du tableau réduit.

Mnémoniques d'assemblage non golfés:

; void __fastcall CollapseAdjacentDuplicates(int * ptrArray, int * ptrLength);
; ECX = ptrArray              ; ECX = fixed ptr to first element
; EDX = ptrLength
   push  edx                  ; save pointer to the length
   mov   edx, [edx]           ; EDX = actual length of the array
   lea   eax, [ecx+edx*4-4]   ; EAX = fixed ptr to last element 

FindAdjacentPairs:
   mov   edi, ecx             ; EDI = ptr to element A
   lea   esi, [ecx+4]         ; ESI = ptr to element B
FindNext:
   cmp   esi, eax             ; is ptr to element B at end?
   ja    Finished             ; if we've reached the end, we're finished
   cmpsd                      ; compare DWORDs at ESI and EDI, set flags, and increment both by 4
   jne   FindNext             ; keep looping if this is not a pair

; Found an adjacent pair, so remove it from the array.
   sub   edi, 4               ; undo increment of EDI so it points at element A
   dec   edx                  ; decrease length of the array by 2
   dec   edx                  ;  (two 1-byte DECs are shorter than one 3-byte SUB)
RemoveAdjacentPair:
   movsd                      ; move DWORD at ESI to EDI, and increment both by 4
   cmp   edi, eax             ; have we reached the end?
   jne   RemoveAdjacentPair   ; keep going until we've reached the end
   xchg  eax, edi             ; set new end by updating fixed ptr to last element
   jmp   FindAdjacentPairs    ; restart search for adjacent pairs from beginning

Finished:
   pop   eax                  ; retrieve pointer to the length
   mov   [eax], edx           ; update length for caller
   ret

L'implémentation a été inspirée par ma réponse C ++ 11 , mais méticuleusement réécrite en assemblage, optimisant pour la taille. L'assemblage est une bien meilleure langue de golf. :-)

Remarque: Étant donné que ce code utilise les instructions de chaîne, il suppose que l'indicateur de direction est vide ( DF== 0). Il s'agit d'une hypothèse raisonnable dans la plupart des environnements d'exploitation, car l'ABI exige généralement que DF soit clair. Si cela ne peut pas être garanti, une CLDinstruction d'un octet ( 0xFC) doit être insérée en haut du code.

Comme indiqué, il suppose également un mode protégé 32 bits, en particulier un modèle de mémoire "plat", dans lequel le segment supplémentaire ( ES) est le même que le segment de données ( DS).


1

Lot, 133 octets

@set s=.
:l
@if "%1"=="%2" (shift/1)else set s=%s% %1
@shift/1
@if not "%1"=="" goto l
@if not "%s:~2%"=="%*" %0%s:~1%
@echo(%*

J'ai défini s .car Batch est confus s'il n'y a que des doublons. Je dois également utiliser shift/1pour pouvoir %0%s:~1%définir la liste d'arguments sur le nouveau tableau et la nouvelle boucle.


Je dois demander ... pourquoi? Bonne réponse ... mais pourquoi?
Zacharý

@ Zacharý Parce que c'est là.
Neil

1
@ Zacharý En partie, une bonne raison de jouer au golf dans des langues autres que le golf est parce que cela pourrait être utile . Personne ne va lancer un interprète Jelly dans la vraie vie pour le faire, mais ils pourraient avoir besoin de le faire dans un fichier batch!
Cody Gray

Oh. ça a du sens.
Zacharý

1

Gelée , 12 octets

ŒgṁLḂ$$€ẎµÐL

Un lien monadique prenant et renvoyant des listes de numéros.

Essayez-le en ligne! ou voir une suite de tests

Comment?

ŒgṁLḂ$$€ẎµÐL - Link: list
         µÐL - perform the chain to the left until no changes occur:
Œg           -   group runs (yield a list of lists of non-zero-length equal runs)
      $€     -   last two links as a monad for €ach run:
     $       -     last two links as a monad:
   L         -       length (of the run)
    Ḃ        -       modulo 2 (1 if odd, 0 if even)
  ṁ          -     mould (the run) like (1 or 0) (yields a list of length 1 or 0 lists)
        Ẏ    -   tighten (make the list of lists into a single list)

ṁLḂ$$€est équivalent à ḣLḂ$$€ce qui est équivalent à celui ṫḊ¿€3$que vous pouvez remplacer par ṫḊ¿€3ici pour former une paire dyade / nilade.
Erik the Outgolfer du

Cela ne fonctionne pas avec, par exemple, une entrée avec une longueur de 4. Quelle est l'entrée dans la file d'attente à chaque itération de la boucle while?
Jonathan Allan

Vous êtes censé vous retrouver avec une liste avec 0 ou 1 éléments. Si len (x) == 1, alors reviendra []alors que si len (x) == 0 reviendra 0, les deux étant des valeurs fausses. L'entrée de est bien sûr la valeur courante, et aura la valeur courante comme argument de gauche et 3comme droite. Si len (x) == 4, alors ce serait la même chose que ṫ3ṫ3ou ṫ5vous laissant avec [].
Erik the Outgolfer

Je peux voir ce qu'il est censé faire, mais y a- xt-il vraiment dans votre description la valeur actuelle? Essayez ceci pour la taille.
Jonathan Allan

Pour être honnête, je ne sais pas si c'est le code ou un bug :)
Jonathan Allan


1

05AB1E , 15 octets

[γʒgÉ}€нÐγ‚€gË#

Essayez-le en ligne!

Explication

[γʒgÉ}€нÐγ‚€gË#
[               # Start infinite loop
 γ              # Group Array into consecutive equal elements
  ʒgÉ}          # Keep the subarrays with an uneven amount of elements
      €н        # Keep only the first element of each subarray
        Ð       # Triplicate the result on the stack
         γ      # Group the top element into consecutive equal elements
          ‚     # Wrap the top two items of the stack in an array
           €g   # Get the length of each subarray
             Ë# # Break if they are equal
                # Implicit print          

1

05AB1E , 13 octets

[DγʒgÉ}€нDŠQ#

Essayez-le en ligne!

Explication:

[DγʒgÉ}€нDŠQ# Implicit input
[             Start infinite loop
 D            Duplicate
  γ           Split into chunks of equal elements
   ʒ  }       Filter by
    g           Length
     É          Odd? (0=falsy 1=truthy)
       €      Foreach command
        н     Head
         D    Duplicate
          Š   Push c, a, b
           Q  Equal? (0=falsy 1=truthy)
            # Break if true (i.e. equal to 1)


1

Python 2 , 74 70 66 octets

  • Merci @SteamyRoot pour 4 octets: rau lieu delen(r) c'est suffisant pour vérifier le vide de la liste / pile.
  • Merci @ovs pour 4 octets: mieux si la condition [i]==r[-1:]

Python 2 , 66 octets

r=[]
for i in input():
 if[i]==r[-1:]:r.pop()
 else:r+=[i]
print r

Essayez-le en ligne!


1
Si le but de len(r)est juste de vérifier si la liste est vide ou non, vous devriez pouvoir la remplacer par juste r, je pense?
SteamyRoot

Oh oui, merci.
officialaimm


@ovs Merci beaucoup, c'est génial! (y)
officialaimm

1
Version alternative de 66 octets , mais ne nécessitant que trois lignes.
Jonathan Frech

0

Clojure, 100 octets

#(loop[i % j[]](if(= i j)i(recur(mapcat(fn[p](repeat(mod(count p)2)(last p)))(partition-by + i))i)))

Je ne sais pas si c'est le plus court possible.


0

Bash, 82 octets

cat>b
while cat b>a
perl -pe 's/(\d+) \1( |$)//g' a>b
! diff a b>c
do :
done
cat a

Il y a probablement un moyen de sortir de tous ces cats, mais je ne le sais pas.


0

Husk , 10 octets

ωoṁS↑o%2Lg

Essayez-le en ligne!

Explication

ωoṁS↑o%2Lg
ω           Repeat until fixed point
 o          the following two functions:
         g   a) group adjacent elements
  ṁ          b) map over groups and concatenate:
        L     length of group
     o%2      mod 2
   S↑         take that many elements of group

0

PHP, 81 octets

    function f(&$a){for($i=count($a);--$i;)$a[$i]-$a[$i-1]||array_splice($a,$i-1,2);}

fonction, appelez par référence ou essayez-le en ligne .

échoue pour une entrée vide; insérer $i&&ou $a&&avant --$ide fixer.


0

V , 10 octets

òͨ.«©î±î*

Essayez-le en ligne!

Regex comprimé: :%s/\(.\+\)\n\1\n*. Le retour à la ligne facultatif permet de fonctionner également à la fin du fichier. Si je suppose qu'il y a une nouvelle ligne après la fin, ce serait 8 octets ... mais cela semble être un tronçon


0

dc , 84 78 octets

[L.ly1-dsy0<A]sA[LtLtS.ly1+sy]sP[dStrdStr!=Pz1<O]sO[0syzdsz1<Oly0<Azlz>M]dsMxf

Essayez-le en ligne!

Déballage un peu, hors service dans une tentative de clarté:

  • [0syzdsz1<Olydsx0<Alx1+lz>M]dsMxfLa macro principale Mréinitialise le compteur yà 0, récupère le nombre d'éléments sur la pile, le stocke dans le registre z, puis exécute la macro Os'il y a au moins deux éléments sur la pile. Une fois Oterminé, il charge le compteur yet le copie dans le registre xavant de vérifier pour s'assurery n'est pas nul (ce qui signifie que la pile .contient des données). Si tel est le cas, il exécute une macro A. Enfin, il vérifie si la taille de pile d'origine est supérieure à la taille de pile actuelle et se réexécute si tel est le cas. Une fois terminé, il imprime la pile avec f.
  • [dStrdStr!=Pz1<O]sO Macro O stocke temporairement les deux premiers éléments de la pile dans la pile t. Il compare ensuite les deux premiers éléments et exécute une macroP s'ils ne sont pas égaux. Enfin, il vérifie s'il y a au moins deux éléments sur la pile et s'exécute lui-même dans l'affirmative.
  • [LtLtS.ly1+sy]sPLa macro Pprend les deux éléments de la pilet , repousse celui du haut sur la pile principale et pousse le suivant sur la pile .. Il incrémente ensuite le compteur y.
  • [L.ly1-dsy0<A]sA Macro A prend la pile .et la retourne dans la pile principale. Il fait cela, décrémentant le compteur yjusqu'à ce qu'il n'y ait plus rien à pousser.

Modifié pour explication, et pour jouer au golf sur 6 octets car je stockais inutilement la taille de la pile.


0

C ++ 11, 161 octets

#include<vector>
#include<algorithm>
using V=std::vector<int>;void f(V&v){V::iterator i;while((i=std::adjacent_find(v.begin(),v.end()))!=v.end())v.erase(i,i+2);}

Le code ci-dessus définit une fonction,, fqui prend unstd::vector<int> par référence, la modifie en place pour réduire les doublons adjacents selon la spécification, puis retourne.

Essayez-le en ligne!

Avant de vérifier le nombre d'octets, je pensais que c'était un code assez svelte. Plus de 150 octets, ce n'est pas si bon! Soit je ne suis pas très bon au golf, soit le C ++ n'est pas un très bon langage de golf…

Non golfé:

#include <vector>
#include <algorithm>

using V = std::vector<int>;

void f(V& v)
{
   V::iterator i;

   // Use std::adjacent_find to search the entire vector for adjacent duplicate elements.
   // If an adjacent pair is found, this returns an iterator to the first element of the
   // pair so that we can erase it. Otherwise, it returns v.end(), and we stop.
   while ((i=std::adjacent_find(v.begin(), v.end())) != v.end())
   {
        v.erase(i, i+2);   // erase this adjacent pair
   }
}

C ++ n'est pas le meilleur langage de golf. Bonne utilisation de std::adjacent_find! Je me demande si vous avez mis en cette fonction vous - même si ce serait plus court, puisque vous pouvez supprimer #include <algorithm>ainsi
musicman523

@ musicman523 Ma première tentative l' a implémenté à la main, bien que j'aie utilisé un algorithme un peu différent. J'adaptais l'implémentation de std::uniquepour faire ce dont j'avais besoin. Mais il faut beaucoup de code pour faire toute la logique, et quand je suis tombé sur std::adjacent_find, il était assez évident que c'était un gagnant en termes de taille de code.
Cody Gray

0

PHP, 74 octets

function c(&$a){foreach($a as$k=>$v)$a[$k+1]===$v&&array_splice($a,$k,2);}

La fonction c appelle par référence pour réduire le tableau. Essayez-le en ligne .

Fait intéressant, cela fonctionne en Php5.6 mais pas 7.





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.