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'

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.

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`

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


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

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

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)

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

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


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.


¡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


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

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


2

Raqueta, 70 bytes

Muy claro.

(λ(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}

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


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

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

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


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


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.


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í


0

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

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

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.

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

Hola y bienvenidos a PPCG! ¡Gran respuesta!
NoOneIsHere


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 .


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"

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
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.