Przełącz ciąg

15

Wyzwanie polega na zwykłym przełączaniu łańcucha w innym łańcuchu.

Wyjaśnienie

Jeśli łańcuch przełączający jest podciągiem łańcucha głównego , usuń wszystkie instancje łańcucha przełączającego z łańcucha głównego ; w przeciwnym razie dołącz łańcuch przełączający na końcu łańcucha głównego .

Zasady

  • Wszystkie ciągi znaków składają się z drukowalnych znaków ASCII
  • Funkcja powinna przyjmować dwa parametry: ciąg główny i ciąg przełączający .
  • Główny ciąg może być pusta.
  • Ciąg przełącznik nie może być pusta.
  • Wynik powinien być ciągiem, który może być pusty.
  • Najkrótsza odpowiedź wygrywa.

Przykłady

function toggle(main_string, toggle_string){ ... }

toggle('this string has 6 words ', 'now') 
=> 'this string has 6 words now'

toggle('this string has 5 words now', ' now') 
=> 'this string has 5 words'

Testuje przypadki

'','a'          => 'a'
'a','a'         => ''

'b','a'         => 'ba'
'ab','a'        => 'b'

'aba','a'       => 'b'
'ababa', 'aba'  => 'ba'
nobe4
źródło
2
@KennyLau To było w piaskownicy przez wszystkie 3 godziny. Zalecenie to 2 dni.
Morgan Thrapp,
9
Zalecenia to w rzeczywistości 72 godziny . Strona główna ma znacznie lepszą widoczność niż piaskownica, więc zagwarantowano tu więcej komentarzy. To powiedziawszy, nie jest to złe wyzwanie, ma tylko kilka szorstkich krawędzi.
AdmBorkBork
2
Więc zastępujesz wszystkie nie nakładające się wystąpienia?
Suever,
1
@Jakube Tak, powinienem ograniczyć to do liter i cyfr.
nobe4
1
Nie, myślę, że zezwalaj na niealfanumeryczne: w ten sposób jest to trudniejsze.
msh210

Odpowiedzi:

5

Galaretka , 7 bajtów

œṣȮ⁸e⁹ẋ

Wypróbuj online!

Jak to działa

œṣȮ⁸e⁹ẋ  Main link. Arguments: s (string), t (toggle string)

œṣ       Split s at occurrences of t.
  Ȯ      Print the result.
   ⁸e    Check if s occurs in the split s. Yields 1 (true) or 0 (false).
     ⁹ẋ  Repeat t that many times.
Dennis
źródło
11

Java 8, 80 70 65 34 bajtów

t->m->m==(m=m.replace(t,""))?m+t:m

Prawdopodobnie mój najkrótszy jak dotąd „codegolf” Java .. xD
z pewną pomocą komentarzy ..;)

Wyjaśnienie:

Wypróbuj online.

t->m->                     // Method with two String parameters and String return-type
                           // (NOTE: Takes the toggle `t` and main `m` in reversed order)
  m==(m=m.replace(t,""))?  //  If `m` equals `m` with all `t`-substrings removed:
                           //  (And set `m` to `m` with all `t`-substrings removed)
   m+t                     //   Output this new `m` concatted with `t`
  :                        //  Else:
   m                       //   Output just this new `m`
Kevin Cruijssen
źródło
1
Powinieneś być w stanie zaoszczędzić sporo, zmieniając na iftrójskładnikowy. Jeśli nic więcej, pozbędzie się „dodatkowych” return.
Geobity
@Geobits Ah, oczywiście .. Byłem tak entuzjastycznie nastawiony, że pojedyncza metoda miała „niską” liczbę bajtów (w kategoriach „kodegolfingu” java), że zapomniałem jednego z najbardziej oczywistych kodegolfów dla ifs i powraca ..>.> Dzięki, zredagowane.
Kevin Cruijssen
1
Możesz zaoszczędzić jeszcze kilka bajtów, używając lambda zamiast zwykłej funkcji.
Denker
return m=m.replace(t,"")?m+t:m;
Leaky Nun
2
m==(m=m.replace...
Leaky Nun
8

MATL, 11 bajtów

yyXf?''YX}h

Wypróbuj online!

Wszystkie przypadki testowe

Wyjaśnienie

            % Implicitly grab the main string
            % Implicitly grab the toggle string
y           % Copy the main string
y           % Copy the toggle string
Xf          % Check to see if the toggle string is present in the main string
?           % If so
    ''YX    % Replace with an empty string
}           % else
    h       % Horizontally concatenate the two strings
            % Implicit end of if...else
            % Implicitly display the result
