아들이 편지를 찾도록 도와주세요


17

배경

내 4 살짜리가 그의 랍비에서 얻은 게임을 바탕으로

"목표"는 주어진 순서대로 글자를 "찾는"것입니다 (예 :) aecdb. 예를 들어 레터 카드 묶음이 제공 daceb됩니다. 주기적으로하더라도 주어진 순서로만 스택을 검색 할 수 있습니다. 필요한 편지를 만나면 스택에서 꺼내십시오.

객관적인

순서와 스택 (서로 중복없는 순열)이 주어지면 게임을하는 동안 볼 수있는 최상위 스택 문자 (모두 인쇄 가능한 ASCII 임)의 시퀀스를 찾으십시오.

단계별 예

aecdb스택이 주어지면 순서를 찾아야합니다 daceb.

스택 맨 위 d: 우리가 찾고있는 것이 아니므로 ( a)를 시퀀스에 추가 d하고 스택 :을 얻기 위해 회전하십시오 acebd.

스택 맨 위 a: 예! 시퀀스에 추가 da하고 스택에서 제거합니다 cebd.

스택 맨 위 c: 우리가 찾고있는 것이 아니므로 ( e)를 시퀀스에 추가 dac하고 스택 :을 얻기 위해 회전하십시오 ebdc.

스택 맨 위 e: 예! 시퀀스에 추가 dace하고 스택에서 제거합니다 bdc.

스택 맨 위 b: 우리가 찾고있는 것이 아니므로 ( c)를 시퀀스에 추가 daceb하고 스택 :을 얻기 위해 회전하십시오 dcb.

스택 맨 위 d: 우리가 찾고있는 것이 아니므로 ( c)를 시퀀스에 추가 dacebd하고 스택 :을 얻기 위해 회전하십시오 cbd.

스택 맨 위 c: 예! 시퀀스에 추가 dacebdc하고 스택에서 제거합니다 bd.

스택 맨 위 b: 우리가 찾고있는 것이 아니므로 ( d)를 시퀀스에 추가 dacebdcb하고 스택 :을 얻기 위해 회전하십시오 db.

스택 맨 위 d: 예! 시퀀스에 추가 dacebdcbd하고 스택에서 제거합니다 b.

스택 맨 위 b: 예! 시퀀스에 추가 dacebdcbdb하고 스택에서 제거합니다 .

그리고 우리는 끝났습니다. 결과는 dacebdcbdb입니다.

참조 구현

def letters(target, stack):
    string = ''
    while stack:
        string += stack[0]
        if stack[0] == target[0]:
            stack.pop(0)
            target = target[1:]
        else:
            stack.append(stack.pop(0))
    return string

print letters('aecdb', list('daceb'))

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

테스트 사례

try, yrtyrtyry

1234, 43214321432434

ABCDEFGHIJKLMNOPQRSTUVWXYZ, RUAHYKCLQZXEMPBWGDIOTVJNSFRUAHYKCLQZXEMPBWGDIOTVJNSFRUHYKCLQZXEMPWGDIOTVJNSFRUHYKLQZXEMPWGIOTVJNSFRUHYKLQZXMPWGIOTVJNSRUHYKLQZXMPWIOTVJNSRUYKLQZXMPWOTVNSRUYQZXPWOTVSRUYQZXPWTVSRUYQZXWTVSRUYZXWTVSUYZXWTVUYZXWVYZXWYZXYZ

?, ??

a, a a a

abcd, abcdabcd

답변:


5

상당히 다른 세 가지 방법으로 동일한 바이트 수를 제공합니다.

파이썬 2 , 59 바이트

s,t=input()
for c in s*99:
 if c in t:print c;t=t.lstrip(c)

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

각 문자를 해당 줄에 인쇄합니다.


파이썬 2 , 59 바이트

lambda s,t:[c==t[0]and t.pop(0)or c for c in s*99if c in t]

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

리스트를 입력으로 받아서리스트를 출력합니다.


파이썬 3 , 59 바이트

def f(s,t):
 for c in t:p,q=s.split(c);s=q+p;print(end=p+c)

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


1
흠, 나는 처음 두 버전을 의심합니다 ... 왜 99구체적으로?
Outgolfer Erik

@EriktheOutgolger 최소한 인쇄 가능한 ASCII 문자 수이며 각 입력의 길이와 같습니다.
xnor

5

APL (Dyalog Classic) , 21 바이트

∊⊢,⊢∘⊂~¨(,\⊣⊂⍨1,2>/⍋)

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

이 열차는 {∊⍵,(⊂⍵)~¨(,\⍺⊂⍨1,2>/⍺⍋⍵)}

