Моделюйте циклічну систему міток


14

Циклічна система тегів крихітна, Тьюринг обчислювальна модель , що складається з алфавіту два-символу (я буду використовувати {0,1}), кінцевий, непорожній циклічний список виробництв , що складаються з цих двох символів, і необмежену слово , яке також складається з ці два символи.

На кожному кроці:

  • перший елемент у слові видаляється
  • якщо це було 0поточне виробництво пропущено
  • якщо це було 1поточне виробництво , додається в кінці слова .
  • наступне виробництво стає активним. Якщо це було останнє виробництво, поверніться до першого.

Система зупиняється, коли слово стає порожнім.

Приклад (з Вікіпедії):

Productions: (010, 000, 1111)
Initial word: 11001

Generation  Production   Word (before)            Word (after)
   0           010           11001             →     1001010       
   1           000            1001010          →      001010000
   2           1111            001010000       →       01010000
   3           010              01010000       →        1010000
   4           000               1010000       →         010000000
   5           1111               010000000    →          10000000
   6           010                 10000000    →           0000000010
   7           000                  0000000010 →            000000010
   8           1111                  000000010 →             00000010
   9           010                    00000010 →              0000010

Ваше завдання, якщо ви вирішите прийняти це, - написати програму або функцію, яка займає:

  • перелік постановок,
  • початкове слово, і
  • покоління,

і друкує або повертає слово в цьому поколінні.

Наприклад,

cyclic_tag(
      prod=[[0,1,0],[0,0,0],[1,1,1,1]], 
      word=[1,1,0,0,1], 
      gen=4) => [1,0,1,0,0,0,0]

Деталі щодо впровадження:

  • Алфавіт не має значення. Ви можете використовувати 0і 1, Trueі False, Tі NIL, Aі B, або навіть 1і 0, або все інше, що ви можете придумати, до тих пір, поки будете послідовні. Усі вхідні та вихідні дані повинні використовувати один і той же алфавіт, і ви повинні вказати, для чого ви використовуєте 0і для чого 1.

  • Довжина слова повинна бути теоретично необмеженою. Тобто ви не можете жорстко кодувати максимальну довжину слова. Якщо я запускаю вашу програму на ідеальному комп'ютері з нескінченним обсягом пам'яті, вона повинна теоретично мати можливість використовувати її. (Ви можете ігнорувати обмеження перекладача / компілятора.)

  • Якщо дана система зупиняється до досягнення даного покоління, ви повинні повернути або надрукувати порожнє слово.

  • Порожня продукція існує, і ви повинні вміти з нею впоратися. Якщо ви пишете повну програму, ваш ввід / вивід також повинен мати можливість це впоратися.

Редагувати : Спочатку я подумав, що покоління 0є самим вхідним словом, а генерація 1- результатом першого кроку. Тобто я мав намір вам повернути стовпець " раніше ". Однак , оскільки я недостатньо зрозуміла, заявляючи про це, я прийму обидва варіанти ; для кожного покоління ви можете повернути значення або в стовпці до, або після . Ви повинні заявити, що ви стежите за стовпцем після , якщо ви це робите. Ви також повинні бути послідовними, у якому стовпці ви виберете.

Я присуджую найменший код за тиждень (27.10.2014).


Гм, ви впевнені, що ваш результат у прикладі правильний? Виходячи з іншого прикладу, який ви навели, я думаю, що це ген 5 ...
FryAmTheEggman

Чи можемо ми взяти дані в іншому порядку?
Мартін Ендер

1
@FryAmTheEggman: Це правильно, я мав на увазі стовпець "до". Якщо більше людей допустили цю помилку, я зміню своє питання, щоб прийняти будь-яке. Зізнаюся, мені було не дуже ясно.
marinus

@ MartinBüttner: поки ви вказуєте замовлення, це не має значення.
marinus

Відповіді:


4

GolfScript (від 17 до 19 байт залежно від формату введення та прийнятого вихідного формату)

18 байт:

