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!

Barre
la source
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!)

Okx
la source
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").

ETHproductions
la source
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}.

la source
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>

Hirsute
la source
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.

}
Brad Gilbert b2gills
la source
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
pizzapants184
la source
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"]

J42161217
la source
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

Python, 69 68 64 57 51 45 octets

Cela a fini par être une solution complètement différente avec Regex.

Merci à Value Ink pour -2 octets!
et Felipe Nardi Batista pour l’énorme -6 octets!

import re
lambda s,c:re.sub(c+'$|^'+c,'',s,1)

Essayez-le en ligne!

Artyer
la source
Pour -2 octets:re.sub(c.join("^|$"),'',s,1)
Valeur Ink
1
Pour -6 octets:c+'$|^'+c
Felipe Nardi Batista
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 (% / #)

marcosme
la source
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

Adam
la source
Je pense que vous pouvez économiser un octet avec {0::⍺{0::⍺⋄,∘⍵⍣¯1⊢⍺}⍵⋄⍵,⍣¯1⊢⍺}.
Zacharý
@ Zacharý Oui, merci.
Adám
2

PHP, 54 octets

[,$x,$y]=$argv;echo preg_replace("#^$y|$y$#","",$x,1);

Testcases

Jörg Hülsermann
la source
2

Python 2 , 68 octets

def f(s,c):v=len(c);print[s[v:],s[:-v],s][[s[:v],s[-v:],c].index(c)]

Essayez-le en ligne!

Jonathan Allan
la source
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.

Laikoni
la source
2

Python 2 , 72 65 octets

a,b=input()
l=len(b)
print[[a,a[:-l]][b==a[-l:]],a[l:]][b==a[:l]]

Essayez-le en ligne!

-7 octets grâce à @FelipeNardiBatista

ovs
la source
golfed
Felipe Nardi Batista
@FelipeNardiBatista merci beaucoup!
ovs
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>>.

TheLethalCoder
la source
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.

John Dvorak
la source
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.

Michael Plotke
la source
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"
algmyr
la source
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.

Robert Benson
la source
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!

Giuseppe
la source
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
Renzo
la source
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!

escargot_
la source
? {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:
mazzy
la source
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$
Steenbergh
la source
0

Lua , 71 65 octets

Accepter les suggestions

a,b=...p='(.*)'print(a:match('^'..b..p)or a:match(p..b..'$')or a)

Essayez-le en ligne!

Felipe Nardi Batista
la source
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!

Jeff Freeman
la source
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)
Wernisch
la source