왼쪽 인수에서 오른쪽 인수의 순열을 제공합니다.

1,2>/연속 쌍을 비교 >하고 1을 앞에 붙입니다.

⍺⊂⍨위의 부울 마스크를 사용하여 그룹 으로 나눕니다 . 마스크에서 1은 새 그룹의 시작을 표시합니다.

,\ 그룹의 누적 연결

(⊂⍵)~¨ 에 대한 각각의 보완

⍵, 접두사

단일 문자열로 평평하게하다


4

배치, 155 바이트

@set/pt=
@set/ps=
@set r=
:l
@set c=%s:~,1%
@set r=%r%%c%
@if %c%==%t:~,1% set t=%t:~1%&set c=
@set s=%s:~1%%c%
@if not "%t%"=="" goto l
@echo %r%

STDIN의 입력으로 대상 및 스택을 가져옵니다.


4

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

대상을 문자열로, 스택을 문자 배열로 사용합니다. 문자열을 반환합니다.

f=(t,[c,...s])=>t&&c+f(t.slice(c==t[0]||!s.push(c)),s)

테스트 사례

어떻게?

각 반복 c에서 스택 맨 위에 있는 문자 를 추출 하여 최종 결과에 추가합니다. 그런 다음 매개 변수가의 결과에 따라 달라지는 재귀 호출을 수행합니다 c == t[0].t[0] 향후 예상되는 문자입니다.

c일치하는 경우 t[0]:

  • 우리는 제거 c 는 전달하여 대상 문자열에서t.slice(1)
  • 변경하지 않고 c전달하여 스택에서 제거 합니다s

c일치하지 않는 경우 t[0]:

  • 우리는 전달하여 대상 문자열을 변경하지 못하게합니다. t.slice(0)
  • 우리 c는 스택의 끝에서 뒤로 밀어



3

하스켈 , 49 46 바이트

q@(a:b)#(c:d)|a==c=a:b#d|e<-d++[c]=c:q#e
a#_=a

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

상당히 간단합니다. 왼쪽 인수는 "목표"이고 오른쪽은 스택입니다. 목표의 머리가 스택의 상단과 일치하면 목표를 추가하고 나머지 목표 및 스택과 함께 반복합니다 (항목을 다시 추가하지 않고). 그렇지 않으면 우리는 최상위 항목을 추가하고 동일한 목표로 반복하여 최상위 항목을 스택의 끝까지 읽습니다. 목표가 비어 있으면 패턴 일치가 두 번째 줄을 선택하고 빈 목록이 반환됩니다.

편집 : @GolfWolf 및 @Laikoni 덕분에 -3 바이트!





