Разрешить удвоение и утроение действий в Доминионе


14

вдохновение

Этот вопрос навеян карточками Throne Room и King's Court из популярной карточной игры Dominion .

Тронный зал Королевский двор

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

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

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

* Технически, вы выбираете действие, на которое влияют, как часть решения Тронного Зала или Королевского Суда, но этот взгляд является более чистым для этой задачи.

Требования к программе

Написать программу или именованную функцию . Он должен принимать цепочку сыгранных действий (ввод STDIN или функции) и выводить или распечатывать результирующую цепочку действий от эффектов удвоения и утроения. Побеждает несколько байтов.

вход

Строка, представляющая последовательность сыгранных действий. Общие действия представлены заглавными буквами Aчерез Z. Специальное Удвоение действие Тронный зал представлен характер 2, и троекратное действие короля Суд по 3,

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

Пример ввода: WA23G3GA

Выход

Строка заглавных букв Aв Z. Это должна быть последовательность общих действий, возникающих в результате разрешения эффектов удвоения и утроения, в порядке их возникновения.

У вас может быть выходной конец в новой строке, если вы хотите. В противном случае не должно быть никаких дополнительных символов.

Пример вывода: WAGGGGGGAAA.

Как работает удвоение и утроение в Доминионе

Здесь я расскажу о том, как работают цепочки Тронных комнат ( 2ов) и Королевских судов ( 3ий) в соответствии с правилами Доминиона.

После того, как вы сыграете a 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;}

Expanded:

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('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;}

Ungolfed

#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

Python (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.