Генерация действительных значений Фибоначчи

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 внутри этих строк.

Для дальнейшего чтения есть тезис, в котором эта мозаика используется как простая одномерная аналогия мозаики Пенроуза.

Соревнование

Напишите программу или функцию, которая, учитывая неотрицательное целое число 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 Ах да, хороший улов. Я исправил это. К вашему сведению, это произошло потому, что я на самом деле сгенерировал строку наоборот, начиная снизу, используя похожие правила декомпозиции, и они не совсем обратимы, когда дело доходит до границ фрагмента.
Мартин Эндер

Ответы:

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

Explaination:

Я определяю 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

Йоханнес Кун
источник