Suever
źródło
6

Python 3, 38 bajtów

lambda s,t:(s+t,s.replace(t,""))[t in s]
Hunter VL
źródło
4

JavaScript (ES6), 39 37 bajtów

(s,t,u=s.split(t).join``)=>u==s?s+t:u
Neil
źródło
3

Pyke, 14 bajtów

DX{iIXRk:)i!IJ

Wypróbuj tutaj!

Biorąc pod uwagę, że Pyke nie ma elsestruktury, myślę, że jest to całkiem rozsądny wynik

Wyjaśnienie:

D              -    Duplicate input
 X             -   a,b = ^
  {            -  a in b
   i           - i = ^
    I          - if i:
     XRk:      -  a = b.replace(a,"")
         i!I   - if not i:
            J  -  a = "".join(input)
               - print a
niebieski
źródło
3

CJam, 9

q~:B/2Be]

Wypróbuj online. Dzięki jimmy23013 za odcięcie 1 bajtu :)

Wyjaśnienie:

q~     read and evaluate the input (given as 2 quoted strings)
:B     store the toggle string in B
/      split the main string by the toggle string
2Be]   pad the array of pieces to the right with B, up to length 2 (if shorter)
aditsu zrezygnowało, ponieważ SE jest ZŁEM
źródło
1
9 bajtów: q~:B/2Be].
jimmy23013
2

JavaScript (ECMAScript 6): 47 bajtów

(a,b)=>(c=a.replace(RegExp(b,'g'),''))!=a?c:a+b
nobe4
źródło
5
Może się to nie powieść, jeśli ciąg przełączający zawiera znaki specjalne. Na przykład ("a", ".")zwraca ""zamiast "a.".
Dennis
2

Siatkówka , 38 31 bajtów

Liczba bajtów zakłada kodowanie ISO 8859-1.

(.+)(?=.*¶\1$)
·
1>`·|¶.+

T`·¶

Końcowe podawanie linii jest znaczące. Format wejściowy to oba ciągi znaków oddzielone wierszem.

Wypróbuj online! Pierwszy wiersz pozwala na uruchomienie kilku przypadków testowych jednocześnie (w zestawie testowym użyj ;do oddzielenia ciągów i kanałów do osobnych przypadków testowych; pierwszy wiersz zajmuje się konwersją).

Wyjaśnienie

(.+)(?=.*¶\1$)
·

W tym pierwszym kroku zamieniamy wszystkie wystąpienia ciągu przełączającego w ciągu głównym na ·. Musimy wstawić te znaczniki, abyśmy mogli później ustalić, czy nastąpiła jakaś zamiana.

1>`·|¶.+

Jest to kolejne podstawienie, które usuwa ·marker lub drugą linię (w tym separację linii). Jednak 1>jest granica co oznacza, że pasuje tylko po pierwsze są uznawane. Dlatego jeśli ciąg przełączający nie wystąpił w głównym ciągu, nie wstawilibyśmy żadnego ·, więc druga linia będzie pierwszym dopasowaniem i nie zostanie usunięta. W przeciwnym razie usuwamy drugą linię wraz ze wszystkimi znacznikami oprócz pierwszego.

T`·¶

Chociaż wykorzystuje to etap transliteracji, służy również do usuwania znaków. W szczególności przenosimy oba ·i linie. Potrzebujemy pierwszego, na wypadek, gdyby był mecz (ponieważ wtedy pierwszy ·zostanie pominięty przez poprzedni etap) i potrzebujemy drugiego, na wypadek, gdyby nie było dopasowania (aby połączyć dwie linie razem, a tym samym dodaj ciąg przełączający do ciągu głównego).

Martin Ender
źródło
2

Python (3.4): 55 54 47 44 bajtów

lambda m,t:m.replace(t,'')if t in m else m+t

Testowanie:

toggle=lambda m,t:m.replace(t,'')if t in m else m+t
print('', 'a', toggle('','a'))
print('a', 'a', toggle('a','a'))
print('b', 'a', toggle('b','a'))
print('ab', 'a', toggle('ab','a'))
print('aba', 'a', toggle('aba','a'))
print('ababa', 'aba', toggle('ababa','aba'))

Wyjście testowe

 a a
a a
b a ba
ab a b
aba a b
ababa aba ba

Użycie def byłoby dłuższe, ponieważ musisz użyć instrukcji return, jeśli byłoby to możliwe bez return, zaoszczędziłoby 2 bajty Ponieważ jawna deklaracja funkcji nie jest potrzebna (przepraszam, nie wiedziałem o tym) 7 bajtów zostało zapisanych.

