Alternar una cuerda

15

El desafío implica simplemente alternar una cadena dentro de otra cadena.

Explicación

Si la cadena de alternar es una subcadena de la cadena principal , elimine todas las instancias de la cadena de alternar de la cadena principal ; de lo contrario, agregue la cadena de alternar al final de la cadena principal .

Reglas

  • Todas las cadenas están compuestas de caracteres ASCII imprimibles
  • La función debe tomar dos parámetros: la cadena principal y la cadena de alternar .
  • La cadena principal puede estar vacía.
  • La cadena de alternar no puede estar vacía.
  • El resultado debería ser una cadena, que puede estar vacía.
  • La respuesta más corta gana.

Ejemplos

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'

Pruebas de casos

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

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

'aba','a'       => 'b'
'ababa', 'aba'  => 'ba'
nobe4
fuente
2
@KennyLau Estuvo en la caja de arena durante 3 horas. La recomendación es de 2 días.
Morgan Thrapp
99
La recomendación es en realidad 72 horas . La página principal tiene mucha más visibilidad que Sandbox, por lo que se garantizan más comentarios aquí. Dicho esto, este no es un mal desafío, solo tiene algunos bordes ásperos.
AdmBorkBork
2
Entonces, ¿reemplaza todas las instancias no superpuestas ?
Suever
1
@Jakube Sí, creo que debería limitar esto a letras y números.
nobe4
1
No, creo que permitir no alfanuméricos: es más desafiante de esa manera.
msh210

Respuestas:

5

Jalea , 7 bytes

œṣȮ⁸e⁹ẋ

Pruébalo en línea!

Cómo 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
fuente
11

Java 8, 80 70 65 34 bytes

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

Probablemente mi 'codegolf' más corto de Java hasta ahora ... xD
con algo de ayuda de los comentarios ...;)

Explicación:

Pruébalo en línea.

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
fuente
1
Debería poder ahorrar bastantes cambiando el ifa un ternario. Si nada más, eliminará el "extra" return.
Geobits
@Geobits Ah, por supuesto ... Estaba tan entusiasmado que un solo método tenía un conteo de bytes 'bajo' (en términos de 'codegolfing' de Java) que olvidé uno de los codegolfing más obvios para ifs y return ..>.> Gracias, editado.
Kevin Cruijssen
1
Puede guardar algunos bytes más utilizando una lambda en lugar de una función regular.
Denker
return m=m.replace(t,"")?m+t:m;
Leaky Nun
2
m==(m=m.replace...
Leaky Nun
8

MATL, 11 bytes

yyXf?''YX}h

Pruébalo en línea!

Todos los casos de prueba

Explicación

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

Python 3, 38 bytes

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

JavaScript (ES6), 39 37 bytes

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

Pyke, 14 bytes

DX{iIXRk:)i!IJ

Pruébalo aquí!

Dado que Pyke no tiene elseestructura, creo que este es un puntaje bastante razonable

Explicación:

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
fuente
3

CJam, 9

q~:B/2Be]

Pruébalo en línea. Gracias jimmy23013 por cortar 1 byte :)

Explicación:

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
fuente
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
fuente
55
Esto puede fallar si la cadena de alternancia contiene caracteres especiales. Por ejemplo, ("a", ".")devuelve en ""lugar de "a.".
Dennis
2

Retina , 38 31 bytes

El recuento de bytes asume la codificación ISO 8859-1.

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

T`·¶

El avance de línea final es significativo. El formato de entrada es ambas cadenas separadas con un salto de línea.

Pruébalo en línea! La primera línea permite ejecutar varios casos de prueba a la vez (para el conjunto de pruebas, use ;para separar las cadenas y los avances de línea para separar los casos de prueba; la primera línea se encarga de la conversión).

Explicación

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

En este primer paso, reemplazamos todas las apariciones de la cadena de alternar en la cadena principal con ·. Necesitamos insertar estos marcadores para que luego podamos determinar si ocurrió alguna sustitución.

1>`·|¶.+

