Supprimer le cas dupliqué et commuté

27

Objectif

Le but de ce défi est: étant donné une chaîne en entrée, supprimez les paires de lettres en double, si le deuxième élément de la paire est de capitalisation opposée. (c'est-à-dire que les majuscules deviennent minuscules et vice-versa).

Les paires doivent être remplacées de gauche à droite. Par exemple, aAadevrait devenir aaet non aA.

exemples

Entrées et sorties:

Input:         Output:  
bBaAdD         bad     
NniIcCeE       Nice    
Tt eE Ss tT    T e S t 
sS Ee tT       s E t   
1!1!1sStT!     1!1!1st!
nN00bB         n00b    
(eE.gG.)       (e.g.)  
Hh3lL|@!       H3l|@!
Aaa            Aa
aaaaa          aaaaa
aaAaa          aaaa

L'entrée se compose de symboles ASCII imprimables.

Vous ne devez pas supprimer les chiffres en double ou autres caractères non-lettre.

Reconnaissance

Ce défi est l'opposé du "Duplicate & switch case" de @nicael . Pouvez-vous l'inverser?

Merci à tous les contributeurs du bac à sable!

Catalogue

L'extrait de pile au bas de cet article génère le catalogue à partir des réponses a) comme une liste des solutions les plus courtes par langue et b) comme un classement général.

Pour vous assurer que votre réponse apparaît, veuillez commencer votre réponse avec un titre, en utilisant le modèle Markdown suivant:

## Language Name, N bytes

Nest la taille de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores dans le titre, en les barrant. Par exemple:

## Ruby, <s>104</s> <s>101</s> 96 bytes

Si vous souhaitez inclure plusieurs nombres dans votre en-tête (par exemple, parce que votre score est la somme de deux fichiers ou que vous souhaitez répertorier les pénalités de drapeau d'interprète séparément), assurez-vous que le score réel est le dernier numéro de l'en-tête:

## Perl, 43 + 2 (-p flag) = 45 bytes

Vous pouvez également faire du nom de la langue un lien qui apparaîtra ensuite dans l'extrait de code:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

aloisdg dit Réintégrer Monica
la source
4
Haha, c'est NniIcCeE :)
nicael
@nicael Je suis content que vous approuviez :)
aloisdg dit Reinstate Monica
quelle est la sortie pour abB:? abBou ab?
Downgoat
@Downgoat abBdevrait sortirab
aloisdg dit Reinstate Monica
1
@raznagul pourquoi le ferait-il? Séparez-: aa; aA; AA, seule la paire du milieu correspond au motif et devient aainsi aa; a; AA
LLlAMnYP

Réponses:

12

Gelée , 8 octets

ṛŒsḟḟȧµ\

Essayez-le en ligne! ou vérifiez tous les cas de test .

Comment ça marche

ṛŒsḟḟȧµ\  Main link. Argument: s (string)

      µ   Convert all links to the left into a chain (unknown arity) and begin a
          new chain.
       \  Do a cumulative reduce by the chain to the left.
          Left argument:   r (previous result or first character)
          Right argument:  c (next character)
ṛ           Set the return value to c.
 Œs         Swap c's case.
    ḟ       Remove c from r (if present).
            This yields an empty string if c and r are identical (repeated letter
            with the same case or non-letter) and r otherwise.
            Note that r will be empty if the previous character has been removed.
   ḟ        Remove the resulting characters (if any) from c with swapped case.
            This yields c with swapped case if the result to the right does not
            contain c; otherwise, it yields the empty string.
     ȧ      Flat logical AND with c.
            Replace swapped case c with c; do not modify an empty string.
Dennis
la source
Plus court que le foutu Regex!
aloisdg dit Réintégrer Monica
2
Battez Retina sur un défi de cordes ._.
TuxCrafting du
11

Rétine , 18 octets

(.)(?!\1)(?i)\1
$1

Essayez-le en ligne!

Explication

Il s'agit d'une substitution unique (et assez simple) qui correspond aux paires pertinentes et les remplace uniquement par le premier caractère. Les paires sont appariées en activant l'insensibilité à la casse à mi-chemin du motif:

(.)     # Match a character and capture it into group 1.
(?!\1)  # Use a negative lookahead to ensure that the next character *isn't* the same
        # as the character we just captured. This doesn't advance the position of the
        # regex engine's "cursor".
(?i)    # Now activate case-insensitivity for the remainder of the pattern.
\1      # Match the second character with a backreference to the first. With the i
        # modifier activated, this will match if the two characters only differ
        # by case.

La substitution réécrit simplement le personnage que nous avons déjà capturé dans le groupe de 1toute façon.

Martin Ender
la source
1
Bonne réponse! Debuggex fonctionne très bien avec celui-ci!
aloisdg dit Réintégrer Monica le
5

Brachylog , 44 octets

.v|.l1|hA,?bhB(@uA;A@uB),?bb&~b.hA|?b&~b.h~h?

Brachylog n'a pas d'expressions régulières.

Explication

    .v          Input = Output = ""
|               OR
    .l1         Input = Output = string of one character
|               OR
    hA,         A is the first char or the Input
    ?bhB        B is the second char of the Input
    (
        @uA         B uppercased is A
        ;           OR
        A@uB        A uppercased is B
    ),
    ?bb&        Call recursively on Input minus the first two elements
    ~b.hA       Output is the result of that call with A appended before it
|               OR
    b&          Call recursively on Input minus the first element
    ~b.h~h?     Output is the result of that call with the first element of Input appended
                  before it
Fatalize
la source
5

C #, 87 75 octets

s=>System.Text.RegularExpressions.Regex.Replace(s,@"(.)(?!\1)(?i)\1","$1");

Avec le puissant regex de Martin Ender. C # lambda où se trouvent l'entrée et la sortie string.

12 octets enregistrés par Martin Ender et TùxCräftîñg.


C #, 141 134 octets

s=>{var r="";for(int i=0,l=s.Length;i<l;i++){var c=s[i];r+=c;if(char.IsLetter(c)&i+1<l&&(c|32)==(s[i+1]|32)&c!=s[i+1])i++;}return r;};

C # lambda où se trouvent l'entrée et la sortie string. L'algorithme est naïf. C'est celui que j'utilise comme référence.

Code:

s=>{
    var r = "";
    for(int i = 0; i < s.Length; i++)
    {
        r+=s[i];
        if (char.IsLetter(s[i]) & i+1 < s.Length)
            if (char.ToLower(s[i])==char.ToLower(s[i+1])
              & char.IsLower(s[i])!=char.IsLower(s[i+1]))
                i += 1;
    }       
    return r;
};

7 octets grâce à Martin Ender!


Essayez-les en ligne!

aloisdg dit Réintégrer Monica
la source
@ TùxCräftîñg En effet mais c'est facile à lire comme ça. Vérifiez ma version golfée pour une réponse moins verbeuse :)
aloisdg dit Réintégrer Monica
4

Perl, 40 24 + 1 = 25 octets

Utilisez le même regex que Martin.
Utilisez le -pdrapeau

s/(.)(?!\1)(?i)\1/\1/g

Testez-le sur ideone

TuxCrafting
la source
Si vous utilisez l'indicateur -p, vous pouvez supprimer presque tout votre code à l'exception du s /// pour une bonne économie!
Dom Hastings
4

Python 3, 64 59 58 octets

r=input()
for c in r:r=c[c.swapcase()==r!=c:];print(end=r)

Testez-le sur Ideone .

Dennis
la source
4

C, 66 octets

l;main(c){for(;~(c=getchar());)l=l^c^32|!isalpha(c)?putchar(c):0;}
orlp
la source
3

Pyth, 24 20 octets

4 octets grâce à @Jakube.

Cela utilise toujours l'expression régulière, mais uniquement pour la tokenisation.

shM:zj\|+s_BVGrG1\.1

Suite de tests.

shM:zj\|+s_BVGrG1\.1   input as z
         s_BVGrG1      generate ['aA', 'Aa', 'bB', 'Bb', ..., 'zZ', 'Zz']
        +        \.    add "." to the back of the array
     j\|               insert "|" between every element of the array,
                       forming a new long string, which will be our
                       tokenizer: "aA|Aa|bB|Bb|cC|Cc|...|yY|Yy|zZ|Zz|."
                       the "." at the end is to capture the remaining characters
  :z               1   return all matches of z against that regex
                       this is effectively a tokenizer
 hM                    take the first character of each token
s                      join all the transformed tokens together, and then
                       implicitly print to STDOUT.
  • Version 24 octets ici .
Leaky Nun
la source
3

JavaScript (ES6), 71 68 octets

s=>s.replace(/./g,c=>l=c!=l&&c>'0'&&parseInt(c+l,36)%37<1?'':c,l='')

Explication:

s=>s.replace(/./g,c=>   Loop over each character in the string
 l=                     Save result for next loop
  c!=l&&                Check whether characters differ
  c>'@'&&               Check minimum character code
  parseInt(c+l,36)%37<1 Check if characters have same value
  ?'':c,                If so then delete this character
 l='')                  Initial empty previous character

Étant donné c>'@', la seule façon parseInt(c+l,36)d'être un multiple de 37 est pour les deux cet ld'avoir la même valeur (ils ne peuvent pas avoir une valeur nulle parce que nous avons exclu l'espace et zéro, et s'ils n'ont pas de valeur, l'expression évaluera à NaN<1laquelle correspond false) est pour eux d'être la même lettre. Cependant, nous savons qu'ils ne sont pas la même lettre sensible à la casse, donc ils doivent être identiques à la casse.

Notez que cet algorithme ne fonctionne que si je vérifie chaque caractère; si j'essaye de le simplifier en faisant correspondre les lettres, cela échouera sur des choses comme "a+A".

Edit: sauvé 3 octets grâce à @ edc65.

Neil
la source
Utilisez remplacer au lieu de la carte. 68. Mais je suis trop paresseux pour comprendre comment mettre '' 'dans un commentaire (nice trick mod 37)
edc65
@ edc65 Je n'ai pas besoin de `s si j'utilise replace. (Je les avais seulement avant pour essayer d'être cohérent, mais j'ai ensuite joué ma réponse en la modifiant pour la soumission et je suis redevenu incohérent.)
Neil
3

C, 129 127 125 107 106 105 93 92 90 88 85 78 bytes

c;d;f(char*s){for(;putchar(c=*s);)s+=isalpha(c)*(d=*++s)&&(!((c^d)&95)&&c^d);}

Port AC de ma réponse C # . Mon C peut être un peu mauvais. Je n'utilise plus beaucoup la langue. Toute aide est la bienvenue!

  • 1 octet sauvé grâce à l' astuce de Lowjacker : a!=b=a^b
  • 1 octet sauvé grâce à l' astuce de Walpen : a&&b=a*b
  • 12 octets sauvés par le tour de Lynn et inspirés ici par TùxCräftîñg
  • 1 octet sauvé grâce à l' astuce de Joey Adams et inspiré ici par orlp: Déplacer la variable vers global
  • 2 octets enregistrés par SEJPM en résolvant mon (c|32)==(d|32)problème au niveau du bit
  • 5 octets enregistrés par Pietu1998

Code:

c;d;f(char*s) {
    for(;putchar(c=*s);)
        s+=isalpha(c)*(d=*++s)&&(!((c^d)&95)&&c^d);
}

Essayez-le en ligne!

aloisdg dit Réintégrer Monica
la source
1
Je pense que vous pouvez incrémenter le pointeur pour économiser quelques octets. J'ai trouvé ceci (non testé):f(char*s){while(*s) {char c=*s,d=s+1;putchar(c);s+=isalpha(c)&&d&&((c|32)==(d|32)&&c!=d);}}
TuxCrafting
@ TùxCräftîñg J'ai oublié celui-ci. J'ai corrigé votre proposition en fonction de la réponse de Lynn. Merci pour l'aide!
aloisdg dit Réintégrer Monica le
1
Je pense que vous pouvez changer s+++1pour ++s.
PurkkaKoodari
@ Pietu1998 En effet, je peux!
aloisdg dit Réintégrer Monica le
1
cet dsera toujours ASCII imprimable, donc 95devrait fonctionner à la place de ~32. En outre, je pense que c;d;f(char*s){for(;*s;){putchar(c=*s);s+=isalpha(c)*(d=*(++s))&&(!((c^d)&95)&&c^d);}}cela fonctionnerait (mais non testé).
PurkkaKoodari
3

MATL , 21 octets

"Kk@k=K@XK=>?4XKx}K&h

Essayez-le en ligne! . Ou vérifiez tous les cas de test .

Explication

Cela traite chaque caractère dans une boucle. Chaque itération compare le caractère actuel au caractère précédent. Ce dernier est stocké dans le presse-papiers K, qui est initialisé 4par défaut.

Le caractère actuel est comparé deux fois au précédent: d'abord sans tenir compte de la casse, puis en respectant la casse. Le caractère actuel doit être supprimé si et seulement si la première comparaison est vraie et la seconde est fausse. Notez que, puisque le presse-papiers K contient initialement 4, le premier caractère sera toujours conservé.

Si le caractère actuel est supprimé, le presse-papiers K doit être réinitialisé (le caractère suivant sera donc conservé); sinon, il doit être mis à jour avec le caractère actuel.

"            % Take input string implicitly. For each char from this string:
  K          %   Push previous char, initiallized to number 4
  k          %   Convert to lower case. For numbers it rounds down
  @          %   Push current char
  k          %   Convert to lower case. 
  =          %   True if current and previous chars are (case-insensitively) equal
  K          %   Push previous char
  @          %   Push current char
  XK         %   Update clipboard K with current char. This doesn't affect the stack
  =          %   True if current and previous chars are (case-sensitively) equal
  >?         %   If first comparison was true and second was false
    4XKx     %     Reset clipboard K to 4
  }          %   Else
    K        %     Push previous char
    &h       %     Concatenate horizontally to gradually build the output string
