Alfabético Fannkuch

14

Fannkuch es un programa de referencia clásico. El nombre proviene del alemán "Pfannkuchen" - panqueques - por la semejanza del algoritmo con voltear pilas de panqueques. Una secuencia de números de Fannkuch se forma de la siguiente manera:

Tome una permutación de {1 ..... n}, por ejemplo: {4,2,1,5,3}. Tome el primer elemento, aquí 4, e invierta el orden de los primeros 4 elementos: {5,1,2,4,3}. Repita esto hasta que el primer elemento sea un 1, por lo que voltear no cambiará nada más: {3,4,2,1,5}, {2,4,3,1,5}, {4,2,3, 1,5}, {1,3,2,4,5}

Debe escribir un programa o función que calcule una secuencia tipo Fannkuch para cadenas de caracteres alfabéticos. En lugar de usar números para indicar cuántos elementos de la lista se deben voltear cada vez, se debe usar la posición de una letra en el alfabeto. Por ejemplo, un cinicio indicaría que debe invertir el orden de los primeros 3 elementos, mientras que un inicio aindica que la secuencia está completa.

Entrada

La entrada se proporcionará como una cadena a través de stdin o como un argumento de función. La cadena contendrá entre 1 y 26 letras minúsculas distintas. Las cadenas no contendrán letras cuyo índice equivalente haría que el algoritmo Fannkuch voltee más elementos de los que existen.

Salida

Los programas o funciones deben regresar o imprimirse para mostrar la secuencia de términos producidos al aplicar el algoritmo de Fannkuch hasta encontrar un ainicio, incluida la cadena inicial. Por ejemplo, si la entrada es bca, puede imprimir:

bca
cba
abc

Los resultados impresos pueden usar cualquier separador razonable: comas, líneas nuevas, etc. Cualquier opción de espacio en blanco es aceptable.

Como otro ejemplo, si su entrada es eabdcpuede devolver:

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

Reglas y puntuación

Este es el : gana el programa más corto. Las lagunas estándar no están permitidas.

JohnE
fuente

Respuestas:

11

Pyth, 16 bytes

.u+_<NJhxGhN>NJz

Demostración.

La función "repetir hasta que deje de cambiar" de las funciones de reducción de Pyth es realmente útil aquí. Esto se usa con .ula función de reducción acumulativa para generar todos los resultados. El cuerpo de la reducción es tan ingenuo como puede ser, pero no pude encontrar nada mejor.

isaacg
fuente
5

T-SQL, 213 bytes

Por supuesto, ser SQL es realmente grande, pero fue interesante hacerlo. Creado como una función de tabla en línea utilizando una consulta CTE recursiva.

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

Expandido

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

Usado de la siguiente manera

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

(5 row(s) affected)
MickyT
fuente
4

CJam, 22 bytes

Esta es una función anónima que toma una cadena en la pila y devuelve una lista de cadenas en la pila.

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

Pruébalo en línea aquí

Optimizador
fuente
3

Python 2, 59 bytes

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

Supongo que esta es una respuesta bastante sencilla. Utiliza la recursividad y la sintaxis de corte de Python. Llamar como: p('eabdc').

Mathmandan
fuente
3

SAS, 131 bytes

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 rutina de llamada FCMP. A continuación, no está incluido (con una comprobación adicional, recomiendo encarecidamente que SAS se bloquee si una rutina FCMP entra en un bucle 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;
Joe
fuente
Buen trabajo. No tenemos mucho proc fcmppor aquí.
Alex A.
2

Haskell, 78 bytes

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

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

nimi
fuente
considere usar splitAt- ¡puede reducirlo a 71 bytes!
MtnViewMark
@MtnViewMark bueno, parece que tengo exactamente el mismo algoritmo, hasta 68 bytes
orgulloso Haskeller
2

K5, 21 bytes

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

Ahorró 5 bytes gracias a @JohnE y otro byte reorganizando una expresión.

¡Por primera vez en la tierra, creo que K ha vencido a CJam!

Versión de 27 bytes

(~97=*){(|v#x),(v:-96+*x)_x}\
kirbyfan64sos
fuente
Puede hacer esto un poco más corto si utiliza la forma de "escaneo" de punto fijo.
JohnE
@JohnE ¡Gracias! No me di cuenta de que, cuando la primera letra es una a, la cadena no cambiará.
kirbyfan64sos
0

Haskell, 68

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

Cualquier táctica más complicada en la que pensé tomó más bytes.

orgulloso Haskeller
fuente