Soustraction de chaîne


37

Objectif

Créer une fonction pour inverser la concaténation de chaînes

Contribution

Deux chaînes (alphanumériques + espaces), où l’une doit être soustraite pour l’autre.

  • Vous pouvez supposer que la chaîne à soustraire ne sera jamais plus grande que l'autre.

Sortie

Le résultat de la soustraction

Soustraction

Vous devez supprimer une chaîne du début ou de la fin d'une autre chaîne. Si la chaîne est présente au début et à la fin, vous ne pouvez en supprimer qu'une, celle qui sera supprimée dépend de vous.
Si la chaîne n'est pas au début ou à la fin, ou n'est pas une correspondance exacte, il s'agit d'une soustraction non valide et vous devez générer la chaîne d'origine.

Cas de test

Soustraction valide

'abcde','ab' -> 'cde'
'abcde','cde' -> 'ab'
'abab','ab' -> 'ab'
'abcab','ab' -> 'abc' or 'cab'
'ababcde','ab' -> 'abcde'
'acdbcd','cd' -> 'acdb'
'abcde','abcde' -> ''
'abcde','' -> 'abcde'
'','' -> ''

Soustraction non valide (retourne la chaîne d'origine)

'abcde','ae' -> 'abcde'
'abcde','aa' -> 'abcde'
'abcde','bcd' -> 'abcde'
'abcde','xab' -> 'abcde'
'abcde','yde' -> 'abcde'

Entrée invalide (ne doit pas être traitée)

'','a' -> ''

C'est du , donc le code le plus court en octets gagne!


4
Pourquoi le résultat du premier cas n'est-il pas cde? Qu'entendez-vous par valide? Devons-nous juger de la validité des entrées ou voulez-vous dire que nous ne recevrons pas d'entrées non valides?
Leaky Nun

7
Bon sang 'abcde','bcd' -> 'abcde', pour avoir brisé ma solution
John Dvorak

5
Pouvons-nous supposer que les chaînes seront rationnelles (espaces alphanumériques +)?
John Dvorak

2
Je suggérerais 'ababcde', 'ab''abcde'comme test. Certains algorithmes naïfs échouent sur celui-là.

2
@Rod Vous pourriez envisager de retitrer le défi "Concaténation de chaîne inverse"?
MD XF

Réponses:


19

Java 8, 46 45 44 40 octets

-1 octet grâce à TheLethalCoder

-1 octet parce que je suis idiot (merci Rod!)

-4 octets grâce à Kevin Cruijssen

a->b->a.replaceFirst("^"+b+"|"+b+"$","")

Essayez-le en ligne! (inclut tous les cas de test)

Une réponse Java bat en réalité quelques autres langages pratiques. Des sourires. (Et maintenant, il bat JS!)


Utilisez currying pour sauvegarder un octeta->b->
TheLethalCoder

@ TheLethalCoder Merci.
Okx

Pourquoi avez-vous laissé dans le hashmap inutilisé dans votre exemple en ligne?
Michael

Vous pouvez modifier le Firstà All-2 octets. Etant donné ^que $c'est toujours à la fin ou au début de la chaîne, replaceAllelle ne la remplace qu'une fois. Essayez ici. PS: J'ai ajouté le nombre d'octets précédent barré à votre réponse, ce qui est généralement fait après les modifications de code-golf effectuées ici sur PPCG.
Kevin Cruijssen

@KevinCruijssen Je connaissais les barrés, je suppose que j'ai tout simplement oublié cette fois. Cependant, si j'utilise Allau lieu de First, cela devient vrai:"abab" + "ab" -> ""
Okx

9

JavaScript (ES6), 41 octets

s=>t=>s.replace(eval(`/^${t}|${t}$/`),'')

Accepte les entrées via la syntaxe de currying, c'est-à-dire f("abab")("ab").


3
Maintenant, pourquoi n'ai-je jamais pensé à utiliser eval()pour construire RegExes auparavant?!
Shaggy

9

Brachylog (Essayez-le en ligne!), 12 octets

~cpĊh.∧Ċtw|w

Essayez-le en ligne!

Prend la chaîne à soustraire de l'entrée standard et la chaîne à soustraire en tant qu'argument de ligne de commande.

Explication

~cpĊh.∧Ċtw|w
~c            Split {the input} into pieces
  p           and (possibly) rearrange those pieces
   Ċ          such that there are two pieces
    h         and the first
     .        matches the command line argument
      ∧       then
         w    print
        t     the last
       Ċ      piece.
          |   If all else fails,
           w  print {the input}.


6

JavaScript (ES6), 76 70 45 41 octets

s=>t=>s.replace(RegExp(`^${t}|${t}$`),"")

L'essayer

f=
s=>t=>s.replace(RegExp(`^${t}|${t}$`),"")
o.innerText=f(i.value="abcde")(j.value="ab")
i.oninput=j.oninput=_=>o.innerText=f(i.value)(j.value)
<input id=i><input id=j><pre id=o>


2
Tu n'as pas besoin new .
programmer5000

@ programmer500, j'ai un peu cessé de travailler là-dessus quand j'ai vu la version d'ETH! : D Mis à jour maintenant. Merci.
Shaggy

4

Perl 6 , 21 octets

->$_,$b {S/^$b|$b$//}

L'essayer

Étendu:

-> $_, $b {   # pointy block lambda

  S/          # Str replace and return (implicitly against 「$_」)

  |   ^ $b    # starting with the second argument
  |     $b $  # or ending with the second argument

  //          # replace with nothing.

}


3

TI-Basic (TI-84 Plus CE), 63 octets

Prompt Str0,Str2
inString(Str0,Str2
If Ans
sub(Str0,1,Ans-1)+sub(Str0,Ans+length(Str2),length(Str0)-Ans+1-length(Str2→Str0
Str0

J'ai une question, pourquoi n'avez-vous pas utilisé Str1 comme variable?
Zacharý

@ Zacharý, je pense que j'avais quelque chose de stocké à l'époque. Je ne m'en souviens pas vraiment.
pizzapants184

À quoi fait Ans-on référence à la quatrième ligne?
Zacharý

@ Zacharý se Ansréfère à la dernière valeur évaluée, donc dans ce cas, à la valeur renvoyée par inString(, qui correspond à l'index de la sous-chaîne Str2de la chaîne Str0ou à 0 si la sous-chaîne n'apparaît pas. Une instruction if ne modifie pas la valeur de Ans, donc sur la quatrième ligne, l'index est toujours présent Ans.
pizzapants184

Oh, j'ai oublié comment inStringfonctionnait. Beau golf!
Zacharý

3

Mathematica, 162 octets

(c=Characters;a=c@#;b=c@#2;l=Length;t={};If[l@Intersection[a,b]==l@b,If[MemberQ[Partition[a,l@b,1],b],t=a;Table[t=DeleteCases[t,b[[i]],1,1],{i,l@b}]],t=a];""<>t)&

test du style d'entrée ["abcde", "ab"]


1
Belle solution! Vous pouvez enregistrer un octet en utilisant à la #place de #1- ils ont exactement la même signification. En outre, au lieu d'utiliser StringJoin@t, vous pouvez tricher en joignant une chaîne vide à celle-ci ""<>t, qui joint automatiquement tout tensemble. Avez-vous vu la page des astuces de golf de Mathematica ?
Pas un arbre

Il y a encore quelques choses que vous pouvez faire pour économiser des octets (je ne pense pas que vous n’ayez pas besoin de définir t={};au début, par exemple), mais il serait peut-être plus facile d’utiliser une approche totalement différente: avez-vous essayé StringReplaceune fonction?
Pas un arbre

Vous êtes autorisé à prendre un tableau de chaînes en entrée, vous n'avez donc pas vraiment besoin dec=Characters;a=c@#;b=c@#2;
JungHwan Min

Aussi, l@Intersection[a,b]est l[a∩b].
JungHwan Min


3

Bash ,66 61 49 octets

case $1 in *$2)echo ${1%$2};;*)echo ${1#$2};;esac

Essayez-le en ligne!

moins golfé:

a=$1;
case $1 in 
    *$2)  c=${a%$2};;       
    $2*)  c=${a#$2};;
      *)  c=$1;;
esac;
echo $c

Utilise la casse pour tester le début ou la fin et la soustraction du préfixe / suffixe du tableau (% / #)


1
Bon usage de case, mais plus long que nécessaire. Les 2e et 3e modèle pourraient être fusionnés en un seul: *)c=${1#$2};;. Puis , avec seulement deux branches seraient plus courtes à echochaque directement au lieu d'utiliser la variable $c: case $1 in *$2)echo ${1%$2};;*)echo ${1#$2};;esac. Ou vous pouvez continuer à l' utiliser, mais sans case: c=${1%$2};[[ $c = $1 ]]&&c=${1#$2};echo $c.
manatwork

3

APL (Dyalog) , 31 à 30 octets

-1 grâce à Zacharý .

Ceci utilise en fait la concaténation inverse (c'est-à-dire l'inverse de)! Prend la chaîne d'origine comme argument de gauche et ce qu'il faut soustraire comme argument de droite.

{0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}

Essayez-le en ligne!

Ungolfed:

{
    0::⍺{          if an error happens, apply the following function on the arguments
        0::⍺           if an error happens, return the left argument unmodified
        ,∘⍵⍣¯1⊢⍺       inverse-append right argument on left argument
        }⍵
    ⍵,⍣¯1⊢⍺       inverse-prepend the right argument on the left argument
}

Légende:

{} Fonction anonyme

 argument gauche de la fonction courante

 bon argument de la fonction courante

0::… Si une erreur se produit, exécutez ceci, sinon…

⍣¯1⊢ inverse

,∘⍵ concaténer à droite

⍵, concaténer à gauche


Je pense que vous pouvez économiser un octet avec {0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}.
Zacharý

@ Zacharý Oui, merci.
Adám



2

Haskell , 49 octets

f s a b|s==b=a|a/=b,h:t<-a=f(s++[h])t b|1<3=s
f""

Essayez-le en ligne! Utilisation: f"" "abcdef" "ab". Alternativement, définir (-)=f""et utiliser comme "abcdef" - "ab".

Cette solution sans regex fonctionne en scindant de manière récursive la chaîne dans tous ses préfixes et postfixes et en vérifiant si la chaîne à soustraire correspond à l'un d'entre eux.



1

C #, 88 octets

s=>r=>s.StartsWith(r)?s.Substring(r.Length):s.EndsWith(r)?s.Substring(0,s.IndexOf(r)):s;

Compile a Func<string, Func<string, string>>.


1

Ruby (expression lambda), 29 octets

->a,b{a.sub /^#{b}|#{b}$/,""}

Yay pour l'interpolation regex! Requiert des soustraits regex-safe, mais cela ne pose pas de problème selon le défi.


1

Tcl , 37 octets

proc s {a b} {regsub "^$b|$b$" $a {}}

Essayez-le en ligne! (exécute maintenant tous les tests)

Tcl est simple. proc s {a b}définit une fonction nommée squi prend des paramètres aet b. regsubsubstitutes {}, qui est une chaîne vide, pour la valeur du bdébut ou de la fin de a. Le retour est implicite.


1

C, 96 octets

Il est de notoriété publique que la manipulation des cordes en C est lourde, car une extension de golf serait limite masochiste. Cela me va.

f(a,b,t,l)char**a,*b,*t;{t=*a;l=strlen(b);bcmp(t,b,l)?bcmp(t+=strlen(t)-l,b,l)||(*t=0):(*a+=l);}

L'un des programmes les moins lisibles que j'ai écrits. Prend deux entrées (quelle que soit l'apparence de la fonction), un char**pointant sur la chaîne à déconcaténer et un char*qui est la chaîne à supprimer. Le pointeur d'entrée est édité à la place et devient la sortie (qui parle quand même des fuites de mémoire).

Exemple d'utilisation:

char *a = malloc(6);
strcpy(a, "abcde");
char *b = malloc(4);
strcpy(b, "abc");
f(&a,b);
printf("%s\n", a); // "de"

1

AWK , 21 32 octets

{sub("^"$2"|"$2"$",z,$1);$0=$1}1

Essayez-le en ligne!

La soumission originale a naïvement remplacé le texte dans la première chaîne, pas seulement au début ou à la fin.

{sub($2,z,$1);$0=$1}1

Essayez-le en ligne!

A l'origine essayé sans accolades, mais il fallait des astuces pour imprimer des lignes vides et / ou des non-correspondances qui ont fini par ajouter plus d'octets que cette version.


1

R, 20 42 41 octets

pryr::f(sub(sprintf('^%s|%s$',b,b),'',a))

-1 octet grâce à MickyT!

Retourne une fonction anonyme (qui a des arguments dans l'ordre b,a). Calcule la différence de chaîne a-b. subest une simple substitution qui permute la première occurrence du motif avec, dans ce cas, la chaîne vide ''. Construit l’expression rationnelle avec sprintfpour qu’elle ne corresponde qu’au début et à la fin de la chaîne. Nécessite l' pryrinstallation du package.

Sur le lien TIO, utilise la function(a,b)définition plus détaillée de la fonction pour quatre octets supplémentaires.

Essayez-le en ligne!


1
Qu'en est-il de l' 'abcde','bcd' -> 'abcde'affaire?
Jonathan Allan

" subest une simple substitution qui remplace simplement la première occurrence de bin a": cette permutation sera-t-elle effectuée si la deuxième chaîne est au milieu de la première chaîne?
TheLethalCoder

J'ai mal compris la question! Oops. Merci d'avoir attrapé ça!
Giuseppe

vous pouvez obtenir 1 octet avecsprintf('^%s|%s$',b,b)
MickyT

@MickyT, merci! fixé.
Giuseppe

1

Common Lisp, 121 octets

(lambda(x y)(cond((equal(#1=subseq x 0 #3=(length y))y)(#1#x #3#))((equal(#1#x #2=(-(length x)#3#))y)(#1#x 0 #2#))(t x)))

Essayez-le en ligne!

Le common Lisp habituel verbeux!

Version non-golfée:

(defun f(x y)
  (cond ((equal (subseq x 0 (length y)) y)               ; if x starts with y
         (subseq x (length y)))                          ; return rest of x
        ((equal (subseq x (- (length x) (length y))) y)  ; if x ends with x
         (subseq x 0 (- (length x) (length y))))         ; return first part of x
        (t x)))                                          ; else return x

1

Kotlin , 91 octets

{a,b->val v=b.length
if(a.startsWith(b))a.drop(v)else if(a.endsWith(b))a.dropLast(v)else a}

Essayez-le en ligne!


? {a,b->var c=a.removePrefix(b);if(a==c){c=a.removeSuffix(b)};c}
mazzy

@ Mazzy, n'hésitez pas à soumettre cela comme votre propre réponse.
snail_

1

Powershell, 34 à 40 octets

+6 octets lorsque Invalid Subtractiondes cas de test sont ajoutés

param($s,$t)$s-replace"^$t(?!.*$t$)|$t$"

Commentaire:

L’expression regexp ^$t|$t$ne fonctionne pas comme prévu: elle remplace les deux correspondances au lieu d’une (flagg toujours activé). Nous sommes donc obligés d’utiliser le groupe de surveillance négatif.

Script de test:

$f = {
    param($s,$t)$s-replace"^$t(?!.*$t$)|$t$"
}

@(
    ,('abcde','ab', 'cde')
    ,('abcde','cde', 'ab')
    ,('abab','ab', 'ab')
    ,('abcab','ab', 'abc', 'cab')
    ,('ababcde','ab', 'abcde')
    ,('acdbcd','cd', 'acdb')
    ,('abcde','abcde', '')
    ,('abcde','', 'abcde')
    ,('','', '')

    ,('abcde','ae', 'abcde')
    ,('abcde','aa', 'abcde')
    ,('abcde','bcd', 'abcde')
    ,('abcde','xab', 'abcde')
    ,('abcde','yde', 'abcde')

    ,('','a', '')
) | % {
    $s,$t,$e = $_
    $r = &$f $s $t
    "$($r-in$e): $r"
}

Sortie:

True: cde
True: ab
True: ab
True: abc
True: abcde
True: acdb
True:
True: abcde
True:

0

QBIC , 57 octets

Whegh, c'est un gâchis dans QBIC / QBasic ...

B=@ `+B┘x=instr(;,;)~x|?_t_sB,x-1|+_sB,x+_lC|,_lB|||\?B

B=@ `+B          Prepend a string to B$. Thisis a hack to avoid errors with 
                 removing substrings stating at index 1
┘                Line-break in QBasic output
       (;,;)     Read the string (B$) and the to-be-removed substring (C$)
x=instr          And make x to be the starting index of the first C$ in B$
~x|              IF X <> 0 (ie C$ is present in B$)
?                PRINT
 _t                trimmed version (drops the prepended space)
  _sB,x-1|+        of a substring from 1 to x (the start of C$) -1
  _sB,x+_lC|,_lB   and the rest of the string, starting after C$
                     _l takes the length of a string
  |||              End TRIM, end Substring, end Length
\?B              When missing C$, just print B$


0

Au début, j'ai mal lu les instructions. Merci, Ørjan Johansen d' avoir signalé mon erreur!

PowerShell , 46 à 51 octets

Function F($o,$a){([regex]"^$a").replace($o,'',1);}

Essayez-le en ligne!


Cela échoue dans le cas "abcde" "bcd".
Ørjan Johansen

Je vois les résultats attendus de ce test - TIO ici
Jeff Freeman

Il s'agit d'un cas de test répertorié de l'OP et le résultat devrait être abcde- bcdne se produit pas à l'une des extrémités de la chaîne.
Ørjan Johansen

Vous avez raison. J'ai mal lu les instructions. Merci de l'avoir signalé!
Jeff Freeman

0

Excel, 129 octets

=IFERROR(IF(FIND(B1,A1)=1,SUBSTITUTE(A1,B1,"",1),IF(FIND(B1,A1,LEN(A1)-LEN(B1))>LEN(A1)-LEN(B1),LEFT(A1,LEN(A1)-LEN(B1)),A1)),A1)

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.