추가 및 삭제


14

문자로 구성된 한 줄이 주어지면 다음과 같이 처리하십시오.

  • 처음에는 비어있는 문자열을 유지합니다.
  • 다음 입력 문자가 문자열에 있으면 문자열에서 제거하십시오.
  • 다음 입력 문자가 문자열에 없으면 문자열에 추가하십시오.

문자열의 최종 상태를 출력합니다.

입력이 적어도 하나의 문자 (즉, 비어 있지 않은)로 구성되어 있다고 가정 할 수 있지만 출력이 비어 있지 않다는 보장은 없습니다.

의사 코드 (무료로 골프를 즐기십시오) :

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)

입력은 적용 가능한 방식으로 제공 될 수 있지만 출력으로 문자열로 취급되어야합니다. 프로그램이 오류와 함께 종료 되어서는 안됩니다 .

각 언어에서 가장 짧은 프로그램이 승리합니다!

추가 (선택 사항) : 프로그램 작동 방식을 설명하십시오. 감사합니다.


줄이 비어있을 수 있습니까?
user202729

1
@ user202729 아니요. 조금 변경 했으므로 (응답이 무효화되지 않음) 입력이 비어 있지 않습니다.
iBug

1
그렇다면 왜 ais523의 편집 제안 (link) 을 거부 했 습니까?
user202729

답변:


10

하스켈 , 44 42 바이트

