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'

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.

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`

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

6

Python 3, 38 bytes

lambda s,t:(s+t,s.replace(t,""))[t in s]

4

JavaScript (ES6), 39 37 bytes

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

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

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)

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

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


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.


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


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

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


2

Raquete, 70 bytes

Bem direto.

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

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


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

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

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


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


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.


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


0

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

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

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.

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

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!


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.


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"

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
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.