Wyodrębnij ciąg z danego ciągu

17

Otrzymasz ciąg i dwa znaki. Musisz wydrukować ciąg między tymi znakami z ciągu.

Wejście

Dane wejściowe będą najpierw zawierać ciąg znaków (nie pusty lub null). W następnym wierszu będą dwa znaki oddzielone spacją.

Wyzwanie

Zwraca ciąg między dwoma znakami

Przykład

Hello! What's your name?
! ?

powinien dać wynik:

" What's your name"

Zasady

  • Ciąg nie będzie dłuższy niż 100 znaków i będzie zawierać tylko znaki ASCII w zakresie (spacja) do ~(tylda) (kody znaków od 0x20 do 0x7E włącznie). Zobacz tabelę ASCII w celach informacyjnych.
  • Musisz wziąć dane wejściowe z stdin(lub najbliższej alternatywy).
  • Dane wyjściowe powinny być otoczone cudzysłowami ( ").
  • Możesz napisać pełny program lub funkcję, która pobiera dane wejściowe i generuje końcowy ciąg znaków
  • Dwa znaki będą zawierać tylko znaki ASCII w zakresie (spacja) do ~(tylda) (kody znaków od 0x20 do 0x7E włącznie). Zobacz tabelę ASCII w celach informacyjnych.
  • Nie ma gwarancji, że oba znaki będą w ciągu.
  • Jeśli któryś ze znaków nie zostanie znaleziony w ciągu, wydrukuj "null" .
  • Jeśli którykolwiek ze znaków zostanie znaleziony więcej niż jeden raz (chyba że oba znaki są takie same) w ciągu, wydrukuj "null".
  • Jeśli oba znaki są tym samym znakiem, wydrukuj ciąg "null".

Przypadki testowe

1)

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

2)

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

3)

abcdefghijklmnopqrstuvwxyz
n k                       --> "lm"

4)

Testing...
e T                       --> ""

5)

Last test-case
  -                       --> "test"

Punktacja

To jest kod golfowy, więc wygrywa najkrótsze przesłanie (w bajtach).

Spikatrix
źródło
3
Czy znaki mogą występować w przeciwnej kolejności w ciągu? Jeśli tak, to można użyć przypadku testowego.
Martin Ender
1
Co jeśli podciąg zawiera "? Czy powinniśmy otoczyć go inną parą cytatów i nie przejmować się tym?
jimmy23013
@ MartinBüttner, Tak. Zobacz zredagowany przypadek testowy 3. Dziękujemy za przypomnienie mi o tym
Spikatrix
@ user23013, Tak. Przykładowe dane wejściowe: one"two-three \n" -wynik: "two"( \njest
nowym wierszem
1
Nie jestem fanem dziwacznych szczegółów na temat tego, że markery nie pojawiają się ani nie pojawiają się wiele razy. Myślę, że rozwiązanie problemu byłoby przyjemniejsze dzięki silniejszym gwarancjom na wejściach.
xnor

Odpowiedzi:

3

CJam, 34 33 32 bajty

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

Wypróbuj online w interpretatorze CJam .

Pomysł

  1. Usuń drugi znak z wiersza 2.

  2. Utwórz ciąg składający się z pojedynczej kopii wszystkich znaków, które łączą obie linie.

  3. Powtórz powstały ciąg dwa razy i odrzuć pierwsze dwa znaki.

    W wyniku tego powstaje dwuznakowy ciąg (jeśli znaki z wiersza 2 są różne i oba występują w wierszu 1) lub pusty ciąg.

  4. Zastąp znaki wynikowego ciągu w wierszu 1 wierszami wiersza.

  5. Podziel linię 1 przy liniach.

    Drugim elementem tablicy wynikowej będzie pożądany ciąg, jeśli tablica zawiera dokładnie trzy porcje.

  6. Zastąp pierwszy element tablicy ciągiem pustym .

  7. Pobierz drugi element tablicy, jeśli jego długość wynosi 3, a pierwszy w przeciwnym razie.

  8. Dołącz i dołącz podwójny cytat.

Kod

'"       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
źródło
2

CJam, 38 bajtów

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

Za długo...

Wyjaśnienie

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
źródło
2

Pyth, 37 36 34 bajtów

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

Dzięki @isaacg za dwa bajty oszczędzania.

Wypróbuj online: Pyth Compiler / Executor

Wyjaśnienie:

                                     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
źródło
*2]1jest krótszy niż [1 1)i - ... 1jest jeszcze krótszy.
isaacg
@isaacg -...1nie działa, ponieważ muszę również sprawdzić, czy są dokładnie dwie liczby.
Jakube,
2
Pomyślałem o sposób 3 znaków do makijażu [1 1): jT9.
isaacg
2

