Алфавітний Фаннкух


14

Fannkuch - класична орієнтирова програма. Назва походить від німецького "Pfannkuchen" - млинці - за схожістю алгоритму з перегортанням стосів млинців. Послідовність чисел у Фаннкуха формується наступним чином:

Візьміть перестановку {1 ..... n}, наприклад: {4,2,1,5,3}. Візьміть перший елемент, тут 4, і переверніть порядок перших 4 елементів: {5,1,2,4,3}. Повторіть це, поки перший елемент не стане 1, тож гортання більше нічого не змінить: {3,4,2,1,5}, {2,4,3,1,5}, {4,2,3, 1,5}, {1,3,2,4,5}

Ви маєте написати програму або функцію, яка обчислює послідовність, що нагадує Фаннкуч, для рядків алфавітних символів. Замість використання цифр для вказівки, скільки елементів списку слід перегортати кожного разу, слід використовувати літеру в алфавіті. Наприклад, ведучий cвказує на те, що слід змінити порядок перших 3 елементів, тоді як ведучий aвказує на те, що послідовність завершена.

Вхідні дані

Введення надається у вигляді рядка через stdin або як аргумент функції. Рядок буде містити від 1 до 26 різних малих літер. Рядки не містять букв, еквівалентний індекс яких призведе до того, що алгоритм Fannkuch переверне більше елементів, ніж існує.

Вихідні дані

Програми або функції повинні повертати або друкувати, щоб викреслити послідовність термінів, створених за допомогою застосування алгоритму Fannkuch, поки aне зустрінеться ведучий , включаючи початковий рядок. Наприклад, якщо введення є bca, ви можете надрукувати:

bca
cba
abc

Для друкованих результатів можна використовувати будь-які розумні роздільники, коми, нові рядки тощо. Будь-який вибір пробілу є прийнятним.

Як інший приклад, якщо ви введете дані, eabdcви можете повернутись:

("eabdc"
 "cdbae"
 "bdcae"
 "dbcae"
 "acbde")

Правила та підрахунок балів

Це - виграє найкоротша програма. Стандартні лазівки заборонені.

Відповіді:


11

Pyth, 16 байт

.u+_<NJhxGhN>NJz

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

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


5

T-SQL, 213 байт

Звичайно, що це SQL, він дійсно великий, але це було цікаво зробити. Створений у вигляді функції вбудованої таблиці за допомогою рекурсивного запиту CTE.

CREATE FUNCTION F(@ CHAR(26))RETURNS TABLE RETURN WITH R AS(SELECT @ S UNION ALL SELECT CAST(STUFF(S,1,ASCII(LEFT(S,1))-96,REVERSE(LEFT(S,ASCII(LEFT(S,1))-96)))AS CHAR(26))FROM R WHERE LEFT(S,1)<>'a')SELECT*FROM R

Розширено

CREATE FUNCTION F(@ CHAR(26))
RETURNS TABLE 
RETURN WITH R AS(
    SELECT @ S            -- Initial string as an anchor for the recursion
    UNION ALL 
    SELECT CAST(
        STUFF(                                    -- Stuff into 
            S,                                    -- string S
            1,                                    -- from position 1
            ASCII(LEFT(S,1))-96,                  -- to index value of first char
            REVERSE(LEFT(S,ASCII(LEFT(S,1))-96))  -- the reverse of the index first chars
            )
        AS CHAR(26))
    FROM R 
    WHERE LEFT(S,1)<>'a'  -- recurse until first char is a
)SELECT*FROM R

Використовується наступним чином

SELECT * FROM F('eabdc')
S
--------------------------
eabdc                     
cdbae                     
bdcae                     
dbcae                     
acbde                     

(5 row(s) affected)


3

Python 2, 59 байт

def p(l):
 print l;o=ord(l[0])-97
 if o:p(l[o::-1]+l[o+1:])

Я думаю, це досить відверта відповідь. Використовує рекурсію та синтаксис фрагмента Python. Телефонуйте , як: p('eabdc').


3

SAS, 131 байт

sub a(s$);outargs s;put s;do while(b ne 1);b=rank(char(s,1))-96;substr(s,1,b)=reverse(substr(s,1,b));if b>1 then put s;end;endsub;

Порядок дзвінків FCMP. Nongolfed внизу (з додатковою перевіркою, я настійно рекомендую, оскільки SAS виходить з ладу, якщо FCMP рутина входить у нескінченний цикл).


options cmplib=work.funcs;
proc fcmp outlib=work.funcs.funcs;
  sub a(s$);
    outargs s;
    put s=;
    do while (b ne 1 and z<1e5);
        b=rank(char(s,1))-96;
        substr(s,1,b) = reverse(substr(s,1,b));
        if b>1 then put s=;
        z+1;
    end;
  endsub;
quit;

Хороша робота. Нас тут не так багато proc fcmp.
Алекс А.

2

Haskell, 78 байт

f l@(h:_)|h=='a'=[l]|1<2=l:f(reverse(take d l)++drop d l)where d=fromEnum h-96

Використання: f "eabdc"-> ["eabdc","cdbae","bdcae","dbcae","acbde"].


Подумайте про використання splitAt- ви можете зменшити його до 71 байт!
MtnViewMark

@MtnViewMark добре, що, здається, у мене такий самий алгоритм, аж до 68 байт
гордий haskeller

2

К5, 21 байт

{(|v#x),(v:*x-96)_x}\

Збережено 5 байт завдяки @JohnE та іншому байтові, переставляючи вираз.

Вперше на землі я думаю, що K побив CJam!

27-байтна версія

(~97=*){(|v#x),(v:-96+*x)_x}\

Ви можете зробити це трохи коротше, якщо використовувати фіксовану форму "сканування".
JohnE

@JohnE Дякую! Я не усвідомлював, що, коли перша буква є,, aрядок не зміниться.
kirbyfan64sos

0

Хаскелл, 68 років

f l@(x:_)|x<'b'=[l]|(x,y)<-splitAt(fromEnum x-96)l=l:f(reverse x++y)

Будь-яка більш складна тактика, яку я думав, взяла більше байтів.

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