foldl(#)""
s#x|z<-filter(/=x)s=z++[x|z==s]

온라인으로 사용해보십시오! 편집 : Zgarb 덕분에 -2 바이트!

설명:

두 번째 줄은 (#)문자열 s과 문자 x를 받아서 제거 또는 추가를 수행 하는 함수 를 정의합니다 . 이것에 의해 달성된다 filter마다 발생 밖으로 보내고 x하여 s문자열 결과 z. 경우 x에 발생하지 않는 s한 다음 z과 같다 sz++[x|z==s]함께 원래의 문자열을 수득 x첨부. 그렇지 않으면 [x|z==s]빈 문자열이 생성되고 필터링 된 문자열 만 반환됩니다.

foldl(#)""익명 함수는 문자열을 가져 와서 함수를 사용하여 처음에 비어있는 문자열 뒤에 한 문자를 추가 ""합니다 (#).


2
필터를 재사용하여 42 바이트 .
Zgarb


8

J , 21 19 바이트

#~~:&.|.(2|*)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

1#. -기본 1 변환에 의한 각 행의 합계 (문자가 몇 번이나 발생하는지)

   ]c =: 1#. b
3 2 2 2 2 2 2 3 2 2 3 2 2

~:&.|-뒤집은 다음 너브 체를 적용하고 (문자는 고유합니다) 다시 뒤집으십시오. 따라서 문자열에서 마지막으로 나타나는 문자를 찾습니다.

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

* -슬링에서 캐릭터의 마지막 위치에 대해 카운트에 1을 곱하고, 그렇지 않으면 0으로 계산 ~:&.|

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

2| -모듈로 2 (짝수를 가진 문자의 위치를 ​​0으로 설정) :

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

#~-오른쪽 인수 왼쪽 인수를 복사하십시오. 시간 (~ args의 위치를 ​​반대로합니다)

]f # a A

온라인으로 사용해보십시오!


6

Brainfuck, 95 바이트

,[<<<[[->+>>>+<<<<]>>>[-<+<->>]<<[[-]<]>[[-]>>[-]>[[-<+>]>]<<[<]<<]<<]<[->>>>[-]<<<]>>>>[->+<]>>[>]>>,]<<<[.<]

온라인 시도

작동 원리

, 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



2

R , 92 84 77 바이트

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

온라인으로 사용해보십시오!

djhurio 덕분에 -15 바이트

설명

djhuriofor 는 R 프로그래머가 본능적으로 규칙 (자체 포함)처럼 루프를 피하는 탁월한 R 답변을 제공했습니다 . 다음은 for루프 를 활용 하고 프로세스에서 몇 바이트를 절약 하는 R 답변입니다 .

  • 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, 나는 4 바이트를 얻을 수 있지만, 그렇게 할 djhurio 에서 우리의 바이트 수를 가하고, 96 각각 88 및 99.


좋은데 for 루프가 더 짧을 것이라고 생각하지 마십시오. else 문을 생략하면 더 짧게 만들 수 있습니다 for(i in el(strsplit(scan(,y<-''),y)))y=c(y[y!=i],if(!i%in%y)i);cat(y,sep='').
djhurio

@ djhurio-알다시피, Ra에서 for 루프가 도움이 될 경우는 거의 없습니다. 당신의 제안에 관하여 : 좋은 생각! 제안이 이제 답변에 통합되었습니다.
duckmayr

1
@djhurio-충분히 공정합니다. 나는 당신이 시작을 어떻게 바꾸 었는지 보지 못했던 else 문을 생략함으로써 도입 된 차이점을보고 너무 바빴습니다. 지금 수정 중입니다. 훌륭한 일!
duckmayr

1
@ djhurio @duckmayr 기본적 으로이 솔루션을 사용하고 문자 추출에 약간 다른 접근법을 사용 하는 73 바이트 솔루션 이 있습니다. 나는 그것을 별도의 답변으로 게시하고 싶지 않았습니다. 또한 주 ...[[1]]이상입니다 el(...)이상하지만 짧은은 unlist(...),이 제공 ...길이 1의 목록입니다
주세페

1
그 흠집이 나는 발견 된 70 안녕 답을 이후 0는 IS nul성격과 빈 문자열로 변환됩니다.
Giuseppe

2

MATL , 6 바이트

vi"@X~

TIO 환경에서는 작동하지 않지만 MATLAB 구현에서는 제대로 작동하며 새로운 패치 덕분에 MATL Online 에서 시도 할 수 있습니다

X~동일 setxor또는 정확히 도전이 요구하시는 않습니다 대칭 차이. 나머지는 입력을 반복 i"@하고 시작시 비어있는 전체 스택을 연결하여 빈 문자열로 시작합니다 (Luis Mendo 덕분에).


2

파이썬 2 , 56 바이트

xnor 덕분에 -2 바이트 ovs 덕분에 -3 바이트

lambda s:reduce(lambda a,c:a.replace(c,'')+c[c in a:],s)

온라인으로 사용해보십시오!

말 그대로 의사 코드를 골랐습니다. :피


1
2 바이트 저장 : s=(s+c).replace(c,c[c in s:]).
xnor

@xnor 그것은 아주 영리하게 실행되는 기본 골프입니다. 감사!
완전히 인간적인

1
-1 바이트 :s=s.replace(c,'')+c[c in s:]
ovs


1

자바 스크립트 (ES6), 60 바이트

s=>[...s].map(c=>s=s.match(c)?s.split(c).join``:s+c,s='')&&s

테스트 사례


@MartinEnder의 Retina 답변을 포팅했으며 45 바이트였습니다 ...
Neil


1

APL + WIN, 19 바이트

Galen의 J 솔루션과 유사한 논리.

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

1

Wolfram Language (Mathematica) , 36 바이트

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

온라인으로 사용해보십시오!

문자 목록으로 입력 및 출력을 가져옵니다.

작동 원리

더 이상 반복되는 문자가 없을 때까지 //.(alias ReplaceRepeated)를 사용 하여 반복되는 두 문자를 찾고 둘 다 삭제합니다. 캐릭터가 두 번 이상 발생하면 Mathematica는 항상 처음 두 항목을 삭제합니다. 따라서 캐릭터가 홀수 번 발생하면 마지막 인스턴스는 항상 살아남을 것입니다.


1

프롤로그 81 바이트

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

난독 화되지 않은 버전 :

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)
    ).
  1. delete/3 세 번째 인수가 첫 번째 인수와 통합되고 두 번째 인수의 모든 인스턴스가 제거됩니다.
  2. 그것들이 같다면, 우리는 요소를 추가합니다 (제거되지 않았습니다).
  3. append/3 이름에 따라 목록에 요소를 추가합니다.
  4. 우리는 [](빈 목록)에 도달 할 때까지 입력 요소를 반복합니다. 이 시점에서 중간 결과가 원하는 결과와 통합됩니다.

테스트:

?- 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 = "".