1
@GolfWolf 두 번째 솔루션 (및 Laikoni)이 작동하지 않습니다. 연산자 우선 순위가 (:) 및 (#)으로 인해 "yrtyry"대신 "ytrty"를 생성합니다.
user1472751


1

자바 8, 88 바이트

a->b->{for(int c:a)for(char t=0;c!=t;System.out.print(t)){t=b.poll();if(c!=t)b.add(t);}}

로 입력 char[]하고 java.util.LinkedList<Character>(java.util.Queue 구현)

설명:

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

a->b->{                        // Method with two parameters and no return-type
  for(int c:a)                 //  Loop over the characters of the char-array
    for(char t=0;c!=t;         //   Inner loop until we've found the character in the queue
        System.out.print(t)){  //     After every iteration: print the char `t`
      t=b.poll();              //    Remove the top of the queue, and save it in `t`
      if(c!=t)                 //    If this is not the character we're looking for:
        b.add(t);}}            //     Add it at the end of the queue again

1

> <> , 38 32 바이트

편집 : 청록 펠리컨은 여기 에 입력 방법을 교환 하는 훨씬 더 나은 ><>접근 방식을 가지고 있습니다.

0[i:0(1$.
\~~l]1+{$[&
/?=&:&:o:{

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

통해 편지의 순서를 -s플래그를 와 입력을 통한 스택 .

작동 방식 :

0[.... Creates a new empty stack
...... This puts the order of the letters safely away
......

..i:0(1$. Takes input until EOF (-1). This means input is in reverse
..~...    And then teleports to the ~ on this line
......

......      Gets the first character from the beginning of the order
\.~l]1+{$[& And stores it in the register before going to the next line
/.....

......     Output the bottom of the stack
......     Checks if the bottom of the stack is equal to the current character
/?=&:&:o:{ If so, go to the second line, else cycle the stack and repeat

0.....      Pop the extra 0 we collected
\~~l]1+{$[& Pop the value that was equal and get the next character from the order
/.....      And go down to the last line. This will end with an error (which could be avoid with a mere 4 extra bytes


1

> <> , 21 16 바이트

i$\~~
=?\$:{::o@

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

빈 공간을 활용하고 추가 코드 재 라우팅을 제거하도록 흐름이 변경되었습니다. (-5 바이트)-@JoKing 덕분에

> <> , 21 바이트

i:{:@=?v:o$!
o~i00. >

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

다른> <> 답변은 여기 에서 찾을 수 있습니다.

설명

스택은 -s 플래그를 사용하여 초기 문자 세트로 시작합니다. 입력은 사용자에게 주어진 문자 순서입니다. 이 설명은 코드의 흐름을 따릅니다.

i$\        : Take input, swap the top 2 stack items then move to line 2;
             [1,2,3] -> [1,2,4,3]
  \$:      : Swap the top 2 stack items then duplicate the top item;
             [1,2,4,3] -> [1,2,3,4,4]
     {::o  : Move the stack items 1 left then duplicate the stack top twice and print one;
             [1,2,3,4,4] -> [2,3,4,4,1,1]
=?\      @ : Swap the top three stack items left 1 then do an equal comparison, if equality move to line 1 else continue;
             [2,3,4,4,1,1] -> [2,3,4,1,1,4] -> [2,3,4,1]
  \~~      : Remove the top 2 stack items;
             [2,3,4,1] -> [2,3]

오 예, 그런 식으로 입력하는 것이 더 의미가 있습니다 lol
Jo King

어떻게 약 17 바이트 ?
Jo King

1
@JoKing-중복 라우팅을 없애기위한 아주 좋은 변화, 나는 여분의 바이트를 빼앗길 수 없었습니다. : P
Teal pelican

0

펄, 62 바이트

sub{$_=$_[1];for$x(@{$_[0]}){/\Q$x\E/;$z.="$`$&";$_="$'$`"}$z}

첫 번째 인수 인 순서를 문자 목록으로, 두 번째 인수 인 스택을 문자열로 사용합니다.

언 골프 드 :

sub {
    $_ = $_[1];
    for $x (@{$_[0]}) {
        /\Q$_\E/;
        $z.="$`$&";
        $_ = "$'$`"
    }
    $z
}

모호한 정규식 변수가 무엇인지 궁금한 적이 있습니까? 분명히, 그들은이 정확한 도전을 위해 설계되었습니다. 우리는 현재 캐릭터와 일치합니다 $x(불행히도 정규 표현식 특수 문자 인 경우 탈출해야합니다). 이렇게하면 문자열이 "일치하기 전" $`, "일치하는" $&및 "일치 한 후 " 로 편리하게 분할 $'됩니다. 주기적 검색에서 일치하기 전에 모든 문자를 명확하게 확인하고 다시 스택에 넣습니다. 우리는 또한 현재 캐릭터를 보았지만 다시 넣지 않았습니다. 따라서 "검색 전"을 "표시"목록에 추가하고 "일치 후"와 "일치 전"으로 $z스택을 구성합니다.


0

SNOBOL4 (CSNOBOL4) , 98 바이트

	S =INPUT
	L =INPUT
R	S LEN(1) . X REM . S	:F(END)
	OUTPUT =X
	L POS(0) X =	:S(R)
	S =S X	:(R)
END

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

각 문자를 줄 바꿈에 인쇄합니다. 이 버전 을 사용 하여 모든 내용을 같은 줄에 인쇄하십시오. 입력을 스택으로 가져온 다음 줄 바꿈으로 구분하여 타겟팅합니다.

	S =INPUT			;*read stack
	L =INPUT			;*read letters
R	S LEN(1) . X REM . S	:F(END)	;*set X to the first letter of S and S to the remainder. If S is empty, goto END.
	OUTPUT =X			;*output X
	L POS(0) X =	:S(R)		;*if the first character of L matches X, remove it and goto R
	S =S X	:(R)			;*else put X at the end of S and goto R
END

0

펄, 44 바이트

포함 +4을 위해-lF

STDIN에서 대상으로 입력 한 다음 스택으로 입력하십시오 (이 예제의 역순입니다).

(echo daceb; echo aecdb) | perl -lF -E '$a=<>;say,$a=~s/^\Q$_//||push@F,$_ for@F'

후행 줄 바꿈이 마음에 들지 않으면 다음과 같이 40작동합니다.

(echo daceb; echo aecdb) | perl -plE '$_=<>=~s%.%s/(.*)\Q$&//s;$_.=$1;$&%reg'
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.