Переключить строку

15

Задача состоит в том, чтобы просто переключить строку внутри другой строки.

объяснение

Если строка переключения является подстрокой основной строки , удалите все экземпляры строки переключения из основной строки ; в противном случае добавьте строку переключения в конец основной строки .

правила

  • Все строки состоят из печатных символов ASCII
  • Функция должна принимать два параметра: основную строку и строку переключения .
  • Основная строка может быть пустой.
  • Строка переключения не может быть пустым.
  • Результатом должна быть строка, которая может быть пустой.
  • Самый короткий ответ выигрывает.

Примеры

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'

Тесты кейсы

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

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

'aba','a'       => 'b'
'ababa', 'aba'  => 'ba'
nobe4
источник
2
@KennyLau Это было в песочнице в течение всех 3 часов. Рекомендация 2 дня.
Морган Трепп
9
Рекомендация на самом деле 72 часа . Главная страница имеет гораздо большую видимость, чем песочница, поэтому здесь больше комментариев гарантировано. Тем не менее, это не плохая задача, просто имеет несколько грубых краев.
AdmBorkBork
2
Таким образом, вы заменяете все непересекающиеся экземпляры?
Suever
1
@Jakube Да, я должен ограничить это буквами и цифрами, я думаю.
nobe4
1
Нет, я думаю разрешить не алфавитно-цифровые: это более сложный способ.
msh210

Ответы:

5

Желе , 7 байт

œṣȮ⁸e⁹ẋ

Попробуйте онлайн!

Как это устроено

œṣȮ⁸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 байта

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

Вероятно, мой самый короткий Java 'codegolf' до сих пор .. xD
с некоторой помощью из комментариев ..;)

Объяснение:

Попробуйте онлайн.

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
Вы должны быть в состоянии сохранить довольно много, изменив на ifтроичный. Если ничего другого, он избавится от «лишнего» return.
Geobits
@Geobits Ах, конечно .. Я был настолько полон энтузиазма, что у одного метода было «низкое» количество байтов (с точки зрения java «codegolfing»), что я забыл одно из самых очевидных codegolfing для ifs и return ..>.> Спасибо, отредактировал.
Кевин Круйссен
1
Вы можете сохранить еще несколько байтов, используя лямбду вместо обычной функции.
Денкер
return m=m.replace(t,"")?m+t:m;
Утренняя монахиня
2
m==(m=m.replace...
Утренняя монахиня
8

MATL, 11 байт

yyXf?''YX}h

Попробуйте онлайн!

Все тесты

объяснение

            % 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
источник
6

Python 3, 38 байт

lambda s,t:(s+t,s.replace(t,""))[t in s]
Охотник В.Л.
источник
4

JavaScript (ES6), 39 37 байт

(s,t,u=s.split(t).join``)=>u==s?s+t:u
Нил
источник
3

Пайк, 14 байт

DX{iIXRk:)i!IJ

Попробуй это здесь!

Учитывая, что Пайк не имеет elseструктуры, я думаю, что это довольно разумный результат

Объяснение:

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]

Попробуйте онлайн. Спасибо jimmy23013 за обрезание 1 байта :)

Объяснение:

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
источник
1
9 байт: q~:B/2Be].
jimmy23013
2

Javascript (ECMAScript 6): 47 байт

(a,b)=>(c=a.replace(RegExp(b,'g'),''))!=a?c:a+b
nobe4
источник
5
Это может не сработать, если строка переключения содержит специальные символы. Например, ("a", ".")возвращает ""вместо "a.".
Деннис
2

Retina , 38 31 байт

Количество байтов предполагает кодировку ISO 8859-1.

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

T`·¶

Конечный перевод строки значителен. Формат ввода - обе строки, разделенные переводом строки.

Попробуйте онлайн! Первая строка позволяет запускать несколько тестовых случаев одновременно (для набора тестов используйте ;для разделения строк и перевода строки для разделения тестовых случаев; первая строка заботится о преобразовании).

объяснение

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

На этом первом шаге мы заменяем все вхождения строки переключения в основной строке на ·. Нам нужно вставить эти маркеры, чтобы впоследствии мы могли определить, произошла ли какая-либо замена.

1>`·|¶.+

