Extraire une chaîne d'une chaîne donnée

17

Vous obtenez une chaîne et deux caractères. Vous devez imprimer la chaîne entre ces caractères à partir de la chaîne.

Contribution

L'entrée contiendra d'abord une chaîne (non vide ou null). Dans la ligne suivante, il y aura deux caractères séparés par un espace.

Défi

Renvoie la chaîne entre les deux caractères

Exemple

Hello! What's your name?
! ?

devrait entraîner la sortie:

" What's your name"

Règles

  • La chaîne ne dépassera pas 100 caractères et ne contiendra que des caractères ASCII dans la plage (espace) à ~(tilde) (codes de caractères 0x20 à 0x7E, inclus). Voir le tableau ASCII pour référence.
  • Vous devez prendre connaissance de stdin(ou de l'alternative la plus proche).
  • La sortie doit être entourée de guillemets ( ").
  • Vous pouvez écrire un programme complet ou une fonction qui prend en entrée et sort la chaîne finale
  • Les deux caractères ne contiendront que des caractères ASCII dans la plage (espace) à ~(tilde) (codes de caractères 0x20 à 0x7E, inclus). Voir le tableau ASCII pour référence.
  • Il n'y a aucune garantie que les deux caractères seront dans la chaîne.
  • Si aucun des caractères n'est trouvé dans la chaîne, imprimez "null".
  • Si l'un des caractères est trouvé plusieurs fois (sauf si les deux caractères sont identiques) dans une chaîne, imprimez "null".
  • Si les deux caractères sont le même caractère, imprimez la chaîne "null".

Cas de test

1)

<HTML>code</HTML>
> <                       --> "null"

2)

What's what?
' '                       --> "null"

3)

abcdefghijklmnopqrstuvwxyz
n k                       --> "lm"

4)

Testing...
e T                       --> ""

5)

Last test-case
  -                       --> "test"

Notation

Il s'agit du code golf, donc la soumission la plus courte (en octets) l'emporte.

Spikatrix
la source
3
Les caractères peuvent-ils apparaître dans l'ordre inverse de la chaîne? Si oui, cela pourrait utiliser un cas de test.
Martin Ender
1
Et si la sous-chaîne contient un "? Faut-il simplement l'entourer d'une autre paire de citations et ne pas s'en soucier?
jimmy23013
@ MartinBüttner, oui. Voir le cas de test édité 3. Merci de me le rappeler
Spikatrix
@ user23013, oui. Exemple d'entrée: one"two-three \n" -sortie: "two"( \nest une nouvelle ligne)
Spikatrix
1
Je ne suis pas fan des détails délicats sur les marqueurs n'apparaissant pas ou n'apparaissant pas plusieurs fois. Je pense que le problème serait plus agréable à résoudre avec des garanties plus fortes sur les entrées.
xnor

Réponses:

3

CJam, 34 33 32 octets

'"l_l2%&2*2>NerN/0"null"t_,3=='"

Essayez-le en ligne dans l' interpréteur CJam .

Idée

  1. Supprimez le deuxième caractère de la ligne 2.

  2. Formez une chaîne composée d'une seule copie de tous les caractères communs aux deux lignes.

  3. Répétez la chaîne résultante deux fois et supprimez ses deux premiers caractères.

    Il en résulte une chaîne de deux caractères (si les caractères de la ligne 2 sont différents et se produisent tous les deux à la ligne 1) ou une chaîne vide.

  4. Remplacez les caractères de la chaîne résultante à la ligne 1 par des sauts de ligne.

  5. Séparez la ligne 1 aux sauts de ligne.

    Le deuxième élément du tableau résultant sera la chaîne souhaitée si le tableau contient exactement trois morceaux.

  6. Remplacez le premier élément du tableau par la chaîne null .

  7. Récupérez le deuxième élément du tableau si sa longueur est 3 et le premier sinon.

  8. Ajoutez et ajoutez un guillemet double.

Code

'"       e# Push a double quote.
l_       e# Read one line from STDIN. Push a copy.
l2%      e# Read one line from STDIN. Only keep characters at odd indexes.
&        e# Intersect both strings.
2*2>     e# Repeat the intersection twice and discard the first two characters.
Ner      e# Replace the characters of the resulting string with linefeeds.
N/       e# Split the result at linefeeds.
0"null"t e# Replace the first element of the resulting array with "null".
_,3=     e# Push 1 if the length of the array is 3 and 0 otherwise.
=        e# Retrieve the corresponding element from the array.
'"       e# Push a double quote.
Dennis
la source
2

CJam, 38 octets

l:Tl2%f#_W-$2,=2,@f#$~T<>1>"null"?'"_o

Trop long...

Explication

l:T             e# Read a line and store in T.
l2%             e# Read the two characters into a list.
f#              e# Find each character in the list of two characters.
_W-             e# Copy and remove not found results.
$2,=            e# Sort and check if the result is exactly [0 1].
                e# If true:
