Alternar uma sequência

15

O desafio envolve simplesmente alternar uma string dentro de outra.

Explicação

Se a seqüência de alternância é uma substring da corda principal , remova todas as ocorrências da seqüência de alternância da corda principal ; caso contrário, anexe a string de alternância no final da string principal .

Regras

  • Todas as strings são compostas por caracteres ASCII imprimíveis
  • A função deve ter dois parâmetros: a sequência principal e a sequência de alternância .
  • A cadeia principal pode estar vazia.
  • A cadeia de alternância não pode estar vazia.
  • O resultado deve ser uma sequência, que pode estar vazia.
  • A resposta mais curta vence.

Exemplos

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'

Casos de testes

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

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

'aba','a'       => 'b'
'ababa', 'aba'  => 'ba'
nobe4
fonte
2
@KennyLau Ele ficou na caixa de areia por todas as 3 horas. A recomendação é de 2 dias.
Morgan Thrapp
9
A recomendação é na verdade 72 horas . A página principal tem muito mais visibilidade que o Sandbox, portanto, mais comentários são garantidos aqui. Dito isto, este não é um mau desafio, apenas tem algumas arestas.
AdmBorkBork 20/05
2
Então você substitui todas as instâncias não sobrepostas ?
Suever 20/05
1
@Jakube Sim, devo limitar isso a letras e números que eu acho.
nobe4
1
Não, acho que permitir não-alfanuméricos: é mais desafiador assim.
Msh210 22/05

Respostas:

5

Geléia , 7 bytes

œṣȮ⁸e⁹ẋ

Experimente online!

Como funciona

œṣȮ⁸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
fonte
11

Java 8, 80 70 65 34 bytes

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

Provavelmente o meu 'codegolf' Java mais curto até agora .. xD
com alguma ajuda dos comentários ..;)

Explicação:

Experimente 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
fonte
1
Você deve conseguir economizar alguns, alterando ifpara um ternário. Se nada mais, ele vai se livrar do "extra" return.
Geobits 20/05
@ Geobits Ah, é claro. Fiquei tão entusiasmado que um único método tinha uma contagem de bytes 'baixa' (em termos de 'codegolfing' em java) que esqueci um dos codegolfing mais óbvios para ifs e retornos ..>.> Obrigado, editado.
Kevin Cruijssen
1
Você pode salvar mais alguns bytes usando uma lambda em vez de uma função regular.
Denker 20/05
return m=m.replace(t,"")?m+t:m;
Freira vazando 20/05
2
m==(m=m.replace...
Freira vazando
8

MATL, 11 bytes

yyXf?''YX}h

Experimente Online!

Todos os casos de teste

Explicação

            % 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
fonte
6

Python 3, 38 bytes

lambda s,t:(s+t,s.replace(t,""))[t in s]
Hunter VL
fonte
4

JavaScript (ES6), 39 37 bytes

(s,t,u=s.split(t).join``)=>u==s?s+t:u
Neil
fonte
3

Pyke, 14 bytes

DX{iIXRk:)i!IJ

Experimente aqui!

Dado que Pyke não tem elseestrutura, acho que essa é uma pontuação bastante razoável

Explicação:

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
Azul
fonte
3

CJam, 9

q~:B/2Be]

Experimente online. Obrigado jimmy23013 por cortar 1 byte :)

Explicação:

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
fonte
1
9 bytes: q~:B/2Be].
Jimmy23013
2

Javascript (ECMAScript 6): 47 bytes

(a,b)=>(c=a.replace(RegExp(b,'g'),''))!=a?c:a+b
nobe4
fonte
5
This can fail if the toggle string contains special characters. For example, ("a", ".") returns "" instead of "a.".
Dennis
2

Retina, 38 31 bytes

Byte count assumes ISO 8859-1 encoding.

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

