Створіть дійсні облицювання Фібоначчі


9

Фон

Плитка Фібоначчі - це плитка лінії (1D), що використовує два сегменти: короткий, S та довгий, L (їх відношення довжини - це золоте співвідношення, але це не стосується цієї проблеми). Щоб плитка з використанням цих двох прототилів фактично була плиткою Фібоначчі, повинні бути виконані наступні умови:

  • Плитка не повинна містити послідовності SS .
  • Черепиця не повинна містити підсвічування LLL .
  • Якщо нова плитка складається з виконання всіх наступних підстановок, результатом все одно повинен бути плитка Фібоначчі:
    1. LLS
    2. SL
    3. L(порожній рядок)

Давайте розглянемо кілька прикладів:

SLLSLLSLLSLS

Це виглядає як дійсна плитка, оскільки вона не містить двох * S * s або трьох * L * s, але давайте виконаємо композицію:

LSLSLSLL

Це все ще виглядає чудово, але якщо ми знову складемо це, отримаємо

LLLS

що не є дійсною плиткою Фібоначчі. Тому дві попередні послідовності також не були допустимими.

З іншого боку, якщо ми почнемо з

LSLLSLSLLSLSLL

і неодноразово складати це для коротших послідовностей

LSLLSLLS
LSLSL
LL
S

всі результати є дійсними нахилами Фібоначчі, оскільки ми ніколи не отримуємо SS або LLL ніде всередині цих рядків.

Для подальшого читання існує теза, яка використовує цю плитку як просту 1D-аналогію обшивці Пенроуза.

Змагання

Напишіть програму або функцію, яка, отримавши невід'ємне ціле число N , повертає всі дійсні черепиці Фібоначчі у вигляді рядків, що містять N символів (буття Sабо L).

Ви можете взяти введення через аргумент функції, STDIN або ARGV і повернути або роздрукувати результат.

Це кодовий гольф, найкоротша відповідь (у байтах) виграє.

Приклади

N      Output
0      (an empty string)
1      S, L
2      SL, LS, LL
3      LSL, SLS, LLS, SLL
4      SLSL, SLLS, LSLS, LSLL, LLSL
5      LLSLL, LLSLS, LSLLS, LSLSL, SLLSL, SLSLL
...
8      LLSLLSLS, LLSLSLLS, LSLLSLLS, LSLLSLSL, LSLSLLSL, SLLSLLSL, SLLSLSLL, SLSLLSLL, SLSLLSLS

Це має бути LSLSL-> LL?

@tolos Ага, хороший улов. Я це зафіксував. FYI, це сталося тому, що я насправді генерував рядок навпаки, починаючи знизу, використовуючи подібні правила декомпозиції, і вони не є точно оборотними, коли мова йде про межі фрагмента.
Мартін Ендер

Відповіді:


4

CJam, 70 62 59 байт

Qali{_'L:Xf+\'S:Yf++}*{{_X2*/Xf-Yf/Xf*Y*}h]N*_X3*#\Y2*#=},p

Читає від STDIN. Спробуйте в Інтернеті.

Приклад виконання

$ cjam tilings.cjam <<< 5
["LLSLL" "SLSLL" "SLLSL" "LSLSL" "LSLLS" "LLSLS"]

Як це працює

Ідея полягає в тому, щоб висунути всі рядки L і S належної довжини, послідовно застосувати перетворення до кожного, поки результат не буде порожнім рядком, об'єднати послідовності рядків і шукати заборонені підрядки.

Qa         " Push R := [ '' ].                                                            ";
li{        " Do the following int(input()) times:                                         ";
  _'L:Xf+  " Append (X := 'L') to a copy of all strings in R.                             ";
  \'S:Yf+  " Append (Y := 'S') to all original strings in R.                              ";
  +        " Concatenate the arrays into R.                                               ";
}*         " R now contains all strings of L's and S's of length int(input()).            ";
{          " For each S ∊ R:                                                              ";
  {        "                                                                              ";
    _      " Push a copy of S.                                                            ";
    X2*/   " Split S at 'LL'.                                                             ";
    Xf-    " Remove 'L' from the chunks.                                                  ";
    Yf/    " Split the chunks at 'S'.                                                     ";
    Xf*    " Join the chunks, separating by 'L'.                                          ";
    Y*     " Join, separating by 'S'.                                                     ";
  }h       " If the resulting string is non-empty, repeat.                                ";
  ]N*      " Join the array of resulting strings from S to '', separating by linefeeds.   ";
  _X3*#    " Push the index of 'LLL' a copy in the resulting string (-1 if not present).  ";
  \Y2*#    " Push the index of 'SS' in the original string (-1 if not present).           ";
  =        " Check if the indexes are equal; this happens if and only if both are -1.     ";
},         " Filter: Keep S in R if and only if = pushed 1.                               ";
p          " Print a string representation of R.                                          ";

3

GolfScript (86 байт)

~:|'LS'1/\{{.{1&!'LLS'2/=}%'SS'/'SLS'*[.(1&{'LS'\+}*]{.)1&{'SL'+}*}/}%.&}*['']+{,|=},p

Це інфляційний підхід: вона починається з Lі Sі розширює їх , використовуючи правила LL -> SLS, L -> S, S -> LLі початкові або кінцеві Sможуть мати Lдодані на кордоні слова.

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


@ MartinBüttner, як правило, я б посилався на інтернет-демонстрацію з golfscript.apphb.com, але він працює зі старою версією з помилкою навколо вкладених циклів (зафіксовано у випуску 3 грудня 2012 року ) і не може правильно виконати цю програму.
Пітер Тейлор

3
@ MartinBüttner На жаль Спасибі хлопці за те, що повідомили про помилку. Я оновив веб-сайт новою версією GS. Клацніть це посилання для демонстрації.
Крістіан Лупаску

@ w0lf, дякую за оновлення (і за нещодавню зміну, щоб також збільшити часовий ліміт).
Пітер Тейлор

1

Хаскелл, 217

import Control.Monad
data F=L|S deriving (Eq)
f n=filter s$replicateM n [L,S]
r (L:L:m)=S:r m
r (S:m)=L:r m
r (L:m)=r m
r []=[]
s []=True
s m|v m=s$r m
s _=False
v (L:L:L:_)=False
v (S:S:_)=False
v (_:m)=v m
v []=True

Пояснення:

Я визначаю 4 функції:

  • f приймає ціле число і повертає результат

    replicateM n [L,S]створює всі можливі перестановки [L,S]з довжиною n filter s ..., фільтрує цей список (списки) за допомогою функціїs

  • r зменшує даний список на 1 рівень.

    Це просто робиться шляхом узгодження шаблону. Список, що починається з 2 L, стане списком, починаючи з Sзменшеного

  • v підтверджує даний список за наведеними правилами (немає 3 безперервних L, немає 2 безперервних S)

    якщо список починається з однієї з 2-х незаконних послідовностей (L, L, L або S, S), результат є Falseпорожнім списком дійсним, а не порожній список перевіряється знову, коли перший елемент видалений

  • s перевіряє, чи є список та всі скорочені списки дійсними.

    Знову: порожній список дійсний (і його далі не можна зменшити).
    Якщо список, наведений як аргумент, є дійсним, то список зменшується s.
    Інакше результат єFalse

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