Допоможіть моєму синові знайти його листи


17

Фон

На основі гри мій чотирирічний діточок отримав від свого рабина.

«Мета» - «знайти» букви в заданому порядку, наприклад 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

Три досить різні методи дають рівне число байтів.

Python 2 , 59 байт

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

Спробуйте в Інтернеті!

Друкує кожного символу у власному рядку.


Python 2 , 59 байт

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

Спробуйте в Інтернеті!

Приймає списки як вхідні та виводить список.


Python 3 , 59 байт

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

Спробуйте в Інтернеті!


1
Гм, мені подобаються перші дві версії ... чому 99саме?
Ерік Аутгольфер

@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

JavaScript (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

Haskell , 49 46 байт

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

Спробуйте в Інтернеті!

Досить просто. Лівий аргумент - «мета», а правий - стек. Якщо голова цілі збігається з вершиною стеку, ми передбачуємо її та повторюємо з рештою цілі та стеком (без повторного додавання пункту зверху). В іншому випадку ми додаємо верхній елемент і повторюємо ту саму мету, читаючи верхню позицію до кінця стека. Коли мета порожня, відповідність шаблону вибирає другий рядок і порожній список повертається.

EDIT: -3 байти завдяки @GolfWolf та @Laikoni!





1
@GolfWolf ваше друге рішення (і Лайконі) не працює. Він створює "ytrty" замість "yrtyry" через пріоритет оператора перед (:) та (#)
user1472751


1

Java 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 байти

Edit: Teal пелікан має набагато кращий ><>підхід тут , що свопи методу введення

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]

О так, введення цього способу має більше сенсу хаха
Jo King

Як щодо 17 байт ?
Jo King

1
@JoKing - Дуже приємна зміна для усунення цих зайвих маршрутів, але я не міг протистояти додатковому байту: P
Teal pelican

0

Perl, 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

Perl, 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'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.