Python 3, 149 bajtów

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)]+'"')

Wersja bez golfa:

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"')

To jest moja pierwsza odpowiedź tutaj, więc wskazówki i krytyka są bardzo mile widziane.

TheSidekick
źródło
2

Ruby, 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]}

I dla wersji bez golfa

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
źródło
Dlaczego nie widzę żadnych danych wyjściowych po uruchomieniu tutaj kodu ?
Spikatrix
@CoolGuy Jest to funkcja bez nazwy, więc musisz ją tak nazwać. ->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>",?>,?<]Na [...]końcu jest to, co wywołuje funkcję.
blutorange
@blutorange, Ok. Ten rodzaj zadziałał, ale jak mam przetestować ostatni przypadek testowy?
Spikatrix,
@CoolGuy Użyj normalnie cytowanych ciągów:->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
Zamiast zgłaszać błąd raise, możesz zastąpić raiseniezdefiniowaną zmienną, taką jak _lub y. To wywołuje błąd NameError. Myślę też, że można zaoszczędzić jeszcze kilka bajtów bez wyraźnego ratowania:->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 bajty

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));}

Nieskluczony kod:

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
}

Sprawdź to tutaj

Spikatrix
źródło
1

Python 3, 172 bajty

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
źródło
1

JavaScript ( ES6 ), 125 123 bajtów

Pomysł skradziony mocno z rozwiązania @ 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
źródło
Najbardziej podoba [a,,b]=mi się, użyję go następnym razem. Ponieważ wyrażenia regularne są kłopotliwe, oto rozwiązanie wolne od [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)
wyrażeń
(ostatni ciąg jest
wzorowany
1

Python, 161 bajtów

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)+'"'

Rozwiązanie w większości używa po prostu wyrażenia regularnego do wyodrębnienia ciągu. Aby uwzględnić to, że litery mogą być dopasowane w obu kierunkach, początek i koniec dopasowanej części pozwala na dowolną literę. Sprawdzanie, czy litery, które faktycznie pasują do różnych, wyklucza, że ​​ta sama litera jest dopasowywana dwukrotnie, a także dwie litery na wejściu są takie same.

To moja pierwsza próba użycia Pythona do uzyskania odpowiedzi tutaj. Informacje zwrotne dotyczące możliwych ulepszeń są więc bardzo mile widziane. W szczególności mam wrażenie, że musi istnieć sposób, aby warunek w wyciągu drukowanym był krótszy.

Reto Koradi
źródło
1

Python 3, 155 bajtów

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]+'"')

Wypróbuj online

OrangeHat
źródło
1

golflua, 132 bajty

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)..'"')

Całkiem brzydka odpowiedź. Bit wejściowy jest nieco zgrubny (i wymaga dwóch linii, pierwsza z łańcuchem i druga ze znakami plastra). Znalezienie lokalizacji flag jest proste, ale po prostu zbyt długie, aby konkurować z innymi odpowiedziami. Wyjście jest dość łatwe. Równoważny byłby program Lua

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
źródło
Czy jest jakiś kompilator online, który mogę przetestować wersję dla golfistów?
Spikatrix
Nie wierzę, że istnieje wersja online, ale kod źródłowy jest dostępny . Jest to mapowanie Lua 1: 1 (nie interpretacja ani tłumaczenie na Lua), więc kod Lua można przetestować w ideone .
Kyle Kanos
0

Perl, 65

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

Wymaga to, że w drugim wierszu wejścia nie ma znaku nowej linii.

nutki
źródło
Dobra robota. Wydaje się, że brakuje podwójnych cytatów.
Dennis
@Dennis, naprawiono. Źle zrozumiałem przykład.
nutki
1
Wciąż brakuje cytatów dotyczących nullsprawy.
Dennis