2,@f#           e# Find 0 and 1 in the original results.
$               e# Sort.
~T<>            e# Get a slice of T between the two positions (left-closed).
1>              e# Remove the first character.
                e# If false:
"null"          e# The string "null".
?               e# End if.
'"_o            e# Append a quote and output another quote at the beginning.
jimmy23013
la source
2

Pyth, 37 36 34 octets

p?"null"njT9m/zd{J%2wt:z.uSmxzdJNN

Merci à @isaacg pour la sauvegarde de deux octets.

Essayez-le en ligne: Pyth Compiler / Executor

Explication:

                                     implicit: z = first input line
                    w                second input line
                  %2                 only use every 2nd char
                 J                   and store in J
                {J                   set(J), gets rid of duplicates
            m/zd                     count the number of appearances of each char
        njT1                         != [1, 1] ([1,1] is 10 in base 9)
 ?      njT1m/zd{J%2w                ... if [1,1] != number of appearances else ...
  "null"                               string "null"
                           mxzdJ     find the index for each char
                          S          sort the indices
                      :z.u           take the substring of z using these indices
                     t               remove the first char

p                               NN  print '"' + ... + '"'
Jakube
la source
*2]1est plus court que [1 1), et - ... 1est encore plus court.
isaacg
@isaacg -...1ne fonctionne pas, car je dois également vérifier qu'il y a exactement deux nombres.
Jakube
2
Je viens de penser à un moyen de 3 caractères à faire [1 1): jT9.
isaacg
2

Python 3, 149 octets

s,i=input(),input();a,b=s.find(i[0]),s.find(i[2]);print('"'+('null',[s[a+1:b],s[b+1:a]][b<a])[(s.count(i[0])==s.count(i[2])==1)*(a!=b)*(a*b>-1)]+'"')

Version non golfée:

string, chars = input(), input()
a, b = string.find(chars[0]), string.find(chars[2])

    if string.count(chars[0]) == string.count(chars[2]) == 1 and a!=b and a*b>-1:
        if b<a:
            print('"' + string[b+1:a] + '"')
        else:
            print('"' + string[a+1:b] + '"')
else:
    print('"null"')

Ceci est ma première réponse ici, donc les conseils et les critiques sont très appréciés.

TheSidekick
la source
2

Rubis, 108 95 94

->s,f,l{a,b=[f,l].map{|u|(f==l||s.count(u)>1)&&abort('"null"');s.index u}.minmax;p s[a+1...b]}

Et pour la version non golfée

def between(string, first, last)
    left, right = [first, last].map do |substring|
        abort('"null"') if first == last || string.count(substring) != 1
        string.index(substring)
    end.minmax
    p string[left + 1 ... right]
end
Dylan Frese
la source
Pourquoi ne puis-je voir aucune sortie lorsque j'exécute votre code ici ?
Spikatrix
@CoolGuy Il s'agit d'une fonction sans nom, vous devez donc l'appeler comme ceci ->s,f,l{begin a,b=[f,l].map{|u|raise if f==l||s.count(u)>1;s.index u}.minmax;p s[a+1...b];rescue;p'null'end}["<html>test</html>",?>,?<]Le [...]à la fin est ce qui appelle la fonction.
blutorange
@blutorange, ok. Cela a fonctionné, mais comment puis-je tester le dernier cas de test?
Spikatrix
@CoolGuy Utilisez les chaînes normalement citées:->s,f,l{begin a,b=[f,l].map{|u|raise if f==l||s.count(u)>1;s.index u}.minmax;p s[a+1...b];rescue;p'null'end}["Last test-case"," ","-"]
blutorange
Au lieu de générer une erreur avec raise, vous pouvez remplacer raisepar une variable non définie telle que _ou y. Cela déclenche une NameError. Aussi, je pense que vous pourriez économiser quelques octets de plus sans sauvetage explicite:->s,f,l{a,b=[f,l].map{|u|(f==l||s.count(u)!=1)&&p('null')&&exit;s.index u}.minmax;p s[a+1...b]}
blutorange
1

C, 192 octets

f(){char b[101],c,d,*p,*t;scanf("%[^\n]%*c%c%*c%c",b,&c,&d);p=strchr(b,c);t=strchr(b,d);c==d||!p||!t||strchr(p+1,c)||strchr(t+1,d)?puts("\"null\""):printf("\"%s\"",p<t?(*t=0,p+1):(*p=0,t+1));}

Code non golfé:

f()
{
    char b[101],c,d,*p,*t; //Variables

    scanf("%[^\n]%*c%c%*c%c",b,&c,&d); //Scan input

    p=strchr(b,c);
    t=strchr(b,d); //Find occurrence of characters

    c==d         ||  //If both characters are the same
    !p           ||  //If no occurrence of first character found
    !t           ||  //If no occurrence of second character found
    strchr(p+1,c)||  //If two occurrence of first character found
    strchr(t+1,d) ?  //If two occurrence of second character found
    puts("\"null\"") //Print "null"
                  :  //else
    printf("\"%s\"",p<t?(*t=0,p+1):(*p=0,t+1)); //print the string
}

Testez-le ici

Spikatrix
la source
1

Python 3, 172 octets

x=input()
a=input()
a,b=a[0],a[2]
if(a!=b)&(x.count(b)==x.count(a)==1):
 if x.index(a)>x.index(b):q=a;a=b;b=q
 print('"'+x.split(a)[1].split(b)[0]+'"')
else:print('"null"')
Tim
la source
1

Javascript ( ES6 ), 125 123 octets

Idée volée massivement dans la solution de @ edc65.

[a,,b]=(p=prompt)(s=p()),[,c,d,e,,f]=s.split(RegExp('(['+(a+b).replace(/\W/g,'\\$&')+'])'))
p('"'+(!e||f||c==e?null:d)+'"')

nderscore
la source
J'aime surtout [a,,b]=, je l'utiliserai la prochaine fois. Comme les regex sont un problème, voici une solution sans regex:[a,,b]=(P=prompt)(s=P()), P((s=s.split(a)).length==2& (s=[].concat(...s.map(s=>s.split(b)))).length==3 ?``"${s[1]}"``:null)
edc65
(la dernière chaîne est
basée sur des
1

Python, 161 octets

import re,sys
s,p=sys.stdin
m=re.match('[^%s]*([%s])([^%s]*)([%s])[^%s]*$'%((p[0]+p[2],)*5),s)
if m:g=m.group
print'"null"'if not m or g(1)==g(3)else'"'+g(2)+'"'

La solution utilise principalement une expression régulière pour extraire la chaîne. Pour tenir compte du fait que les lettres peuvent correspondre dans les deux sens, le début et la fin de la partie correspondante autorisent l'une ou l'autre lettre. Vérifier que les lettres qui correspondaient réellement à différentes exclut la même lettre étant appariée deux fois, ainsi que les deux lettres dans l'entrée étant identiques.

C'est ma première tentative d'utilisation de Python pour une réponse ici. Les commentaires sur les améliorations possibles sont donc les bienvenus. J'ai particulièrement le sentiment qu'il doit y avoir un moyen de raccourcir la condition dans la déclaration d'impression.

Reto Koradi
la source
1

Python 3, 155 octets

s,n,a,b=[input(),'null']+list(input())[::2];q,w=[s.find(a),s.find(b)];print('"'+{0>1:n,0<1:s[min(q,w)+1:max(q,w)],a==b:n}[s.count(a)==s.count(b)==1]+'"')

Essayez-le en ligne

OrangeHat
la source
1

golflua, 132 octets

L=I.r()I,J=I.r():m("(.) (.)")i=L:f(I)j=L:f(J)K,c=L:g(I,'')_,b=K:g(J,'')?i>j i,j=j,i$w((i==j|c+b!=2)&'"null"'|'"'..L:s(i+1,j-1)..'"')

Réponse assez moche. Le bit d'entrée est un peu approximatif (et nécessite deux lignes, d'abord avec la chaîne et ensuite avec les caractères de tranche). Trouver l'emplacement des drapeaux est simple, mais trop long pour rivaliser avec d'autres réponses. La sortie est assez simple. Un programme Lua équivalent serait

Line1 = io.read()
Line2 = io.read()
I,J = Line2:match("(.) (.)")     -- boobs return the char flags
i = Line1:find(I)                -- find location of flags
j = Line1:find(J)
K,c = Line1:gsub(I,'')           -- replace flag w/ empty & store in K
_,b = K:gsub(J,'')               -- taking K ensures single flags fail
if i > j then i,j=j,i end        -- ensure we start low to high
if i==j or not (c+b == 2) then   -- if i & j are the same or not 2 counts, fail
   print('"null"')
else                             -- print the string otherwise
   print('"'..Line1:sub(i+1,j-1)..'"')
end
Kyle Kanos
la source
Existe-t-il un compilateur en ligne pour tester la version golfée?
Spikatrix
Je ne pense pas qu'il existe une version en ligne, mais le code source est disponible . Il s'agit d'un mappage 1: 1 de Lua (pas une interprétation ou une traduction vers Lua), donc le code Lua peut être testé sur ideone .
Kyle Kanos
0

Perl, 65

#!perl -p0
$.*=s/\Q$1/
/g while s/ ?(.)\z//;/
(.*)
/;$_=$.-1?null:"\"$1\""

Cela nécessite qu'il n'y ait pas de caractère de nouvelle ligne dans la deuxième ligne de l'entrée.

nutki
la source
Bon travail. Cela semble cependant manquer les guillemets doubles.
Dennis
@Dennis, fixe. J'ai mal compris l'exemple.
nutki
1
Il manque toujours les citations de l' nullaffaire.
Dennis