Вирішіть подвійні та утроєні дії в Домініоні


14

Натхнення

Це питання натхнене картками Throne Room та King's Court від популярної карткової гри Dominion .

Тронний зал Королівський суд

У рамках своєї черги людина відтворює послідовність дій. Ці дві конкретні дії призводять до повторення наступної відтвореної дії два-три рази *. Інші "загальні" дії спричиняють конкретні ігрові ефекти, але нас не цікавлять деталі, просто позначивши їх літерами.

Цікавий випадок, коли Тронний зал або Королівський суд впливає на іншу Тронну кімнату Королівського двору, внаслідок чого ефект подвоєння або потроєння сам по собі збільшується вдвічі або втричі. Довгі ланцюги номерів престолів, королівські суди та багаторазові дії можуть збентежити навіть досвідчених гравців Домініону.

Ваша мета - написати код, який правильно розв’язує ці ланцюги, використовуючи якомога менше байтів. Я опишу вимоги до програми, перш ніж поясню, як ланцюги вирішуються в правилах Dominion.

* Технічно ви обираєте дію, на яку постраждали, як частину рішення Тронної кімнати або Королівського двору, але ця думка є більш чистою для цього виклику.

Вимоги до програми

Напишіть програму або названу функцію . Він повинен виконувати ланцюжок відтворених дій (STDIN або функція введення) та виводити або друкувати результуючу ланцюжок дій з ефектів подвоєння та утроєння. Виграє найменше байт.

Вхідні дані

Рядок, що представляє послідовність відтворених дій. Родові дії представлені великими літерами Aнаскрізь Z. Спеціальна дія подвоєння "Тронна кімната" представлена ​​персонажем 2, а подвоєне дійство "Царський двір" 3-

Кількість символів (дій) буде від 1 до 30 включно. За бажанням у вас може бути кінець вводу в новому рядку.

Приклад введення: WA23G3GA

Вихідні дані

Рядок з великої літери Aдо Z. Це має бути послідовність родових дій, що виникає в результаті вирішення подвоєних та потрійних ефектів у порядку, ніж вони відбуваються.

Ви можете мати кінець виходу в новому рядку, якщо бажаєте. В іншому випадку не повинно бути додаткових символів.

Приклад виведення: WAGGGGGGAAA.

Як працює подвоєння та потроєння в Домініоні

Тут я перегляну, як працюють ланцюги кімнат престолів 2і судів короля 3відповідно до правил Домініону.

Після того як ви граєте в 2, наступна розв’язана дія відбувається двічі. Отже, якщо ви спочатку граєте 2, значить A, у вас Aтрапляється двічі.

2A -> AA

Аналогічно

A2BC -> ABBC
3DE -> DDDE
3N2BC3XY2 -> NNNBBCXXXY

В останньому прикладі зауважте, що фінал 2не мав нічого подвоїти, тому це не мало ефекту.

Цікава річ, коли ефекти подвоєння або потроєння самі по собі збільшуються вдвічі або втричі. Наприклад,

22AB -> AABB

По-перше, ви граєте 2. Потім ви граєте в інший 2, який подвоюється від попереднього 2. В результаті дві наступні дії подвоюються. По-перше, дві копії Aрішення. Потім, копії Bвирішуються.

Зауважте, що Aце не вчетверо: після першої копії 2актів на першу A, наступна копія діє на наступну невирішену дію, яка є B. Без цього Bми мали б

22A -> AA

де другий примірник 2очікує подвоєння наступної дії, але жодної дії не відбувається.

Наостанок розглянемо складний приклад.

223BCDE -> BBBCCCDDE

Як і раніше, перший 2спричиняє 2подвоєння другого . Отже, наступні дві дії будуть подвоєні. Перша копія 2подвоює наступну дію 3, яка повинна бути повністю вирішена до вирішення наступної копії 2. Перший примірник 3трійки B, а другий примірник трійки C. Тепер, ще очікуваний другий примірник2 подвоює наступну ще не вирішену дію, яка є D. Після цього ефектів подвоєння чи потрійності не залишається, і остаточна дія Eпросто відбувається.

Тестові справи

Вони задані як (input,output).

(FY, FY)
(A2BC, ABBC)
(3DE, DDDE)
(3N2BC3XY2, NNNBBCXXXY)
(WA23G3GA, WAGGGGGGAAA)
(32, )
(33RST, RRRSSSTTT)
(2A32B2CDEFG, AABBCCDDEEFG)
(A2A323AB2CD2D2E3ABC, AAAAAABBBCCDDDDEEAAABBBC)
(P22LL3Q2Q22T, PLLLLQQQQQTT)
(322322ABCDEFGHIJKLMN, AABBCCDDEEEFFGGHHIJKLMN)

Відповіді:


5