Это еще одна замена, которая удаляет ·маркер или вторую строку (включая разделительный перевод строки). Однако 1>это предел, который означает, что рассматриваются только совпадения после первого. Следовательно, если строка переключения не встречается в основной строке, мы не вставим ни одной ·, поэтому вторая строка будет первым совпадением и не будет удалена. В противном случае мы удаляем вторую строку вместе со всеми, кроме первого маркера.

T`·¶

Хотя здесь используется этап транслитерации, он также используется просто для удаления символов. В частности, мы перемещаем как ·и перевод строки. Нам нужен первый, в случае, если было совпадение (потому что тогда первый ·будет оставлен на предыдущем этапе), и нам нужен второй в случае, если не было совпадения (чтобы объединить две строки и тем самым добавить строку переключения к основной строке).

Мартин Эндер
источник
2

Python (3,4): 55 54 47 44 байт

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

Тестирование:

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

Тестовый вывод

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

Использование def было бы длиннее, потому что вы должны использовать оператор return, если бы это было возможно без возврата, это сэкономило бы 2 байта, поскольку явное объявление функции не требуется (извините, я этого не знал) 7 байтов были сохранены.

levanth
источник
Хороший ответ! Для наших правил вам не нужно имя для функции. Таким образом, вы можете удалить toggle=.
Rɪᴋᴇʀ
Я только что понял, что мой Тест не будет работать, если я не toggle=
назову
да, toggleэто нужно для проверки. Но вам только нужно рассчитывать с lambda m,t:на.
Rɪᴋᴇʀ
Вы можете изменить, m+''+tчтобы m+tсохранить 3 байта, если я не ошибаюсь.
Sherlock9
Вы правы, я начал с m+' '+tввода пробела между ними, но после прочтения описания снова удалил пробел, но не '' и +
levanth
2

C #, 63

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

Лучше чем Java :)

Тестовый код:

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

Выход:

a

ba
b
b
ba
RedLaser
источник
2

Pyth, 13 11 10 байт

?/Qz:Qzk+z

Тестирование.

Формат ввода: первая строка в кавычках, вторая строка без кавычек.

Это также 10 байтов:

?tJcQzsJ+z

Тестирование.

Это 11 байт:

pscQz*!}zQz

Тестирование.

Предыдущее 13-байтовое решение:

?:IQzk+Qz:Qzk

Тестирование.

Дрянная Монахиня
источник
1
Также 11 байтов:?}zQ:Qzk+Qz
Голубой
2

Джольф, 12 байт

?=iγρiIE+iIγ

Или, если мы должны включить регулярные выражения:

?=iγρiLeIE+iIγ

Попробуй это здесь!

объяснение

?=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 байт

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

Чуть короче, чем ответ @ nobe4, используя преимущества разделения и объединения

MayorMonty
источник
2

Ракетка, 70 байт

Довольно прямо вперед.

(λ(s t)((if(string-contains? s t)string-replace string-append)s t""))
Winny
источник
2

Scala, 72 70 байт

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

Онлайн переводчик: www.tryscala.com

Avis
источник
1
Добро пожаловать в Программирование Пазлов и Code Golf! Я не знаю, Scala, но я думаю, что вы можете удалить пробелы вокруг if(r==m).
Деннис
Да, вы правы
Авис
1

Oracle SQL 11.2, 66 байт

SELECT DECODE(:1,s,s||:2,s)FROM(SELECT REPLACE(:1,:2)s FROM DUAL);
школа для водителей
источник
1

Perl, 37 30 байт

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

Регулярные выражения внутри строки переключения не оцениваются из-за цитирования с \Q...\E .

sub Fи \Eудалены согласно комментарию msh210.

Это не совсем без побочных эффектов из-за настройки $_. Использование локальной переменной будет стоить шесть дополнительных байтов:

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

С другой стороны, с переключенными входными параметрами можно сохранить два байта, используя popвместо shift(28 байтов):

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

Тестовый файл:

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

Результат испытаний:

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 говорит: «Подпись является частью тела подпрограммы. Обычно тело подпрограммы - это просто блок кода в скобках». Таким образом, вы можете опустить sub Fсвой счетчик байтов. Кроме того, вы должны иметь возможность использовать popвместо shift(путем изменения порядка ввода, natch) сохранение двух байтов. (Не проверено.) Наконец, вы сможете опустить \E, сохранив еще два байта. (Также не проверено.)
msh210
@ msh210 Спасибо, ваши советы сохранили семь байтов. Я не вижу, как popвместо того, чтобы shiftпомочь, потому что $_должен быть первый аргумент, чтобы избежать $_[1]=~s/.../. Порядок входных аргументов фиксируется вопросом AFAIK.
Хайко Обердиек
Порядок входных аргументов не фиксируется вопросом afaict.
msh210
1

C # (58 байт)

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

Он использует встроенное назначение, чтобы сбрить несколько байтов

Blue0500
источник
Здравствуйте и добро пожаловать в PPCG! Отличный первый пост! Я не использую C # много, но вы не можете сделать var s,tили var s,var tвместо string?
NoOneIsHere
Благодарность! К сожалению, его varможно использовать только в тех местах, где тип известен во время компиляции, поэтому его нельзя использовать в сигнатурах методов. Вы можете использовать dynamic, но это на 1 символ длиннее, чемstring
Blue0500
Как насчет var F(string s, string t? Это можно сделать вывод ...
NoOneIsHere
1

bash + sed, 28 байт

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

Сценарий находится в файле toggle-string.bash, который мы вызываем bash toggle-string.bash mainstring togglestring.

s/$2//g удаляет строку переключения из основной строки

t переходит в конец, если предыдущая подстановка прошла успешно (т. е. основная строка содержала строку переключения)

/$/$2/добавляет строку переключения в конец ( $), если мы не прыгали до конца

bash требуется для herestring

Thiht
источник
Это не будет работать, если строка переключения содержит специальные символы.
Деннис
0

PowerShell v2 +, 47 байт

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

Принимает ввод $a,$bи затем использует псевдо-троичный (... , ...)[...]оператор для выполнения if / else. Внутренние части оцениваются первыми, чтобы сформировать массив из двух элементов. 0-й - для $aвсех вхождений $b -replaced, в которых ничего не хранится $c. 1-й это просто последовательность строк $aи$b .

Если $cэто -eqUAL к $a, что означает , что $bне было установлено, что это Логическое $trueили 1, и поэтому выбирается первый элемент массива (конкатенации). Иначе, это логическое значение $false, поэтому мы выводим$c выводим 0-й элемент.

Обратите внимание, что -replaceон жадный, поэтому сначала он будет заменен слева, что означает, что ababa / abaконтрольный пример вернется правильно ba.

AdmBorkBork
источник
0

Java 8, 65 байт

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

Та же логика, что и у решения Java 7, написанного с помощью лямбды.

Попробуй здесь

nickb
источник
0

Ruby, 33 байта 27 байтов (28 при использовании глобального подстановки) определенно 28 байтов

->u,v{u[v]?u.gsub(v,''):u+v}
Луис Масуэлли
источник
0

Mathematica, 45 байт

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

Анонимная функция, которая принимает основную строку и строку переключения (в указанном порядке) и возвращает результат. Объяснение:

                                            &  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
источник
0

TSQL, 143 129 121 байт

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

Удобочитаемый:

   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 байт со строго введенным символом

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

SELECT CASE WHEN @1 LIKE '%' + @2 + '%'
            THEN REPLACE(@1, @2, '')
            ELSE CONCAT (@1, @2) END
dfundako
источник
Здравствуйте и добро пожаловать в PPCG! Отличный ответ!
NoOneIsHere
0

Рубин, 35 37 28 байт

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

Ура для интерполяции строк! Это даже работает в регулярных выражениях. Все остальное просто: если строка tсоответствует m, заменить tна'' , иначе вернуть m+t.

Редактировать: Исправлена ​​ошибка.

Изменить: я применил предложение Кевина Лау, но, похоже, я достиг того же алгоритма, который использовался в ответе Луиса Масуэлли .

Sherlock9
источник
Это может не сработать, если строка переключения содержит специальные символы. Например, ("a", ".")возвращает "a"вместо "a.".
Деннис
m[t]намного короче m.include?(t)и все еще проверяет наличие в строках.
Value Ink
0

к (23 байта)

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

Примеры:

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
источник
0

Котлин, 61 байт

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

Это было бы короче, если бы присваивание было выражением в Kotlin, а параметры были изменяемыми, и был троичный условный оператор, к сожалению, это не так :(

Попробуйте онлайн!

UnGolfed

fun t(m:String, t:String):String{
    var n=m.replace(t, "")
    return if(m==n)m+t else n
}
The_Lone_Devil
источник