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


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'

2
@KennyLau Это было в песочнице в течение всех 3 часов. Рекомендация 2 дня.
Морган Трепп

9
Рекомендация на самом деле 72 часа . Главная страница имеет гораздо большую видимость, чем песочница, поэтому здесь больше комментариев гарантировано. Тем не менее, это не плохая задача, просто имеет несколько грубых краев.
AdmBorkBork

2
Таким образом, вы заменяете все непересекающиеся экземпляры?
Suever

1
@Jakube Да, я должен ограничить это буквами и цифрами, я думаю.
nobe4

1
Нет, я думаю разрешить не алфавитно-цифровые: это более сложный способ.
msh210

Ответы:



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



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)

1
9 байт: q~:B/2Be].
jimmy23013

2

Javascript (ECMAScript 6): 47 байт

(a,b)=>(c=a.replace(RegExp(b,'g'),''))!=a?c:a+b

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


Хороший ответ! Для наших правил вам не нужно имя для функции. Таким образом, вы можете удалить 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

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, используя преимущества разделения и объединения


2

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

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

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

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


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

Да, вы правы
Авис


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;

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


Здравствуйте и добро пожаловать в 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


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


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.


0

Java 8, 65 байт

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

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

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


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.

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

Здравствуйте и добро пожаловать в PPCG! Отличный ответ!
NoOneIsHere


0

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

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

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

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

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


Это может не сработать, если строка переключения содержит специальные символы. Например, ("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"

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
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.