Luis Mendo
la source
2

Java 7, 66 octets

String c(String i){return i.replaceAll("(.)(?!\\1)(?i)\\1","$1");}

Utilisé l'expression régulière de Martin Ender de sa réponse Retina .

Code non testé et testé:

Essayez-le ici.

class Main{
  static String c(String i){
    return i.replaceAll("(.)(?!\\1)(?i)\\1", "$1");
  }

  public static void main(String[] a){
    System.out.println(c("bBaAdD"));
    System.out.println(c("NniIcCeE"));
    System.out.println(c("Tt eE Ss tT"));
    System.out.println(c("sS Ee tT"));
    System.out.println(c("1!1!1sStT!"));
    System.out.println(c("nN00bB"));
    System.out.println(c("(eE.gG.)"));
    System.out.println(c("Hh3lL|@!"));
    System.out.println(c("Aaa"));
    System.out.println(c("aaaaa"));
    System.out.println(c("aaAaa"));
  }
}

Sortie:

bad
Nice
T e S t
s E t
1!1!1st!
n00b
(e.g.)
H3l|@!
Aa
aaaaa
aaaa
Kevin Cruijssen
la source
2

JavaScript (ES6), 61 octets , 57 octets

s=>s.replace(/./g,c=>l=c!=l&/(.)\1/i.test(l+c)?'':c,l='')