Esta es otra sustitución que elimina un ·marcador, o la segunda línea (incluido el salto de línea de separación). Sin embargo, 1>es un límite, lo que significa que solo se consideran coincidencias después de la primera. Por lo tanto, si la cadena de alternancia no se produjo en la cadena principal, no habremos insertado ninguna ·, por lo que la segunda línea será la primera coincidencia y no se eliminará. De lo contrario, eliminamos la segunda línea junto con todos menos el primer marcador.

T`·¶

Si bien esto usa una etapa de transliteración, también se usa simplemente para eliminar caracteres. En particular, movemos ambos ·y avances de línea. Necesitamos el primero, en caso de que haya una coincidencia (porque entonces la primera ·habrá quedado atrás en la etapa anterior) y necesitamos el segundo en caso de que no haya una coincidencia (para unir las dos líneas y así agregue la cadena de alternar a la cadena principal).

Martin Ender
fuente
2

Python (3.4): 55 54 47 44 Bytes

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

Pruebas:

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

La salida de prueba

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

Usar un def sería más largo porque tiene que usar una declaración de retorno, si fuera posible sin retorno, ahorraría 2 Bytes Dado que no es necesaria la declaración explícita de la función (lo siento, no lo sabía) Se guardaron 7 Bytes.

levanth
fuente
¡Buena respuesta! Para nuestras reglas, no necesita un nombre para la función. Para que pueda eliminar el toggle=.
Rɪᴋᴇʀ
Me acabo de dar cuenta de que mi prueba no funcionará si no nombro la función, pero con toggle=las pruebas funcionan
nombro
Sí, togglese necesita para probarlo. Pero solo necesitas contar a partir lambda m,t:de ahora.
Rɪᴋᴇʀ
Puede cambiar m+''+ta m+tpara guardar 3 bytes, si no me equivoco.
Sherlock9
Tienes razón, empecé con m+' '+t a ingresar un espacio entre ellos, pero después de leer la descripción nuevamente eliminé el espacio en blanco pero no el '' y el +
levanth
2

C #, 63

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

Mejor que Java :)

Código de prueba:

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

Salida:

a

ba
b
b
ba
RedLaser
fuente
2

Jolf, 12 bytes

?=iγρiIE+iIγ

O, si debemos incluir caracteres sensibles a expresiones regulares:

?=iγρiLeIE+iIγ

Pruébalo aquí!

Explicación

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

JavaScript (ES6), 37 bytes

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

Un poco más corto que la respuesta de @nobe4 aprovechando la división y la unión

AlcaldeMonty
fuente
2

Raqueta, 70 bytes

Muy claro.

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

Scala, 72 70 bytes

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

Intérprete en línea: www.tryscala.com

Avis
fuente
1
¡Bienvenido a Programming Puzzles & Code Golf! No conozco a Scala, pero creo que puedes eliminar los espacios alrededor if(r==m).
Dennis
Sí, tienes razón
Avis
1

Oracle SQL 11.2, 66 bytes

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

Perl, 37 30 bytes

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

Las expresiones regulares dentro de la cadena de alternar no se evalúan debido a las citas con \Q...\E .

sub Fy \Ese eliminan de acuerdo con el comentario de msh210.

No está completamente libre de efectos secundarios debido a la configuración $_. Usar una variable local costará seis bytes adicionales:

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

Por otro lado, con los parámetros de entrada conmutados se pueden guardar dos bytes usando en poplugar de shift(28 bytes):

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

Archivo de prueba:

#!/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 de la prueba:

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
fuente
perlsub dice "La firma es parte del cuerpo de una subrutina. Normalmente, el cuerpo de una subrutina es simplemente un bloque de código entre paréntesis". Por lo tanto, puede omitir sub Fde su recuento de bytes. Además, debería poder usar en poplugar de shift(invirtiendo el orden de las entradas, natch), ahorrando dos bytes. (No probado.) Finalmente, debería poder omitir el \E, guardando dos bytes más. (También no probado.)
msh210
@ msh210 Gracias, sus consejos ahorraron siete bytes. No veo cómo en poplugar de shiftpuede ayudar, porque $_debería ser el primer argumento para evitar $_[1]=~s/.../. El orden de los argumentos de entrada está fijado por la pregunta AFAIK.
Heiko Oberdiek
El orden de los argumentos de entrada no está fijado por la pregunta afaict.
msh210
1

C # (58 bytes)

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

Utiliza una asignación en línea para eliminar algunos bytes

Blue0500
fuente
Hola y bienvenidos a PPCG! Gran primer post! No uso mucho C #, pero ¿no puedes var s,to var s,var tno string?
NoOneIsHere
¡Gracias! Lamentablemente var, solo se puede usar en lugares donde el tipo se conoce en tiempo de compilación, por lo que no se puede usar en firmas de métodos. Podrías usar dynamic, pero es 1 carácter más largo questring
Blue0500
¿Qué hay de var F(string s, string t? Eso se puede inferir ...
NoOneIsHere
1

bash + sed, 28 bytes

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

El script vive en un archivo toggle-string.bash, al que llamamos con bash toggle-string.bash mainstring togglestring .

s/$2//g elimina la cadena de alternar de la cadena principal

t salta al final si la sustitución anterior fue exitosa (es decir, la cadena principal contenía la cadena de alternar)

/$/$2/agrega la cadena de alternar al final ( $), si no saltamos al final

bash es requerido para la herejía

Thiht
fuente
Esto no funcionará si la cadena de alternancia contiene caracteres especiales.
Dennis
0

PowerShell v2 +, 47 bytes

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

Toma entrada $a,$by luego usa una (... , ...)[...]declaración pseudoternaria para realizar un if / else. Las partes internas se evalúan primero para formar una matriz de dos elementos. El 0 es $acon todas las apariciones de $b -replaced sin nada, que se almacena en $c. El primero es solo una concatenación de cadenas de$a y$b .

Si $ces -equal a $a, lo que significa que $bno se encontró, es booleano $trueo 1, por lo que se elige el primer elemento de la matriz (la concatenación). De lo contrario, es booleano$false , así que sacamos$c el elemento 0.

Tenga en cuenta que -replacees codicioso, por lo que se reemplazará desde la izquierda primero, lo que significa que el ababa / abacaso de prueba volverá correctamente ba.

AdmBorkBork
fuente
0

Java 8, 65 bytes

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

La misma lógica que la solución Java 7, escrita con una lambda.

Pruébalo aquí

nickb
fuente
0

Ruby, 33 bytes 27 bytes (28 si usa subtitulación global) definitivamente 28 bytes

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

Mathematica, 45 bytes

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

Función anónima que toma la cadena principal y la cadena de alternar (en ese orden) y devuelve el resultado. Explicación:

                                            &  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
fuente
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

Legible:

   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 con estrictamente entrada de 1 carácter

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

SELECT CASE WHEN @1 LIKE '%' + @2 + '%'
            THEN REPLACE(@1, @2, '')
            ELSE CONCAT (@1, @2) END
dfundako
fuente
Hola y bienvenidos a PPCG! ¡Gran respuesta!
NoOneIsHere
0

TSQL (Sqlserver 2012), 49 bytes

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

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

Pruébalo en línea!

t-clausen.dk
fuente
0

Ruby, 35 37 28 bytes

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

¡Hurra por la interpolación de cuerdas! Incluso funciona en expresiones regulares. El resto es simple: si la cadena tcoincide con m, reemplazar tcon '', de lo contrario devolverm+t .

Editar: se corrigió un error.

Editar: Apliqué la sugerencia de Kevin Lau, pero parece que he alcanzado el mismo algoritmo que el utilizado en la respuesta de Luis Masuelli .

Sherlock9
fuente
Esto puede fallar si la cadena de alternancia contiene caracteres especiales. Por ejemplo, ("a", ".")devuelve en "a"lugar de "a.".
Dennis
m[t]es mucho más corto que m.include?(t)y aún verifica la inclusión dentro de las cadenas.
Value Ink
0

k (23 bytes)

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

Ejemplos:

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

Kotlin, 61 bytes

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

Esto sería más corto si la asignación fuera una expresión en Kotlin, y los parámetros fueran mutables, y hubiera un operador condicional ternario, lamentablemente este no es el caso :(

Pruébalo en línea!

Sin golf

fun t(m:String, t:String):String{
    var n=m.replace(t, "")
    return if(m==n)m+t else n
}
The_Lone_Devil
fuente