levanth
źródło
Niezła odpowiedź! Zgodnie z naszymi zasadami nie potrzebujesz nazwy funkcji. Możesz więc usunąć toggle=.
Rɪᴋᴇʀ
Właśnie zdałem sobie sprawę, że mój test nie zadziała, jeśli nie podam nazwy funkcji, ale przy toggle=pracy Testy
levanth
tak, togglejest to potrzebne do przetestowania. Ale musisz tylko liczyć od samego początkulambda m,t: .
Rɪᴋᴇʀ
Możesz się zmienić, m+''+taby m+tzapisać 3 bajty, jeśli się nie mylę.
Sherlock9,
Masz rację, zacząłem od m+' '+twpisania spacji między nimi, ale po ponownym przeczytaniu opisu
usunąłem
2

C #, 63

string F(string s,string t)=>s.Contains(t)?s.Replace(t,""):s+t;

Lepsze niż Java :)

Kod testowy:

public static void Main()
{
    Console.WriteLine(F("", "a"));
    Console.WriteLine(F("a", "a"));
    Console.WriteLine(F("b", "a"));
    Console.WriteLine(F("ab", "a"));
    Console.WriteLine(F("aba", "a"));
    Console.WriteLine(F("ababa", "aba"));
    Console.ReadLine();
}

Wynik:

a

ba
b
b
ba
RedLaser
źródło
2

Pyth, 13 11 10 bajtów

?/Qz:Qzk+z

Zestaw testowy.

Format wejściowy: pierwszy ciąg w cudzysłowach, drugi ciąg bez cudzysłowów.

To także 10 bajtów:

?tJcQzsJ+z

Zestaw testowy.

To jest 11 bajtów:

pscQz*!}zQz

Zestaw testowy.

Poprzednie 13-bajtowe rozwiązanie:

?:IQzk+Qz:Qzk

Zestaw testowy.

Leaky Nun
źródło
1
Również 11 bajtów:?}zQ:Qzk+Qz
Niebieski
2

Jolf, 12 bajtów

?=iγρiIE+iIγ

Lub, jeśli musimy dołączyć znaki wrażliwe na wyrażenia regularne:

?=iγρiLeIE+iIγ

Wypróbuj tutaj!

Wyjaśnienie

?=iγρiIE+iIγ    if(i === (γ = i.replace(I, E))) alert(i + I); else alert(γ);
  i                i
 =                   ===
    ρ                          .replace( ,  )
     iI                       i         I 
       E                                   E
   γ                     (γ =                )
?               if(                           )
        +iI                                     alert(i + I);
                                                              else
           γ                                                       alert(γ);
Conor O'Brien
źródło
2

JavaScript (ES6), 37 bajtów

(m,t)=>(w=m.split(t).join``)==m?m+t:w

Nieco krótsza niż odpowiedź @ nobe4, wykorzystując split i join

MayorMonty
źródło
2

Rakieta, 70 bajtów

Całkiem prosto.

(λ(s t)((if(string-contains? s t)string-replace string-append)s t""))
Winny
źródło
2

Scala, 72 70 bajtów

def x(m:String,s:String)={val r=m.replaceAll(s,"");if(r==m)m+s else r}

Tłumacz online: www.tryscala.com

Avis
źródło
1
Witamy w Programowaniu Puzzle i Code Golf! Nie znam Scali, ale myślę, że możesz usunąć przestrzenie wokół if(r==m).
Dennis
Tak, masz rację
Avis
1

Oracle SQL 11.2, 66 bajtów

SELECT DECODE(:1,s,s||:2,s)FROM(SELECT REPLACE(:1,:2)s FROM DUAL);
Jeto
źródło
1

Perl, 37 30 bajtów

