Codegolf — Добавить И Стереть

  • Автор темы Fufliga
  • Обновлено
  • 22, Oct 2024
  • #1

Учитывая одну строку, состоящую только из букв, выполните следующие действия:

  • Вы поддерживаете строку, которая вначале пуста.
  • Если следующий входной символ находится в строке, удалите его из строки.
  • Если следующего входного символа нет в строке, добавьте его в строку.

Выведите окончательное состояние строки.

Вы можете смело предположить, что входные данные состоят как минимум из одного символа (т. е. непустые), но нет никакой гарантии, что выходные данные не пусты.

Псевдокод (не стесняйтесь играть в гольф):

 
 ABCDBCCBE -> ADCBE
ABCXYZCABXAYZ -> A
aAABBbAbbB -> aAbB
GG -> (empty)
 

Ввод соответствует регулярному выражению ^[A-Za-z]+$ .

Примеры тестовых случаев:

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

Входные данные могут быть заданы любым подходящим способом, но их следует рассматривать как строку, и то же самое относится и к выходным данным. Программа должна нет выйти с ошибкой.

Побеждает самая короткая программа на каждом языке!

Дополнительный (Необязательно): Пожалуйста, объясните, как работает ваша программа. Спасибо.

#код-гольф #строка

Fufliga


Рег
17 Oct, 2008

Тем
71

Постов
183

Баллов
558
  • 26, Oct 2024
  • #2

Хаскелл, 44 42 байта

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 utf8ToInt(0)=="" 

Попробуйте онлайн! Редактировать: -2 байта благодаря Zgarb!

Объяснение:

Вторая строка определяет функцию 0 which takes a string FALSE и персонаж F and performs either the remove or append. This is achieved by function(s) { for(i in utf8ToInt(s)) # convert string to codepoints and iterate over it F=c(F[F!=i], # remove duplicates and append i*!i%in%F) # 0 if in F, i otherwise intToUtf8(F) # collapse from codepoints to string } выявляя каждое возникновение function(s){for(i in utf8ToInt(s))F=c(F[F!=i],i*!i%in%F);intToUtf8(F)} в s -> s.join( "", s.chars() .mapToObj(c -> (char) c + "") .filter(c -> s.replaceAll("[^" + c + "]", "").length() % 2 < 0) .distinct() .sorted((c, d) -> s.lastIndexOf(c) - s.lastIndexOf(d)) .toArray(String[]::new) ) , в результате чего получается строка s->s.join("",s.chars().mapToObj(c->(char)c+"").filter(c->s.replaceAll("[^"+c+"]","").length()%2>0).distinct().sorted((c,d)->s.lastIndexOf(c)-s.lastIndexOf(d)).toArray(String[]::new)) . If s->{String o="";for(char c:s.toCharArray())o=o.indexOf(c)<0?o+c:o.replace(c+"","");return o;} не происходит в String , then String равно s/(.)(.*?)\1/$2/&&redo and -p возвращает исходную строку с a=arg(1) s='' do while a>'' b=right(a,1) if countstr(b,a)//2 then s=b||s a=changestr(b,a,'') end say s appended. Otherwise (i==s.rfind(c)) возвращает пустую строку, и возвращается только отфильтрованная строка.

(s.count(c)%2) == 0 is an anonymous function which takes a string and adds one character after the other the initially empty string lambda s:''.join(c*(s.count(c)%2)*(i==s.rfind(c))for i,c in enumerate(s)) с функцией { /* Anonymous function */ a=[] /* initialize a */ /* For each character _1 in the stream: */ a-=_ if[_1 in a] /* Remove it from a if a contains it */ else a+=_1; /* Otherwise append it to a */ a /* Push characters in a to the stream */ } .

 

Skv52


Рег
03 Dec, 2011

Тем
93

Постов
217

Баллов
692
  • 26, Oct 2024
  • #4

Дж, 21 19 байт

f Q (f)ilter input (Q) /QT On how many times (/) each character (T) appears in the input (Q) % 2 Only allow odd numbers of occurences (when x % 2 = 1) _xD_Q Sort (D) descending (the first _) by the location (x) of the last (the second _) inde(x) of the target character in the input (Q) { Remove duplicates

Как это работает:

{_xD_Qf%/QT2Q - makes a table of equality of the characters in the string:

->s{ # lambda function taking char-array argument s.reverse # reverse the input .uniq # get unique characters .select{|c| # select only those which... s.count(c)%2>0 # appear in the input array an odd number of times }.reverse # reverse back and return }

.join - sum of each row by base 1 conversion (how many times the letter occurs)

.chars

->s{s.reverse.uniq.select{|c|s.count(c)%2>0}.reverse} - reverse, then apply nub sieve (is the char unique) and reverse again. Thus I find the last occurrences of the characters in the string:

Vz?:kN)=-kN=+kN

(,⍨~∩)/∘⊖ - multiplies the count by 1 for the last position of the character in the sring, by 0 otherwise, computed by the above {(,⍨~∩)/⍣(≢⍵)⊖⍵}

i Read all input. &X Fold symmetric multiset difference over the input. o Output the result. @ Terminate.

i&Xo@ - modulo 2 (sets to 0 the positions of the chars that have even count):

/X&@ \io/

_./:("")((?,y)=>if(?toSet y)?filter(y!=)else? +y) - copy the right argument left arg. times (~ reverses the places of the args)

;£A=øX ?AkX:ApX

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

 

Frolovva05


Рег
12 May, 2011

Тем
60

Постов
189

Баллов
489
  • 26, Oct 2024
  • #5

Мозговой трах, 95 байт

-h

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

Как это работает

$\=~s/$_//g||($\.=$_)for@F}{ ||answer||

Хаскелл, 47 байт

Еще один смахнул пыль благодаря Брюсу Форте.

string_codes/2

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

Принимает список строк.

Симметричная разница раздражает...

 

Porshnyova5000


Рег
27 Oct, 2019

Тем
90

Постов
211

Баллов
721
  • 26, Oct 2024
  • #6

сетчатка, 16 байт

?- append_and_eraze(`ABCDBCCBE`, [], X), string_codes(Y, X). X = [65, 68, 67, 66, 69], Y = "ADCBE". ?- append_and_eraze(`ABCXYZCABXAYZ`, [], X), string_codes(Y, X). X = [65], Y = "A". ?- append_and_eraze(`aAABBbAbbB`, [], X), string_codes(Y, X). X = [97, 65, 98, 66], Y = "aAbB". ?- append_and_eraze(`GG`, [], X), string_codes(Y, X). X = [], Y = "".

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

 

Дмитрий Морданов


Рег
28 Oct, 2020

Тем
89

Постов
195

Баллов
670
  • 26, Oct 2024
  • #7

МАТЛ, 6 байт

[]

Не работает в среде TIO, но отлично работает в реализации MATLAB, и благодаря свежему патчу вы можете попробовать его. МАТЛ Онлайн

append/3 equals delete/3 , или симметричная разница, которая делает именно то, что требует задача. Остальное просто перебирает ввод append_and_eraze([], Output, Output). append_and_eraze([I | Input], Interim, Output) :- delete(Interim, I, Filtered), ( Interim = Filtered -> append(Interim, [I], Interim1), append_and_eraze(Input, Interim1, Output) ; append_and_eraze(Input, Filtered, Output) ). and starting with an empty string by concatenating the entire stack which is empty at the start (thanks Luis Mendo).

 

Amalpikenia


Рег
20 Apr, 2011

Тем
65

Постов
188

Баллов
523
  • 26, Oct 2024
  • #8

К (нгн/к), 21 9 байт

a([],O,O). a([I|J],K,O):-delete(K,I,F),(K=F->append(K,[I],M),a(J,M,O);a(J,F,O)).

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

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

  • ReplaceRepeated count the number of times each distinct character occurs in the string (reversing the order)
  • //. filter down to where the character appears an odd number of times, then reverse
 

Lania


Рег
20 Aug, 2008

Тем
73

Постов
191

Баллов
556
  • 26, Oct 2024
  • #9

д, 38 байт

#//.{a___,x_,b___,x_,c___}:>{a,b,c}& ||answer||

Р, 92 84 77 байт

(2|+⌿⌽<\⌽c∘.=c)/c←⎕

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

-15 байт благодаря Джурио

Объяснение

Джурио предоставил отличный ответ R, избегая let f = s=>[...s].map(c=>s=s.match(c)?s.split(c).join``:s+c,s='')&&s console.log(f("ABCDBCCBE")) // -> ADCBE console.log(f("ABCXYZCABXAYZ")) // -> A console.log(f("aAABBbAbbB")) // -> aAbB console.log(f("GG")) // -> (empty) loop -- as R programmers instinctively do as a rule (myself included). Here's an R answer that utilizes a s=>[...s].map(c=>s=s.match(c)?s.split(c).join``:s+c,s='')&&s цикл (и при этом сохраняет несколько байтов).

  • lambda s:reduce(lambda a,c:a.replace(c,'')+c[c in a:],s) -- assign the input into the variable cat(setdiff(unique(y,,T),names(z[!z%%2])),sep="")
  • setdiff(unique(y,,T),names(z[!z%%2])) -- create an empty string in a variable called names(z[!z%%2])
  • unique(y,,T) -- for every character z in z=table(y<-el(strsplit(scan(,""),"")))
  • y -- assign to y<-el(strsplit(scan(,""),"")) каждый элемент scan(,"") that is not equal to z=table(y<-el(strsplit(scan(,""),"")));cat(setdiff(unique(y,,T),names(z[!z%%2])),sep="") , добавление y=el(strsplit(scan(,""),""));cat(unique(y[colSums(outer(y,y,"=="))%%2>0],,T),sep="") if el еще не был в unlist
  • library(methods) -- print the elements of methods без пространства между ними

Примечание

Если вы нажмете ссылку TIO выше, вы найдете в заголовке el() ; this is to deal with the error Джурио опытный относительно library(methods) function -- the function is provided by the y Пакет, который в любой версии R, который я использовал, загружается по умолчанию, но по какой-то причине не TIO. Если cat(y,sep='') is removed from the header and y заменяется на i , I gain four bytes, but so would Джурио, в результате чего количество наших байтов составит 96, 88 и 99 соответственно.

 

Slock


Рег
03 Jan, 2008

Тем
89

Постов
221

Баллов
696
  • 26, Oct 2024
  • #10

Р, 84 байта

i

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

Другое решение, но есть лучше Р ответы здесь.

Р, 88 байт

i

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

Спасибо Джузеппе за -7 байт!

Есть более короткий ответ от Duckmayr.

  1. y read input from stdin.
  2. y split input by characters and save as y=c(y[y!=i],if(!i%in%y)i) .
  3. x compute frequencies of each character and save resulting table as i ;
  4. for(i in el(strsplit(x,''))) take unique characters from the right side.
  5. y select only even counts and extract names.
  6. y=''; remove characters with even count.
  7. x print the output.
 

Serg_sh


Рег
17 Sep, 2006

Тем
79

Постов
205

Баллов
600
  • 26, Oct 2024
  • #12

JavaScript (ES6), 60 байт

for

Тестовые случаи

for ||answer||

APL+WIN, 19 байт

Логика аналогична решению Галена J.

for(i in el(strsplit(scan(,y<-''),y)))y=c(y[y!=i],if(!i%in%y)i);cat(y,sep='') ||answer||

Язык Wolfram (Математика), 36 байт

""{$[y in x;except;,][x;y]}/

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

Принимает ввод и вывод в виде списка символов.

Как это работает

Использование |&2! (alias #'=|: ), чтобы найти два повторяющихся символа и удалить оба, пока повторяющиеся символы не исчезнут. Если символ встречается более двух раз, Mathematica всегда удалит первые два вхождения. Таким образом, если персонаж встречается нечетное количество раз, выживет всегда его последний экземпляр.

 

Oktan


Рег
20 Mar, 2011

Тем
85

Постов
197

Баллов
652
  • 26, Oct 2024
  • #13

Пролог 81 байт

|&2!#'=|:

Необфусцированная версия:

i"@
  1. setxor ensures that its third argument unifies with its first argument, with all instances of second argument removed from it.
  2. Если они совпадают, мы добавляем элемент (он не был удален).
  3. X~ as per its name, appends an element to list.
  4. Мы повторяемся над элементами ввода, пока не достигнем vi"@X~ (empty list), at which point the intermediate result will unify with desired result.

Тест:

+1`(.)(.*?)\1 $2

Некоторые Прологи обрабатывают строки в двойных кавычках как списки, SWI можно настроить на то же самое, но для простоты я использовал import Data.List foldl1(\x y->union(x\\y)$y\\x) to format output nicely.

 

Yasminkt


Рег
23 Jul, 2014

Тем
72

Постов
175

Баллов
555
  • 26, Oct 2024
  • #14

Perl 5, 28 + 2 (-пФ) = 30 байт

, Gets first input [ Starts loop <<< Go to start of string [ Loop over the string [->+>>>+<<<<] Duplicates the current char of the string >>>[-<+<->>] Duplicates and subtracts the inputted char from the duplicate of the string char <<[[-]<] If the char is different to the input, remove the difference > If the char is the same [ [-]>>[-]>[[-<+>]>]<<[<]<< Remove the char from the string and sets the inputted char to 0 ] << Moves to the next char of the string ] >>>[->+<] adds the inputted char to the string >>[>]>>, gets the next input ] <<<[.<] prints the string

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

 

ALEX1408


Рег
22 Sep, 2011

Тем
66

Постов
217

Баллов
557
  • 26, Oct 2024
  • #17

Алиса, 9 байт

]f =. 2| e 0 0 0 0 0 0 0 0 0 0 1 0 0

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

Объяснение

По сути порт Ответ Эрика. Если не считать небольшого перенаправления IP, код на самом деле просто:

2|

что делает:

]e =. c * d 0 0 0 0 0 0 2 0 2 2 3 2 2 ||answer||

АПЛ (Диалог), 16 байт

~:&.|

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

Если бы ошибки были разрешены, это было бы 9 байт:

* ||answer||

Пиф, 15 байт

]d =. ~:&.|. a 0 0 0 0 0 0 1 0 1 1 1 1 1

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

 

Nihongo


Рег
20 Mar, 2005

Тем
75

Постов
184

Баллов
569
  • 26, Oct 2024
  • #18

Руби, 53 байта

~:&.|

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

Ввод и вывод представляют собой массив символов. Тестовые вызовы кода ]c =: 1#. b 3 2 2 2 2 2 2 3 2 2 3 2 2 and 1#. для удобства.

Объяснение

Использует тот факт, что буквы в результирующей строке появляются нечетное количество раз и в порядке справа налево.

a =. 'ABCXYZCABXAYZ' ]b =: =/~ a 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 ||answer||

Пиф, 13 байт

=/~

Принимает входные данные в виде списка символов. Проверьте это!

#~~:&.|.(2|*)1#.=/~ ||answer||

Рода, 34 байта

œ^/

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

Это прямой перевод псевдокода. Он рассматривает ввод и вывод как потоки символов.

Объяснение:

(#) ||answer||

Питон 3, 73 байта

Не самый короткий, но мне нравится такой подход.

""

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

Проходит по строке, сохраняя только те символы, где:

  • foldl(#)"" - The character appears an even number of times.
  • [x|z==s] - The current index is the last appearance of the character in question.
 

Adelaida2008


Рег
25 Aug, 2011

Тем
64

Постов
171

Баллов
501
  • 26, Oct 2024
  • #19

РЕКСС, 102 байта

x

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

Как это работает: возьмите самую правую букву, посмотрите, является ли количество вхождений четным или нечетным (что также удваивается как значение истинности), и, если нечетное, добавьте ее в выходную строку. Затем удалите все вхождения буквы из входной строки. Повторяйте до тех пор, пока ввод не будет исчерпан.

 

Gracoman


Рег
31 Dec, 2011

Тем
91

Постов
196

Баллов
691
  • 26, Oct 2024
  • #21

Java 8, 93 байта

Лямбда из z to s . Просто реализация псевдокода в вопросе.

x

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

Java 8, 182 байта

Вот еще одна лямбда того же типа, использующая потоки! Наверное, это более эффективно.

z

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

Негольфед

s ||answer||

Р, 70 байт

x

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

Джурио посоветовал мне опубликовать это решение; ответ Джурио можно найти здесь.

Здесь используется та же идея, что и ответ Дакмайра, но он использует числовой подход, преобразуя строку в ее кодовые точки, а не разбивая ее на символы, и представляет собой функцию, а не полную программу, поэтому может возвращать новую строку, а не печатать на стандартный вывод.

filter

Одно важное наблюдение состоит в том, что x is initialized to s или (#) and foldl(#)"" s#x|z<-filter(/=x)s=z++[x|z==s] , так что это будет успешным для пустой строки, а также для правильного свертывания кодовых точек.

 

Oligarx811


Рег
06 Jun, 2019

Тем
68

Постов
179

Баллов
539
Тем
403,760
Комментарии
400,028
Опыт
2,418,908

Интересно