~.@*<{\1,or(@*+}/`

Приймає вхід у форму [1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 4і дає вихід у формі [1 0 1 0 0 0 0]. (Може бути 17 байт без останнього, `якщо висновок як 1010000прийнятний).

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

19 байт:

~.@*<{\0`or(1&@*+}/

Бере введення у формі "11001" ["010" "000" "1111"] 4.

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

Розсічення

~        # Evaluate input: stack: word productions gen
.@*<     # Produce a list of the right number of productions with suitable repetition
{        # For each of those productions:
  \      #   Bring the word to the top
  0`or   #   Ensure that we don't get an error if the word is empty
  (1&    #   Pop the first char from the word and evaluate it
  @*     #   Repeat the production that many times
  +      #   Concatenate 0 or 1 copies of the production to the rest of the word
}/       # Endforeach

Кредит Martin Büttner «s рішення CJam для ідеї створення списку постановок повторення і зрізання.


Ви пов'язані з рішенням CJam, яке ви цитуєте, тому я вибрав цю відповідь. Якщо ви поголите інший байт, я перегляну :)
marinus

@marinus, чи приймаєте ви 17-байтну версію, на яку я згадуюсь у тексті своєї відповіді?
Пітер Тейлор

Я цього не бачив, але це виглядає дійсно. Можливо, вам слід це позначити трохи чіткіше.
marinus

5

Хаскелл, 55 53 51

(t:w)%p|t=w++p|0<1=w
x%_=x
e w=(!!).scanl(%)w.cycle

це використовує Trueяк 1і Falseяк 0. Приклад запуску:

*Main> let t=True ; f=False
*Main> e [t,f,t] [[f,f,f],[t,t,t]] 4
[False,False,False,False,False]

3

CJam, 31 30 28 27 24 18 байт

{_@*<{\_0a?(@*+}/}

Це визначає блок (найбільш близький до функціїN), який очікує, що вхід буде розміщуватися на стеку таким чином

[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 9

Аналогічно він залишить масив 0s і 1s на стеці.

Тестуйте це тут. Вставте вхід один перший рядок, код у третьому рядку та додайте a, ~щоб фактично оцінити блок. Напр

[1 1 0 0 1] [[0 1 0] [0 0 0] [1 1 1 1]] 9
{_@*<{\_0a?(@*+}/}~

Якщо вихід не повинен мати ту саму форму, що і вхід

Пояснення:

_@*<{\_0a?(@*+}/
_@               "Duplicate the generation and pull the productions to the top.";
  *<             "Repeat the productions N times and take the first N elements.";
    {         }/ "For each element in that list, run this block.";
     \           "Swap production and current word W.";
      _0a?       "W = (W != []) ? W : [0]. This is to ensure we can unshift an element.";
          (      "Unshift the first 0 or 1 from the word.";
           @     "Rotate the stack, pulling the production to the top.";
            *    "Repeat it 0 or 1 times.";
             +   "Append to the word.";

Остаточний стан слова залишається на стеці.

Дякую Пітеру Тейлору за те, що він змусив мене переглянути це.


1
l~{_,g{('1=@(:Pa+@@P*+}*}*\;28 та ще можливість для покращення (особливо (:Pчастина), але час для обіду
Optimizer

@Optimizer Ах, гарна ідея. Дякую. І так, :Pмене також дратує: D
Мартін Ендер

l~{_,g{(si@(:Pa+@@P*+}*}*\;: 27, і після того, як вивчити це, :Pнасправді ефективно: P
Оптимізатор

_,gтакож можна замінити, _!!але такі самі байти.
Оптимізатор

@Optimizer Я також можу _{...}{}?тоді використовувати .
Мартін Ендер

2

Математика, 84 80 77 символів

f[_,w_,_]=w;f[p_,{x_,y___},n_/;n>0]:=f[RotateLeft@p,Flatten@{y,p~Take~x},n-1]

Приклад:

f[{{0, 1, 0}, {0, 0, 0}, {1, 1, 1, 1}}, {1, 1, 0, 0, 1}, 4]

{1, 0, 1, 0, 0, 0, 0}


2

Піт 22

Потрібні всі 3 аргументи як окремі входи.

#Vvw=z+tz*@Q%NlQshz)zq

Приймає такі аргументи, як:

11001
["010","000","1111"]
4

Пояснення:

                        : Implicit: z = input(); Q=eval(input())
#                       : Loop until an exception is thrown
 Vvw               )    : for N in range(eval(input()))
    =z                  : assign to z
      +tz               : the sum of the tail of z and
         *@Q%NlQ        : Q[N%len(Q)] times
                shz     : the numeric value of the first character in z
                    zq  : print z then throw exception

Пітон 2 - 61 67 91 105 124

c=lambda p,w,g:g*w and c(p[1:]+p[:1],w[1:]+w[0]*p[0],g-1)or w

Гарна відповідь Джо-Бази. Припускає, що порожнє виробництво є [[]].

Дякуємо @xnor за те, що він зазначив, що гольф о 2 ранку - це погане рішення.

Додаткова подяка @xnor, якому я, мабуть, завдячую 50% своєї оцінки.

Зразок:

>>> c([[0,1,0],[0,0,0],[1,1,1,1]],[1,1,0,0,1],4)
[1, 0, 1, 0, 0, 0, 0]

1
Звичайно , це коротше використовувати лямбда і просто писати g and wдля x? Крім того, я думаю, що g*wслід попрацювати над тим, щоб дати правдиве значення, коли обидва не gє нульовими та wнепусті.
xnor

Крім того, я не розумію внутрішнього if x else w. Чи не xзавжди це правда, тому що цей код виконується лише if xчи я щось пропускаю?
xnor

@xnor Звичайно, ви абсолютно праві :)
FryAmTheEggman

1
Ще трохи гольфу з and/ orтрюком та обертанням, pа не збільшенням n:c=lambda p,w,g:g*w and c(p[1:]+p[:1],w[1:]+w[0]*p[0],g-1)or w
xnor

@xnor Спасибі :) Крім того, тепер, коли ви зробили його функцією з 3 змінних, я думаю, що я перекладаю його на Pyth ...
FryAmTheEggman

1

Javascript ES6 - 88 байт

f=(p,w,g,n)=>g?w.replace(/(.)(.*)/,(_,a,b)=>f(p,a*1?b+p[(n=n||0)%p.length]:b,g-1,n+1)):w

Схоже, чудово схожа на відповідь Фрая, яка щойно вискакувала у моєму браузері. (Ні копіювання, я урочисто клянусь.)

Здавалося б, він пішов шляхом масиву, поки я пройшов шлях string / regex.

Розширено:

f = (p,w,g,n) =>
    g ?
        w.replace( /(.)(.*)/, (_,a,b) =>
            f( p, a*1 ? b + p[(n=n||0)%p.length] : b, g-1, n+1 )
        )
    :
        w

Вибірка зразка

f(['010','000','1111'],'11001',4)
"1010000"

Тепер дивіться, як увійшли мови гольфу та вбийте нас обох. : D


Я фактично видалив свою публікацію, оскільки отримував різні відповіді на два приклади. Ви пробували на прикладі, де він йде покоління в покоління? Здається, його вимкнули на один порівняно з повним прикладом виклику, який він дав ...
FryAmTheEggman

І не хвилюйтесь, я вважаю, що ви не копіювали мене: P
FryAmTheEggman

@FryAmTheEggman: Шахта послідовно генерує стовпчик "до" для номерного покоління. Це узгоджується з прикладом в ОП, і здається логічним, що "покоління 0" просто поверне вхід без його обробки, що відповідає цій інтерпретації. Між іншим, я додав відмову від «копіювання», оскільки рішення були в деяких аспектах незвично подібними. Ми використовували ті ж імена аргументів, ту ж саму основну рекурсивну структуру, і ми навіть додали той же Phantom четвертий аргумент, n. Чудові розуми, так? : D
COTO

Гаразд, я думаю, якщо хтось із нас помиляється, ми обидва помиляємось! Єдино ми стоїмо.
FryAmTheEggman

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