Alphabetisches Fannkuch


14

Fannkuch ist ein klassisches Benchmark-Programm. Der Name kommt vom deutschen "Pfannkuchen", der die Ähnlichkeit des Algorithmus mit dem Umdrehen von Pfannkuchenstapeln beschreibt. Eine Fannkuch-Folge von Zahlen wird wie folgt gebildet:

Nehmen Sie eine Permutation von {1 ..... n}, zum Beispiel: {4,2,1,5,3}. Nehmen Sie das erste Element, hier 4, und kehren Sie die Reihenfolge der ersten 4 Elemente um: {5,1,2,4,3}. Wiederholen Sie dies, bis das erste Element eine 1 ist, damit das Spiegeln nichts mehr ändert: {3,4,2,1,5}, {2,4,3,1,5}, {4,2,3, 1,5}, {1,3,2,4,5}

Sie müssen ein Programm oder eine Funktion schreiben, die eine Fannkuch-ähnliche Sequenz für Zeichenfolgen aus alphabetischen Zeichen berechnet. Anstatt Zahlen zu verwenden, um anzugeben, wie viele Elemente der Liste jedes Mal umgedreht werden sollen, sollte die Position eines Buchstabens im Alphabet verwendet werden. Ein vorangestellter Punkt bedeutet beispielsweise, cdass Sie die Reihenfolge der ersten drei Elemente umkehren sollten, während ein vorangestellter aPunkt angibt, dass die Sequenz abgeschlossen ist.

Eingang

Die Eingabe erfolgt als String über stdin oder als Funktionsargument. Die Zeichenfolge enthält zwischen 1 und 26 verschiedene Kleinbuchstaben. Strings enthalten keine Buchstaben, deren äquivalenter Index dazu führen würde, dass der Fannkuch-Algorithmus mehr Elemente spiegelt, als vorhanden sind.

Ausgabe

Programme oder Funktionen sollten die durch Anwendung des Fannkuch-Algorithmus erzeugte Abfolge von Begriffen zurückgeben oder drucken, bis ein führendes Zeichen aeinschließlich der Anfangszeichenfolge angetroffen wird. Wenn die Eingabe beispielsweise lautet bca, können Sie Folgendes drucken:

bca
cba
abc

Für gedruckte Ergebnisse können alle sinnvollen Trennzeichen, Zeilenumbrüche usw. verwendet werden. Es kann ein beliebiges Leerzeichen gewählt werden.

Wenn Sie als weiteres Beispiel Folgendes eingeben, können eabdcSie Folgendes zurückgeben:

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

Regeln und Wertung

Das ist - das kürzeste Programm gewinnt. Standard-Regelungslücken sind nicht zulässig.

Antworten:


11

Pyth, 16 Bytes

.u+_<NJhxGhN>NJz

Demonstration.

Die Funktion "Wiederholen, bis sich nichts mehr ändert" in Pyths Reduktionsfunktionen ist hier sehr praktisch. Dies wird mit .uder kumulativen Reduktionsfunktion verwendet, um alle Ergebnisse auszugeben. Der Körper des Reduces ist so naiv wie nur möglich, aber ich konnte nichts Besseres finden.


5

T-SQL, 213 Bytes

Natürlich ist SQL sehr umfangreich, aber es war interessant zu tun. Erstellt als Inline-Tabellenfunktion mithilfe einer rekursiven CTE-Abfrage.

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

Erweitert

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

Wird wie folgt verwendet

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

(5 row(s) affected)


3

Python 2, 59 Bytes

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

Ich denke, das ist eine ziemlich einfache Antwort. Verwendet Rekursion und Pythons Slice-Syntax. Rufen wie: p('eabdc').


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;

Eine FCMP-Aufrufroutine. Nongolfed weiter unten (mit einer zusätzlichen Überprüfung, die ich sehr empfehlen kann, da SAS abstürzt, wenn eine FCMP-Routine in eine Endlosschleife eintritt).


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;

Gute Arbeit. Wir kommen hier nicht viel proc fcmprum.
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

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


Erwägen Sie die Verwendung splitAt- Sie können es auf 71 Bytes reduzieren!
MtnViewMark

@MtnViewMark Nun, ich scheine den exakt gleichen Algorithmus zu haben, bis auf 68 Bytes
stolzer Haskeller

2

K5, 21 Bytes

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

5 Bytes dank @JohnE und ein weiteres Byte durch Neuanordnen eines Ausdrucks gespart.

Zum ersten Mal auf der Welt, denke ich, hat K CJam geschlagen!

27-Byte-Version

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

Sie können dies etwas kürzer machen, wenn Sie die Festkommaform "Scan" verwenden.
JohnE

@ JohnE Danke! Ich wusste nicht, dass sich adie Zeichenfolge nicht ändert , wenn der erste Buchstabe ein ist .
kirbyfan64sos

0

Haskell, 68

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

Jede kompliziertere Taktik, an die ich dachte, brauchte mehr Bytes.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.