Учитывая одну строку, которая состоит только из букв, обработайте следующим образом:
- Вы поддерживаете пустую строку в начале.
- Если следующий входной символ находится в строке, удалите его из строки.
- Если следующего входного символа нет в строке, добавьте его в строку.
Выведите окончательное состояние строки.
Вы можете смело предположить, что входные данные состоят как минимум из одного символа (то есть непустого), но нет гарантии, что выходные данные не пусты.
Псевдокод (не стесняйтесь играть в гольф):
str = EMPTY
for each character ch in input
if ch exists in str
remove all ch from str
else
append ch to str
print str
Ввод соответствует регулярному выражению ^[A-Za-z]+$
.
Примеры тестовых случаев:
ABCDBCCBE -> ADCBE
ABCXYZCABXAYZ -> A
aAABBbAbbB -> aAbB
GG -> (empty)
Входные данные могут быть заданы любым применимым способом, но они должны рассматриваться как строка и то же самое для выходных данных. Программа не должна выходить с ошибкой.
Победит самая короткая программа на каждом языке!
Дополнительно (необязательно): пожалуйста, объясните, как работает ваша программа. Спасибо.
Ответы:
Haskell ,
4442 байтаПопробуйте онлайн! Редактировать: -2 байта благодаря Zgarb!
Объяснение:
Вторая строка определяет функцию,
(#)
которая принимает строкуs
и символx
и выполняет удаление или добавление. Это достигается путемfilter
исключения каждого вхожденияx
ins
, в результате чего получается строкаz
. Еслиx
не встречается вs
, тоz
равноs
иz++[x|z==s]
возвращает исходную строку сx
добавлением. В противном случае[x|z==s]
выдает пустую строку и возвращается только отфильтрованная строка.foldl(#)""
является анонимной функцией, которая берет строку и добавляет один символ за другим изначально пустую строку""
с функцией(#)
.источник
Желе , 3 байта
Попробуйте онлайн!
Полная программа.
источник
œ^/
не достаточно?the input is never empty
Ну, теперь это работает.J ,
2119 байтКак это устроено:
=/~
- составляет таблицу равенства символов в строке:1#.
- сумма каждой строки по конверсии по основанию 1 (сколько раз встречается буква)~:&.|
- переверните, затем примените сито (это уникальный символ) и снова переверните. Таким образом я нахожу последние вхождения символов в строке:*
- умножает счет на 1 для последней позиции символа в строке, на 0 в противном случае, рассчитывается по вышеуказанному~:&.|
2|
- по модулю 2 (устанавливает в 0 позиции символов с четным счетом):#~
- скопировать правый аргумент в левый аргумент. времена (~ меняет местами арги)]f # a A
Попробуйте онлайн!
источник
Brainfuck, 95 байт
Попробуйте онлайн
Как это устроено
источник
Haskell , 47 байтов
Еще один байт пыли благодаря Брюсу Форте.
Попробуйте онлайн!
Принимает список строк.
Симметричная разница раздражает ...
источник
++
union
с помощью этого метода экономит 2 байта .Сетчатка , 16 байт
Попробуйте онлайн!
источник
R ,
928477 байтПопробуйте онлайн!
-15 байт благодаря джурио
объяснение
djhurio предоставил отличный ответ R, избегая
for
петли - как обычно делают программисты R (включая меня). Вот ответ R, который используетfor
цикл (и сохраняет несколько байтов в процессе).x=scan(,'');
- назначить вход в переменнуюx
y='';
- создать пустую строку в переменной с именемy
for(i in el(strsplit(x,'')))
- для каждого персонажаi
вx
y=c(y[y!=i],if(!i%in%y)i)
- присваиватьy
каждому элементу,y
который не равенi
, добавление,i
если ещеi
не былоy
cat(y,sep='')
- печатать элементыy
без пробелов между нимиЗаметка
Если вы нажмете ссылку TIO выше, вы найдете в заголовке
library(methods)
; это связано с ошибкой djhurio, возникшей в отношенииel()
функции - функция предоставляетсяmethods
пакетом, который в любой версии R, которую я использовал, загружается по умолчанию, но по какой-то причине не TIO. Еслиlibrary(methods)
удалить из заголовка иunlist
заменить егоel
, я получу четыре байта, но так же, как и djhurio , выставив наши байты в96,88 и 99 соответственно.источник
for(i in el(strsplit(scan(,y<-''),y)))y=c(y[y!=i],if(!i%in%y)i);cat(y,sep='')
....[[1]]
это длиннее,el(...)
но корочеunlist(...)
, при условии, что...
это список длиной 1.0
какnul
символ и преобразован в пустую строку.MATL , 6 байтов
Не работает в среде TIO, но отлично работает с реализацией MATLAB, и, благодаря свежему патчу , вы можете попробовать его на MATL Online
X~
равноsetxor
или симметричная разница, которая делает именно то, что просит задача. Остальное просто зацикливается на вводеi"@
и начинается с пустой строки путем объединения всего стека, который пуст в начале (спасибо Луису Мендо).источник
Python 2 , 56 байт
-2 байта благодаря xnor. -3 байта благодаря овс.
Попробуйте онлайн!
Буквально только что поиграл в псевдокод. :П
источник
s=(s+c).replace(c,c[c in s:])
.s=s.replace(c,'')+c[c in s:]
JavaScript (ES6), 60 байт
Контрольные примеры
Показать фрагмент кода
источник
q , 38 байт
источник
APL + WIN, 19 байт
Логика похожа на решение Галена.
источник
Wolfram Language (Mathematica) , 36 байт
Попробуйте онлайн!
Принимает ввод и вывод в виде списка символов.
Как это устроено
Использует
//.
(псевдонимReplaceRepeated
), чтобы найти два повторяющихся символа и удалить оба, пока повторных символов больше не будет. Если персонаж встречается более двух раз, Mathematica всегда удаляет первые два вхождения. Поэтому, если персонаж встречается нечетное количество раз, его последним всегда будет тот, кто выживет.источник
Пролог 81 байт
Не запутанная версия:
delete/3
гарантирует, что его третий аргумент объединяется с его первым аргументом, и все экземпляры второго аргумента удаляются из него.append/3
согласно его имени, добавляет элемент в список.[]
(пустой список), после чего промежуточный результат объединится с желаемым результатом.Тестовое задание:
Некоторые прологи обрабатывают строки в двойных кавычках как списки, SWI может быть настроен на то же самое, но для простоты я привык
string_codes/2
красиво форматировать вывод.источник
Perl 5, 28 + 2 (-pF) = 30 байт
Попробуйте онлайн
источник
R , 84 байта
Попробуйте онлайн!
Другое решение, но есть лучшие ответы R здесь.
R , 88 байт
Попробуйте онлайн!
Спасибо Джузеппе за -7 байт!
Есть более короткий ответ от Duckmayr .
scan(,"")
читать ввод из стандартного ввода.y<-el(strsplit(scan(,""),""))
разделить ввод по символам и сохранить какy
.z=table(y<-el(strsplit(scan(,""),"")))
вычислить частоты каждого символа и сохранить полученную таблицу какz
;unique(y,,T)
возьмите уникальных персонажей с правой стороны.names(z[!z%%2])
выбрать только четные числа и извлечь имена.setdiff(unique(y,,T),names(z[!z%%2]))
удалить символы с четным количеством.cat(setdiff(unique(y,,T),names(z[!z%%2])),sep="")
распечатать вывод.источник
el()
исходит изmethods
пакета, который обычно загружается по умолчанию, но не TIO (об этом рассказано в моем ответе ниже)rev(unique(rev(y)))
? Не будет простоunique(y)
работать? оооооооооо, я вижу, вы хотите уникальные символы справа налево. В этом случаеunique(y,,T)
(настройкаfromLast=T
) будет 88 байтов .Алиса, 9 bytes
Try it online!
Explanation
В основном порт ответа Эрика . Помимо небольшого перенаправления IP-кода код действительно просто:
который делает:
источник
APL (Dyalog), 16 bytes
Try it online!
If errors were allowed, this would've been 9 bytes:
источник
DOMAIN ERROR
if the string is empty, since(,⍨~∩)
doesn't have a predefined identity element.Pyth, 15 bytes
Try it online!
источник
Ruby, 53 bytes
Try it online!
Input and output are both an array of chars. Test code calls
.chars
and.join
for convenience.Explanation
Uses the fact that the letters in the resulting string appear an odd number of times and in the order from right to left.
источник
Pyth, 13 bytes
Takes in input as list of characters. Test it out!
источник
Röda, 34 bytes
Try it online!
This is a direct translation of the pseudocode. It treats input and output as streams of characters.
Explanation:
источник
Python 3, 73 bytes
Not the shortest, but I like this approach.
Try it online!
Loops through the string, keeping only those characters where:
(s.count(c)%2) == 0
- The character appears an even number of times.(i==s.rfind(c))
- The current index is the last appearance of the character in question.источник
REXX, 102 bytes
Try it online!
How it works: Take the rightmost letter, see if the number of occurrences is even or odd (which also doubles as a truth value) and if odd, add it to the output string. Then remove all occurrences of the letter from the input string. Repeat until input is depleted.
источник
Perl 5, 22 + 1 (
-p
) = 23 bytesTry it online!
источник
Java 8, 93 bytes
A lambda from
String
toString
. Just an implementation of the pseudocode in the question.Try It Online
Java 8, 182 bytes
Here's another lambda of the same type that uses streams! It's probably more efficient.
Try It Online
Ungolfed
источник
R, 70 bytes
Try it online!
I was encouraged by djhurio to post this solution; djhurio's answer can be found here.
This uses the same idea as duckmayr's answer, but it leverages a numeric approach by converting the string to its codepoints rather than splitting it into characters, and is a function rather than a full program so it can return the new string rather than printing to stdout.
One important observation is that
F
is initialized toFALSE
or0
andutf8ToInt(0)==""
, so this will succeed for the empty string as well as correctly collapsing the codepoints.источник
PHP, 71+1 bytes
Run as pipe with
-nR
or try it online.источник
Python 3.6, 69 bytes
Try it online!
Dict insertion order is preserved in Python 3.6 .
источник
SNOBOL4 (CSNOBOL4),
9795 bytesTry it online!
источник