GolfScript ( 29 26 байт)

](1/{\1+(3&@*.23-\1$-@+}/;

Демонстрація в Інтернеті

Розсічення

Це злегка зловживає вільним типізацією GolfScript. Стек скільки разів повторювати наступні дії починається як масив і пізніше перетворюється в рядок - але 1+додає 1 і (3&вискакує перше значення і правильно поміщає його в діапазоні 0до 3незалежно від зміни типу.

](         # Push an empty array under the input string to serve as rep stack
1/{        # Loop over the input string as a series of 1-char strings
           #   Stack is ... reps ch
           #   where the ... covers zero or more strings which will be output
  \        #   Bring the rep stack to the top
  1+(      #   Push a `1` on the bottom of it to avoid underflow and then pop
  3&       #   Coerce to correct range, because if rep stack is a string then
           #   we just got an ASCII value
  @*       #   Apply repetition to the 1-char string: it's now an n-char string
  .23-     #   Duplicate it and remove chars '2' and '3': this becomes output
  \1$-     #   Get the original copy and remove the output string's chars
           #   So the stack is now ... reps output non-output
           #   where non-output is either an empty string or a string of '2's
           #   or '3's
  @+       #   Push non-output onto the repetition stack
}/         # Loop
;          # Pop whatever's left of the repetition stack

Мені подобається, що твій фокус проштовхування 1під стек трактує необмежені дії так само, як і множинні. Не могли б ви пояснити більше про те, як ви жонглюєте різними стеками? Зокрема, що \ робить, щоб "довести стек реп до вершини"?
xnor

@xnor, ось вказівка на вбудовані файли . \ поміняє два верхні елементи в стеку.
Пітер Тейлор

Дякую, я не розумів, що кожен елемент стека - це власний стек; Я уявляв єдиний з’єднаний стек.
xnor

@xnor, це не кожен елемент стека - його власний стек; це те, що стек повторень зберігається як масив або рядок (який все ще є масивом, але деякі вбудовані трактуються по-різному). Демонстрація налагодження, яка друкує вміст стеку GS безпосередньо перед кінцем основного циклу.
Пітер Тейлор

4

Javascript - 162 152 байти

Мінімізовано:

F=I=>{L=c=>S.length;p=c=>L()?S.shift():d=>{};S=[(x=>/\d/.test(x)?(c,b)=>{for(c=p(),b=x;b--;)c();}:c=>s+=x)(m)for(m of I)];for(s='';L();)p()();return s;}

Розширено:

F = I => {
    L = c => S.length;
    p = c => L() ? S.shift() : d => {};
    S = [ (x => /\d/.test( x ) ?
        (c,b) => {
            for( c = p(), b = x; b--; )
                c();
        } : c =>
            s += x
        )(m) for( m of I ) ];

    for( s = ''; L(); )
        p()();

    return s;
}

Я здогадуюсь, що мови для гольфу на основі стеків вбиватимуть цю, оскільки це в основному вправа у складанні функцій. : P

Зразки виходів

F('3N2BC3XY2')
"NNNBBCXXXY"

F('WA23G3GA')
"WAGGGGGGAAA"

F('A2A323AB2CD2D2E3ABC')
"AAAAAABBBCCDDDDEEAAABBBC"

F('322322ABCDEFGHIJKLMN')
"AABBCCDDEEEFFGGHHIJKLMN"

F('FY')
"FY"

F('')
""

1
Мене дивує, наскільки точна паралельна інтерпретація карт як функцій. Я очікував стек, але не буквальний стек викликів функцій! Чи не існує більш стислого способу хоч викликати функцію кілька разів? А ще краще, змінна кількість разів для обробки 2/3справ разом?
xnor

@xnor: Я вважав, що це розумно. ;) Що стосується вашої пропозиції, то ваша інтуїція була правильною. Я поєднав два випадки, щоб заощадити 10 байт. В ідеалі було б 18, але я натрапив на те, що, на мою думку, є помилкою у Firefox. Я повинен мати можливість xбезпосередньо маніпулювати, не спершу скопіювавши його в змінну, bскопійовану до внутрішньої лямбда, але Firefox не оцінює стан циклу належним чином. Зокрема, xйде негатив і браузер зависає. Спробуйте замінити , b = x; b--;з ; x--;і запустити вхід A2A323AB2CD2D2E3ABC. Якщо хтось, хто читає це, може зрозуміти, чому, ...
COTO

... Мені б дуже цікаво знати. Можливо, мені щось не вистачає про те, як повинні працювати закриття.
COTO

3

C, 115 111 байт

Використовує стандартний вхід / вихід.

Збережено 4, використовуючи memsetта змушуючи стек рухатися в іншому напрямку.

char*i,X[222],*s=X+99;main(){for(gets(i=X);*i;i++)*i<55?s=memset(s-*s,*i-49,*s+1):putchar(*i)**s?--*s,--i:++s;}

Безумовно

#include <stdio.h>
#include <stdlib.h>
char I[99], S[99], *i = I, *s = S+66;
int n;
int main()
{
    gets(I);
    for(;*i;)
    {
        if(*i < '5') {
            n = *s;
            s[0] = s[1] = s[2] = *i - '1';
            s += n;
            i++;
        } else {
            putchar(*i);
            if(*s)
                --*s;
            else
                --s, ++i;
        }
    }
    return 0;
}

0

Пітон (84)

S='1'*99
R=''
for c in input():q=int(S[0])*c;S=q*(c<'A')+S[1:];R+=q*(c>'3')
print(R)

S- це стек множників (верхній, якщо спереду). Він ініціалізований з достатньою 1лінією, щоб обробляти незмножені дії.

Залежно від того, чи є поточна дія cзагальною чи ні, ми додаємо її множений результат або до виводу, Rабо до стеку множниківS .

Все представлено як рядок, а не список символів. Оскільки рядки незмінні, ми, на жаль, не можемо використовувати popабо присвоювати їм елементи.

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