T`·¶

The trailing linefeed is significant. Input format is both strings separated with a linefeed.

Try it online! The first line allows running several test cases at once (for the test suite, use ; to separate the strings and linefeeds to separate test cases; the first line takes care of the conversion).

Explanation

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

In this first step we replace all occurrences of the toggle string in the main string with ·. We need to insert these markers so that we can determine afterwards if any substitution happened.

1>`·|¶.+

This is another substitution which removes a · marker, or the second line (including the separating linefeed). However, the 1> is a limit which means that only matches after the first are considered. Hence, if the toggle string did not occur in the main string, we won't have inserted any ·, so the second line will be the first match and won't be removed. Otherwise, we remove the second line along with all but the first marker.

T`·¶

While this uses a transliteration stage, it's also used simply for removing characters. In particular, we move both · and linefeeds. We need the first one, in case there was a match (because then the first · will have been left behind by the previous stage) and we need the second one in case there wasn't a match (to join the two lines together and thereby append the toggle string to the main string).

Martin Ender
fonte
2

Python (3.4): 55 54 47 44 Bytes

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

Testing:

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

The Test output

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

Using a def would be longer because you have to use a return statement, if it were possible without return it would save 2 Bytes Since explicit declaration of the function is not needed (sorry I didn't know that) 7 Bytes were saved.

levanth
fonte
Nice answer! For our rules, you don't need a name for the function. So you can remove the toggle=.
Rɪᴋᴇʀ
I just realized, my Test won't work if I don't name the function, but with the toggle= the Tests work
levanth
yes, the toggle is needed to test it. But you only need to count from lambda m,t: on.
Rɪᴋᴇʀ
You can change m+''+t to m+t to save 3 bytes, if I'm not mistaken.
Sherlock9
You're right, I started with m+' '+t to enter a space between them, but after reading the description again I deleted the whitespace but not the '' and the +
levanth
2

C#, 63

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

Better than Java :)

Test code:

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

Output:

a

ba
b
b
ba
RedLaser
fonte
2

Pyth, 13 11 10 bytes

?/Qz:Qzk+z

Test suite.

Input format: first string in quotes, second string without quotes.

This is also 10 bytes:

?tJcQzsJ+z

Test suite.

This is 11 bytes:

pscQz*!}zQz

Test suite.

Previous 13-byte solution:

?:IQzk+Qz:Qzk

Test suite.

Leaky Nun
fonte
1
Também 11 bytes:?}zQ:Qzk+Qz
Azul
2

Jolf, 12 bytes

?=iγρiIE+iIγ

Ou, se precisarmos incluir caracteres sensíveis a expressões regulares:

?=iγρiLeIE+iIγ

Experimente aqui!

Explicação

?=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
fonte
2

JavaScript (ES6), 37 bytes

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

Um pouco menor do que a resposta do @ nobe4, aproveitando a divisão e a junção

MayorMonty
fonte
2

Raquete, 70 bytes

Bem direto.

(λ(s t)((if(string-contains? s t)string-replace string-append)s t""))
Winny
fonte
2

Scala, 72 70 bytes

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

Online interpreter: www.tryscala.com

Avis
fonte
1
Welcome to Programming Puzzles & Code Golf! I don't know Scala, but I think you can remove the spaces around if(r==m).
Dennis
Sim, você está certo #
214 Avis
1

Oracle SQL 11.2, 66 bytes

SELECT DECODE(:1,s,s||:2,s)FROM(SELECT REPLACE(:1,:2)s FROM DUAL);
Jeto
fonte
1

Perl, 37 30 bytes

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

Expressões regulares dentro da cadeia de alternância não são avaliadas devido à citação com \Q...\E .

sub Fe \Esão removidos de acordo com o comentário por msh210.

Não é totalmente livre de efeitos colaterais por causa da configuração $_. O uso de uma variável local custará seis bytes adicionais:

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

Por outro lado, com os parâmetros de entrada comutados, dois bytes podem ser salvos usando em popvez de shift(28 bytes):

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

Arquivo de teste:

#!/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__

Resultado do teste:

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
fonte
perlsub says "The signature is part of a subroutine's body. Normally the body of a subroutine is simply a braced block of code." Thus, you can omit sub F from your byte count. Also, you should be able to use pop instead of shift (by reversing the order of the inputs, natch), saving two bytes. (Untested.) Finally, you should be able to omit the \E, saving two more bytes. (Also untested.)
msh210
@msh210 Thanks, your tips saved seven bytes. I do not see, how pop instead of shift can help, because $_ should be the first argument to avoid $_[1]=~s/.../. The order of input arguments is fixed by the question AFAIK.
Heiko Oberdiek
The order of input arguments is not fixed by the question afaict.
msh210
1

C# (58 bytes)

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

It uses an inline assignment to shave a few bytes off

Blue0500
fonte
Hello, and welcome to PPCG! Great first post! I don't use C# much, but can't you do var s,t or var s,var t instead of string?
NoOneIsHere
Thanks! Sadly var can only be used in places where the type is known at compile time, so it can't be used in method signatures. You could use dynamic, but it's 1 character longer that string
Blue0500
What about var F(string s, string t? That can be inferred...
NoOneIsHere
1

bash + sed, 28 bytes

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

The script lives in a toggle-string.bash file, which we call with bash toggle-string.bash mainstring togglestring.

s/$2//g removes the toggle string from the main string

t jumps to the end if the previous substitution was successful (ie. the main string contained the toggle string)

/$/$2/ adds the toggle string at the end ($), if we didn't jump to the end

bash is required for the herestring

Thiht
fonte
This won't work if the toggle string contains special characters.
Dennis
0

PowerShell v2+, 47 bytes

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

Takes input $a,$b and then uses a pseudo-ternary (... , ...)[...] statement to perform an if/else. The inner parts are evaluated first to form an array of two elements. The 0th is $a with all occurrences of $b -replaced with nothing, which is stored into $c. The 1st is just a string concatenation of $a and $b.

If $c is -equal to $a, meaning that $b wasn't found, that's Boolean $true or 1, and so the 1st element of the array (the concatenation) is chosen. Else, it's Boolean $false, so we output $c, the 0th element.

Note that -replace is greedy, so it will replace from the left first, meaning the ababa / aba test case will properly return ba.

AdmBorkBork
fonte
0

Java 8, 65 bytes

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

The same logic as the Java 7 solution, written with a lambda.

Try it here

nickb
fonte
0

Ruby, 33 bytes 27 bytes (28 if using global subtitution) definitely 28 bytes

->u,v{u[v]?u.gsub(v,''):u+v}
Luis Masuelli
fonte
0

Mathematica, 45 bytes

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

Anonymous function that takes the main string and the toggle string (in that order) and returns the result. Explanation:

                                            &  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
fonte
0

TSQL, 143 129 121 Bytes

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

Readable:

   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 Bytes with strictly 1 character input

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

SELECT CASE WHEN @1 LIKE '%' + @2 + '%'
            THEN REPLACE(@1, @2, '')
            ELSE CONCAT (@1, @2) END
dfundako
fonte
Hello, and welcome to PPCG! Great answer!
NoOneIsHere
0

TSQL(Sqlserver 2012), 49 bytes

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

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

Try it online!

t-clausen.dk
fonte
0

Ruby, 35 37 28 bytes

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

Hooray for string interpolation! It even works in regexes. The rest is simple: if the string in t matches to m, replace t with '', else return m+t.

Edit: Fixed a bug.

Edit: I applied Kevin Lau's suggestion, but it appears that I have reached the same algorithm as the one used in Luis Masuelli's answer.

Sherlock9
fonte
This can fail if the toggle string contains special characters. For example, ("a", ".") returns "a" instead of "a.".
Dennis
m[t] is much shorter than m.include?(t) and still checks for inclusion within strings.
Value Ink
0

k (23 bytes)

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

Examples:

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
fonte
0

Kotlin, 61 Bytes

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

This is would be shorter if assignment was an expression in Kotlin,and parameters were mutable,and there was a ternary conditional operator, sadly this isn't the case :(

Try it 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
fonte