Merci à Neil d' avoir économisé 5 octets.

cPu1
la source
1
Mauvaise nouvelle: vous avez mal compté, et c'est en fait 62 octets. Bonne nouvelle: je peux vous faire économiser cinq octets! s=>s.replace(/./g,c=>l=c!=l&/(.)\1/i.test(l+c)?'':c,l='')
Neil
Oh, désolé, j'ai compté utiliser, je "code".lengthne savais pas qu'il y avait une séquence d'échappement là-dedans. Merci
cPu1
Essayez d'utiliser (code).toString().length.
Neil
Ouais, ou(code+"").length
cPu1
1

JavaScript (ES6) 70

(s,p,q)=>s.replace(/./g,c=>p!=c&q===(d=parseInt(c,36))?q='':(q=d,p=c))

f=(s,p,q)=>s.replace(/./g,c=>p!=c&q===(d=parseInt(c,36))?q='':(q=d,p=c))

;
[['bBaAdD','bad']
,['NniIcCeE','Nice']
,['Tt eE Ss tT','T e S t']
,['sS Ee tT','s E t']
,['1!1!1sStT!','1!1!1st!']
,['nN00bB','n00b']
,['(eE.gG.)','(e.g.)']
,['Hh3lL|@!','H3l|@!']
,['Aaa','Aa']
,['aaaaa','aaaaa']
,['aaAaa','aaaa']]
.forEach(
  x=>
  {
    var i=x[0],k=x[1],r=f(i)
    console.log(k==r?'OK':'KO',i,r)
  }
)

edc65
la source
OK, je vais mordre. Pourquoi ===?
Neil
0==""mais pas 0===""@Neil
edc65
1

Convexe, 18 octets

V±V.+'.+'|*\ô{0=}%

Essayez-le en ligne!

Approche similaire à la réponse Pyth de @Leaky Nun . Il construit le tableau ["aA" "bB" ... "zZ" "Aa" "Bb" ... "Zz" '.], joint par le '|caractère et teste l'entrée en fonction de cette expression régulière. Il faut ensuite le premier caractère de chaque match.

GamrCorps
la source