Fannkuch alfabetico


14

Fannkuch è un classico programma di benchmark. Il nome deriva dal tedesco "Pfannkuchen" - pancakes - per la somiglianza dell'algoritmo con il lancio di pile di pancake. Una sequenza di numeri Fannkuch è formata come segue:

Prendi una permutazione di {1 ..... n}, ad esempio: {4,2,1,5,3}. Prendi il primo elemento, qui 4, e inverti l'ordine dei primi 4 elementi: {5,1,2,4,3}. Ripeti fino a quando il primo elemento è 1, quindi il lancio non cambierà più nulla: {3,4,2,1,5}, {2,4,3,1,5}, {4,2,3, 1,5}, {1,3,2,4,5}

Devi scrivere un programma o una funzione che calcola una sequenza simile a Fannkuch per stringhe di caratteri alfabetici. Invece di usare i numeri per indicare quanti elementi dell'elenco dovrebbero essere capovolti ogni volta, dovrebbe essere usata la posizione di una lettera nell'alfabeto. Ad esempio, un lead cindica che è necessario invertire l'ordine dei primi 3 elementi, mentre un lead aindica che la sequenza è completa.

Ingresso

L'input verrà fornito come stringa tramite stdin o come argomento di funzione. La stringa conterrà tra 1 e 26 lettere minuscole distinte. Le stringhe non conterranno lettere il cui indice equivalente provocherebbe il capovolgimento dell'algoritmo Fannkuch di più elementi di quelli esistenti.

Produzione

I programmi o le funzioni dovrebbero tornare o stampare per stdout la sequenza di termini prodotti applicando l'algoritmo Fannkuch fino a quando non aviene rilevato un inizio, inclusa la stringa iniziale. Ad esempio, se l'input è bca, è possibile stampare:

bca
cba
abc

I risultati stampati possono utilizzare qualsiasi virgola di separazione ragionevole, newline, ecc. Qualsiasi scelta di spazi bianchi è accettabile.

Come altro esempio, se il tuo input è eabdcche potresti restituire:

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

Regole e punteggio

Questo è : vince il programma più breve. Le scappatoie standard non sono ammesse.

Risposte:


11

Pyth, 16 byte

.u+_<NJhxGhN>NJz

Dimostrazione.

La funzione "ripeti finché non smette di cambiare" delle funzioni di riduzione di Pyth è davvero utile qui. Questo è usato con .u, la funzione di riduzione cumulativa, per produrre tutti i risultati. Il corpo del riduttore è il più ingenuo possibile, ma non sono riuscito a trovare niente di meglio.


5

T-SQL, 213 byte

Naturalmente essendo SQL è davvero grande, ma era interessante da fare. Creato come una funzione di tabella incorporata utilizzando una query CTE ricorsiva.

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

allargato

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

Usato come segue

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

(5 row(s) affected)

4

CJam, 22 byte

Questa è una funzione anonima che accetta una stringa nello stack e restituisce un elenco di stringhe nello stack.

{_,{_0='`-/(W%\+s_}*]}

Provalo online qui


3

Python 2, 59 byte

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

Immagino che questa sia una risposta piuttosto semplice. Usa la ricorsione e la sintassi dello slice di Python. Chiamata come: p('eabdc').


3

SAS, 131 byte

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;

Una routine di chiamata FCMP. Nongolfato di seguito (con un controllo extra consiglio vivamente quando SAS si blocca se una routine FCMP entra in un ciclo infinito).


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;

Bel lavoro. Non c'è molto da proc fcmpqueste parti.
Alex A.

2

Haskell, 78 byte

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

Utilizzo: f "eabdc"-> ["eabdc","cdbae","bdcae","dbcae","acbde"].


splitAtprendi in considerazione l'utilizzo : puoi ridurlo a 71 byte!
MtnViewMark,

@MtnViewMark mi sembra di avere lo stesso algoritmo, fino a 68 byte
orgoglioso haskeller il

2

K5, 21 byte

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

5 byte salvati grazie a @JohnE e un altro byte riorganizzando un'espressione.

Per la prima volta sulla Terra, penso che K abbia battuto CJam!

Versione a 27 byte

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

Puoi renderlo un po 'più breve se usi la forma a virgola fissa di "scan".
Giovanni,

@JohnE Grazie! Non mi rendevo conto che, quando la prima lettera è an a, la stringa non cambierà.
Kirbyfan64sos,

0

Haskell, 68

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

Qualsiasi altra tattica più complicata a cui ho pensato ha richiesto più byte.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.