일부 프롤로그는 큰 따옴표로 문자열을 목록으로 취급하지만 SWI도 동일하게 구성 할 수 있지만 단순성을 위해 string_codes/2출력 형식을 훌륭하게 지정 하는 데 사용 했습니다.



1

R, 84 bytes

y=el(strsplit(scan(,""),""));cat(unique(y[colSums(outer(y,y,"=="))%%2>0],,T),sep="")

Try it online!

Another solution, but there are better R answers here.

R, 88 bytes

z=table(y<-el(strsplit(scan(,""),"")));cat(setdiff(unique(y,,T),names(z[!z%%2])),sep="")

Try it online!

Thanks to Giuseppe for -7 bytes!

There is a shorter answer by duckmayr.

  1. scan(,"") read input from stdin.
  2. y<-el(strsplit(scan(,""),"")) split input by characters and save as y.
  3. z=table(y<-el(strsplit(scan(,""),""))) compute frequencies of each character and save resulting table as z;
  4. unique(y,,T) take unique characters from the right side.
  5. names(z[!z%%2]) select only even counts and extract names.
  6. setdiff(unique(y,,T),names(z[!z%%2])) remove characters with even count.
  7. cat(setdiff(unique(y,,T),names(z[!z%%2])),sep="") print the output.

The reason for your error is that el() comes from the methods package, which while typically loaded by default, is not by TIO (discussed in my answer below)
duckmayr

why are you using rev(unique(rev(y)))? Wouldn't just unique(y) work? ooohhh wait I see, you want the unique characters from right to left. In that case unique(y,,T) (setting fromLast=T) will be 88 bytes.
Giuseppe

0

Alice, 9 bytes

/X&@
\io/

Try it online!

Explanation

Basically a port of Erik's answer. Apart from a bit of IP redirection the code is really just:

i&Xo@

which does:

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



0

Ruby, 53 bytes

->s{s.reverse.uniq.select{|c|s.count(c)%2>0}.reverse}

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.

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

0

Pyth, 13 bytes

{_xD_Qf%/QT2Q

Takes in input as list of characters. Test it out!

      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

0

Röda, 34 bytes

{a=[]a-=_ if[_1 in a]else a+=_1;a}

Try it online!

This is a direct translation of the pseudocode. It treats input and output as streams of characters.

Explanation:

{                    /* 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   */
}

0

Python 3, 73 bytes

Not the shortest, but I like this approach.

lambda s:''.join(c*(s.count(c)%2)*(i==s.rfind(c))for i,c in enumerate(s))

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.

0

REXX, 102 bytes

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

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.



0

Java 8, 93 bytes

A lambda from String to String. Just an implementation of the pseudocode in the question.

s->{String o="";for(char c:s.toCharArray())o=o.indexOf(c)<0?o+c:o.replace(c+"","");return o;}

Try It Online

Java 8, 182 bytes

Here's another lambda of the same type that uses streams! It's probably more efficient.

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

Try It Online

Ungolfed

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

0

R, 70 bytes

function(s){for(i in utf8ToInt(s))F=c(F[F!=i],i*!i%in%F);intToUtf8(F)}

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.

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
}

One important observation is that F is initialized to FALSE or 0 and utf8ToInt(0)=="", so this will succeed for the empty string as well as correctly collapsing the codepoints.


0

PHP, 71+1 bytes

while(~$c=$argn[$i++])$s=strstr($s,$c)?strtr($s,[$c=>""]):$s.$c;echo$s;

Run as pipe with -nR or try it online.



0

SNOBOL4 (CSNOBOL4), 97 95 bytes

	S =INPUT
N	S LEN(1) . C REM . S :F(O)
	O C :S(R)
	O =O C :(N)
R	O C =:S(R)F(N)
O	OUTPUT =O
END

Try it online!

	S =INPUT			;* read input
N	S LEN(1) . C REM . S :F(O)	;* take the first character of S and assign it to C,
					;* assign the remainder to S, and if S has no characters left, goto O
	O C :S(R)			;* if C matches anything in O, goto R, otherwise go to next line
	O =O C :(N)			;* append C to O and goto N
R	O C =:S(R)F(N)			;* as long as C matches O, replace it with ''
					;* (unassigned variables default to the null string)
					;* then goto N once it fails to match
O	OUTPUT =O			;* output the string
END					;* terminate the program
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.