{$_=shift;s/\Q@_//g?$_:"$_@_"}

Wyrażenia regularne wewnątrz ciągu przełączającego nie są obliczane z powodu cytowania za pomocą \Q...\E .

sub Fi \Esą usuwane zgodnie z komentarzem msh210.

Nie jest całkowicie wolny od skutków ubocznych z powodu ustawienia $_. Korzystanie ze zmiennej lokalnej będzie kosztowało sześć dodatkowych bajtów:

{my$a=shift;$a=~s/\Q@_//g?$a:"$a@_"}

Z drugiej strony, przy przełączanych parametrach wejściowych można zapisać dwa bajty, używając popzamiast shift(28 bajtów):

{$_=pop;s/\Q@_//g?$_:"$_@_"}

Plik testowy:

#!/usr/bin/env perl

sub F{$_=shift;s/\Q@_//g?$_:"$_@_"}

sub test ($$$) {
  my ($m, $t, $r) = @_;
  my $result = F($m, $t);
  print "F('$m', '$t') -> '$result' ",
    ($result eq $r ? '=OK=' : '<ERROR>'), " '$r'\n";
}
test '', 'a', 'a';
test 'a', 'a', '';
test 'b', 'a', 'ba';
test 'ab', 'a', 'b';
test 'aba', 'a', 'b';
test 'ababa', 'aba', 'ba';
test 'ababa', 'a*', 'ababaa*';
test 'foobar', '.', 'foobar.';
__END__

Wynik testu:

F('', 'a') -> 'a' =OK= 'a'
F('a', 'a') -> '' =OK= ''
F('b', 'a') -> 'ba' =OK= 'ba'
F('ab', 'a') -> 'b' =OK= 'b'
F('aba', 'a') -> 'b' =OK= 'b'
F('ababa', 'aba') -> 'ba' =OK= 'ba'
F('ababa', 'a*') -> 'ababaa*' =OK= 'ababaa*'
F('foobar', '.') -> 'foobar.' =OK= 'foobar.'
Heiko Oberdiek
źródło
perlsub mówi: „Podpis jest częścią ciała podprogramu. Zwykle ciało podprogramu jest po prostu wzmocnionym blokiem kodu”. W ten sposób możesz pominąć sub Fliczbę bajtów. Ponadto powinieneś być w stanie używać popzamiast shift(poprzez odwrócenie kolejności wejść, natch), oszczędzając dwa bajty. (Niesprawdzone). Wreszcie powinieneś być w stanie pominąć \E, oszczędzając dwa kolejne bajty. (Również niesprawdzone.)
msh210
@ msh210 Dzięki, Twoje wskazówki pozwoliły zaoszczędzić siedem bajtów. Nie rozumiem, jak popzamiast shiftpomóc, bo $_powinien być pierwszym argumentem, którego należy unikać $_[1]=~s/.../. Kolejność argumentów wejściowych jest ustalona przez pytanie AFAIK.
Heiko Oberdiek
Kolejność argumentów wejściowych nie jest ustalona przez pytanie afaict.
msh210
1

C # (58 bajtów)

string F(string s,string t)=>s==(s=s.Replace(t,""))?s+t:s;

Używa wbudowanego przydziału, aby zgolić kilka bajtów

Blue0500
źródło
Witaj i witaj w PPCG! Świetny pierwszy post! Nie używam dużo C #, ale nie możesz var s,tczy var s,var tzamiast tego string?
NoOneIsHere
Dzięki! Niestety varmożna go używać tylko w miejscach, w których typ jest znany w czasie kompilacji, więc nie można go używać w podpisach metod. Możesz użyć dynamic, ale jest o 1 dłużej niżstring
Blue0500
Co var F(string s, string t? Można to wywnioskować ...
NoOneIsHere
1

bash + sed, 28 bajtów

sed "s/$2//g;t;s/$/$2/"<<<$1

Skrypt znajduje się w pliku toggle-string.bash, który wywołujemy bash toggle-string.bash mainstring togglestring.

s/$2//g usuwa ciąg przełączający z ciągu głównego

t przeskakuje na koniec, jeśli poprzednie podstawienie zakończyło się powodzeniem (tzn. główny ciąg zawierał łańcuch przełączający)

/$/$2/dodaje ciąg przełączający na końcu ( $), jeśli nie przeskoczyliśmy do końca

bash jest wymagany dla linków

Thiht
źródło
To nie zadziała, jeśli ciąg przełączający zawiera znaki specjalne.
Dennis
0

PowerShell v2 +, 47 bajtów

param($a,$b)(($c=$a-replace$b),"$a$b")[$c-eq$a]

Pobiera dane wejściowe, $a,$ba następnie używa pseudo-trójkowej (... , ...)[...]instrukcji do wykonania instrukcji if / else. Wewnętrzne części są oceniane najpierw w celu utworzenia układu dwóch elementów. 0 oznacza $awszystkie wystąpienia $b -replaced bez niczego, w którym jest przechowywany $c. Pierwszy to tylko połączenie strunowe$a i $b.

Jeśli $cjest -eqrówne $a, co oznacza, że $bnie znaleziono, to jest wartość logiczna $truelub 1, i dlatego wybierany jest pierwszy element tablicy (konkatenacja). W przeciwnym razie jest to wartość logiczna$false , więc wyprowadzamy $c0 element.

Zauważ, że -replacejest chciwy, więc najpierw zastąpi od lewej, co oznacza, że ababa / abaprzypadek testowy zostanie poprawnie zwrócony ba.

AdmBorkBork
źródło
0

Java 8, 65 bajtów

BinaryOperator<String>l=(m,t)->m.contains(t)?m.replace(t,""):m+t;

Ta sama logika, co rozwiązanie Java 7, napisane za pomocą lambda.

Wypróbuj tutaj

nickb
źródło
0

Ruby, 33 bajty 27 bajtów (28, jeśli używasz globalnej podstawienia) zdecydowanie 28 bajtów

->u,v{u[v]?u.gsub(v,''):u+v}
Luis Masuelli
źródło
0

Mathematica, 45 bajtów

If[StringContainsQ@##,StringDelete@##,#<>#2]&

Anonimowa funkcja, która pobiera ciąg główny i ciąg przełączający (w tej kolejności) i zwraca wynik. Wyjaśnienie:

                                            &  Anonymous function returning...

If[StringContainsQ@##,               ,     ]    if its first argument contains
                                                its second argument, then...
                      StringDelete@##            its first argument with its
                                                 second argument removed, else...
                                      #<>#2      its second argument appended to
                                                 its first argument.
LegionMammal978
źródło
0

TSQL, 143 129 121 bajtów

DECLARE @1 VARCHAR(10)='',@2 VARCHAR(10)='a'SELECT CASE WHEN @1 LIKE'%'+@2+'%'THEN REPLACE(@1,@2,'')ELSE CONCAT(@1,@2)END

Czytelny:

   DECLARE @1 VARCHAR(10) = ''
    , @2 VARCHAR(10) = 'a'

SELECT CASE WHEN @1 LIKE '%' + @2 + '%'
            THEN REPLACE(@1, @2, '')
            ELSE CONCAT (@1, @2)
            END

Live Demo

114 bajtów przy wprowadzeniu 1 znaku

DECLARE @1 CHAR(1) = 'a'
    , @2 CHAR(1) = '.'

SELECT CASE WHEN @1 LIKE '%' + @2 + '%'
            THEN REPLACE(@1, @2, '')
            ELSE CONCAT (@1, @2) END
dfundako
źródło
Witaj i witaj w PPCG! Świetna odpowiedź!
NoOneIsHere
0

TSQL (Sqlserver 2012), 49 bajtów

DECLARE @ VARCHAR(10) = 'hello',@x VARCHAR(10) = 'o'

PRINT IIF(@ LIKE'%'+@x+'%',REPLACE(@,@x,''),@+@x)

Wypróbuj online!

t-clausen.dk
źródło
0

Rubin, 35 37 28 bajtów

->m,t{m[t]?m.gsub(t,''):m+t}

Brawo dla interpolacji łańcuchów! Działa nawet w wyrażeniach regularnych. Reszta jest prosta: jeśli ciąg w tmeczach aby mwymienić tz ''Else zamian m+t.

Edycja: Naprawiono błąd.

Edycja: Zastosowałem sugestię Kevina Laua, ale wygląda na to, że osiągnąłem ten sam algorytm, który zastosowano w odpowiedzi Luisa Masuelliego .

Sherlock9
źródło
Może się to nie powieść, jeśli ciąg przełączający zawiera znaki specjalne. Na przykład ("a", ".")zwraca "a"zamiast "a.".
Dennis
m[t]jest znacznie krótszy niż m.include?(t)i nadal sprawdza włączenie w ciągi znaków.
Wartość tuszu
0

k (23 bajty)

{$[#x ss y;,/y\:x;x,y]}

Przykłady:

k){$[#x ss y;,/y\:x;x,y]}["aba";"a"]
,"b"
k){$[#x ss y;,/y\:x;x,y]}["this string has 6 words ";"now"]
"this string has 6 words now"
k){$[#x ss y;,/y\:x;x,y]}["this string has 5 words now";"now"]
"this string has 5 words "
k){$[#x ss y;,/y\:x;x,y]}["ababa";"ba"]
,"a"
k){$[#x ss y;,/y\:x;x,y]}["";"a"]
,"a"
skeevey
źródło
0

Kotlin, 61 bajtów

{m:String,t:String->var n=m.replace(t,"");if(m==n)m+t else n}

Byłoby to krótsze, gdyby przypisanie było wyrażeniem w Kotlinie, a parametry były zmienne, a byłby trójskładnikowy operator warunkowy, niestety tak nie jest :(

Wypróbuj online!

UnGolfed

fun t(m:String, t:String):String{
    var n=m.replace(t, "")
    return if(m==n)m+t else n
}
The_Lone_Devil
źródło