Rollen Sie den Teppich

15

Diese Frage ist von Kevin Cruijssens Frage inspiriert .

Jetzt, wo der Teppich ausgelegt ist, wollen wir ihn rollen. Ihre Aufgabe ist es, ein Programm zu schreiben, das eine Schnur nimmt und eine aus dieser Schnur hergestellte Spirale zurückgibt (die einen gerollten Teppich darstellt, von der Seite gesehen).

Das Verfahren für einen Schritt des Rollens des Teppichs ist das folgende. Es gibt ein Beispiel, um zu veranschaulichen, was ich meine. Beachten Sie, dass das Beispiel zum besseren Verständnis mit einem teilweise gerollten Teppich beginnt:

ac
rpet
  • trenne den "Kopf" vom "Schwanz" des Teppichs: der Kopf ist das, was bisher gerollt wurde, der Schwanz ist das, was noch gerollt werden muss.
Head: ac   Tail:
      rp          et
  • Drehen Sie den Kopf um 90 ° im Uhrzeigersinn.
Rotated head: ra   Tail (unchanged):
              pc                       et
  • wenn die Breite des neuen Kopfes (hier 2) kleiner oder gleich der Länge des Schwanzes ist (hier 2)
    • Dann lege es oben auf den Schwanz
    • Ansonsten wurde der Teppich (wie zu Beginn des Schritts) gerollt
New carpet: ra
            pc
            et

Wiederholen Sie den Vorgang so oft wie nötig.


Zwei Beispiele, die alle Schritte des Teppichrollens zeigen:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

Einige Präzisionen:

  • Sie müssen nicht alle Zwischenschritte anzeigen, sondern nur den gerollten Teppich (z. B. ist es perfekt, wenn Sie eine nicht iterative Methode zur Berechnung des Ergebnisses finden). Außerdem müssen Sie keine führenden Leerzeichen drucken. In den obigen Beispielen zeige ich sie nur zum Ausrichten von Elementen.
  • Die Eingabe ist ein String, eine Liste / ein Array von Zeichen
  • Die Ausgabe erfolgt als Standardausgabe oder als Datei.
  • Die Eingabe ist nett: Die Länge beträgt mindestens 1 Zeichen und höchstens eine Konstante, die klein genug ist, um keine Probleme zu verursachen, aber Sie können diese Konstante nicht in Ihrem Programm verwenden. Der Inhalt der Zeichenfolge besteht nur aus netten Zeichen ([a-zA-Z0-9]), die nach Ihren Wünschen codiert werden.
  • Das ist , also gewinnt die kürzeste Antwort in Bytes. Lassen Sie sich von Code-Golf-Sprachen nicht davon abhalten, Antworten mit Nicht-Codegolf-Sprachen zu veröffentlichen. Versuchen Sie, für jede Programmiersprache eine möglichst kurze Antwort zu finden.
  • Standardlücken sind verboten.
  • Fügen Sie nach Möglichkeit einen Link mit einem Test für Ihren Code hinzu.
  • Fügen Sie außerdem eine Erklärung für Ihre Antwort hinzu, wenn Sie der Meinung sind, dass dies erforderlich ist.
Bromind
quelle
3
Eng verwandt
Giuseppe
2
Auch dieses hier: codegolf.stackexchange.com/questions/125966/… , aber keines beinhaltet die Kündigungsprüfung.
Bromind
3
Vorgeschlagener Testfall: ProgrammingPuzzlesAndCodeGolf- Die endgültige Schwanzlänge größer als 1 hat mich gestolpert.
Sok
1
Ich denke, Sie haben hier die Wörter "Kopf" und "Schwanz" getauscht: "wenn die Breite des neuen Kopfes [...] größer oder gleich der Länge des Schwanzes ist [...]".
Erik der Outgolfer
1
Abgestimmt wegen zu restriktiver Eingabe- / Ausgaberegeln; Ich habe meine Python 2-Antwort gelöscht, da man sie nicht printin a verwenden kann lambda.
Chas Brown

Antworten:

7

Kohle , 15 Bytes

FS«F¬℅§KV⁰⟲⁶→Pι

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

FS«

Schlinge dich über den Teppich.

F¬℅§KV⁰

Überprüfen Sie, ob sich etwas über dem Cursor befindet.

⟲⁶

Wenn nicht, dann rollen Sie den Teppich.

→Pι

Bewegen Sie sich nach rechts und geben Sie das aktuelle Zeichen aus.

Beispiel: Für die Eingabe 0123456789werden folgende Aktionen ausgeführt:

0

0 gedruckt wird.

01

Der Cursor bewegt sich nach rechts und 1wird gedruckt.

0
1

Da sich nichts über dem befindet 1, wird die Leinwand gedreht.

0
12

Der Cursor bewegt sich nach rechts und das 2wird gedruckt.

10
2

Da sich nichts über dem befindet 2, wird die Leinwand gedreht.

10
23

Der Cursor bewegt sich nach rechts und das 3wird gedruckt.

10
234

Der Cursor bewegt sich nach rechts und das 4wird gedruckt.

21
30
4

Da sich nichts über dem befindet 4, wird die Leinwand gedreht.

21
30
45

Der Cursor bewegt sich nach rechts und das 5wird gedruckt.

21
30
456

Der Cursor bewegt sich nach rechts und das 6wird gedruckt.

432
501
6

Da sich nichts über dem befindet 6, wird die Leinwand gedreht.

432
501
67

Der Cursor bewegt sich nach rechts und das 7wird gedruckt.

432
501
678

Der Cursor bewegt sich nach rechts und das 8wird gedruckt.

432
501
6789

Der Cursor bewegt sich nach rechts und das 9wird gedruckt.

Neil
quelle
Das ist großartig. Also hat Charcoal im Grunde einen eingebauten "Roll" -Operator ?
Jonah
1
@Jonah Nun, es wird nicht für mich rollen, wie es geht, aber durch die Ausgabe der Zeichenfolge Zeichen für Zeichen kann ich rollen, wie ich gehe, ja.
Neil
3

Pyth, 37 Bytes

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQt

Versuchen Sie es online hier oder überprüfen alle Testfälle auf einmal hier .

.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQtQ   Implicit: Q=eval(input())
                                         Trailing Q inferred
                                 ]hQ     First character of Q, wrapped in an array
                                    tQ   All but the first character of Q
                                ,        2-element array of the two previous results
                                           This yields array with rolled carpet (as array of strings) followed by the tail
       .W                                While condition function is truthy, execute inner function, with initial value of the above:
         gleHJlhH                          Condition function, input H
             JlhH                            Number of layers in the current rolled carpet, store in J
          leH                                Lenth of the tail
         g   J                               Is the above greater than or equal to J?
                 ,+_MChZ<eZJ>eZJ           Inner function, input Z
                   _MChZ                     Rotate the current rolled carpet (transpose, then reverse each row)
                  +     <eZJ                 Append the first J characters of the tail as a new row
                 ,                           Pair the above with...
                            >eZJ             ... all but the first J characters of the tail - this is the new tail
.U+j;bZ                                  Join the carpet roll on newlines and append the tail, implicit print
Sok
quelle
3

Schale , 24 Bytes

►S=ÖLmFȯ:T↔ø§z:oΘḣĠ+CṘ2N

Probieren Sie es online!

Erläuterung

Implicit input, say s="carpets"

CṘ2N  Break s into chunks:
   N   Natural numbers: [1,2,3,4,..
 Ṙ2    Repeat each twice: [1,1,2,2,3,3,4,4,..
C      Break s into chunks of these lengths: ["c","a","rp","et","s"]
       The last chunk is shorter if we run out of characters.

§z:oΘḣĠ+  Attempt to merge suffix of chunks:
      Ġ    Cumulative reduce chunk list from right
       +   by concatenation: ["carpets","arpets","rpets","ets","s"]
   oΘḣ     Prefixes of chunk list (empty and nonempty): [[],["c"],..,["c","a","rp","et","s"]]
§z         Zip these by
  :        appending: [["carpets"],["c","arpets"],..,["c","a","rp","et","s"]]
           These are all versions of the chunk list where some suffix has been merged.

mFȯ:T↔ø  Roll each list:
m         Map
 F        reduce from left
      ø   starting from empty character matrix
  ȯ:T↔    by this function:
    T↔     Reverse and transpose (rotating by 90 degrees)
  ȯ:       then append next chunk as new row.
         Result: [["carpets"],["c","arpets"],..,["epr","tca","s"]]

►S=ÖL  Select the matrix rolled by the correct amount:
►       Find element that maximizes
 S=     being equal to
   ÖL   sort by length.
        This selects a matrix whose rows have non-decreasing lengths.
        Ties are broken by choosing the rightmost one.
       Result: ["ra","pc","ets"]

Implicitly print each row separated by newlines.
Zgarb
quelle
2

J , 69 Bytes

-3 Bytes dank FrownyFrog

[:(}:@[,{:@[,])&>/[:((|:@|.@[,#@[$]);#@[}.])&>/^:(<:&#&>/)^:_,.@{.;}.

Probieren Sie es online!

Erläuterung

[: (}:@[ , {:@[ , ])&>/ [: ((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/^:(<:&#&>/)^:_ }. ;~ 1 1 $ {.

Der Algorithmus ist unkompliziert, obwohl er für J etwas ausführlich ist.

Gesamtstrategie: Reduzieren Sie die Eingabe auf einen quadratischen Tisch mit einem (möglicherweise leeren) Reststück.

Beim Reduzieren verwenden wir eine Liste mit 2 Elementen. Unser "bisheriges Ergebnis" ist die erste Box, und "noch zu bearbeitende Artikel" ist die zweite Box. Das erste Feld wird mit dem Kopf der Eingabe initialisiert (aber in eine Tabelle konvertiert):

1 1 $ {.

und "noch zu bearbeitende Elemente" ist der Schwanz der Eingabe:

}. ;~

Jetzt haben wir:

┌─┬─────┐
│c│arpet│
└─┴─────┘

wobei das 'c' eigentlich eine 1x1-Tabelle ist.

Wir reduzieren das mit einer J Do ... While-Schleife:

^:(...)^:_

Wo der Teil in Klammern die Bedingung "weitermachen" ist:

<:&#&>/

welches sagt "mach weiter so lange die Länge des rechten Kastens größer oder gleich der Länge des linken Kastens ist (dh die Seitenlänge der quadratischen Matrix)

Was bedeutet "weitermachen"? ^:Dies ist im Verb links vom ersten definiert , das uns sagt, wie wir das aktuelle Ergebnis nehmen und die nächste Iteration erzeugen. Das Verb ist:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/

Lassen Sie es uns aufschlüsseln:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/
(  verb in parens               )&>/ NB. put the verb in parens
                                     NB. between the two items
                                     NB. of our list, and unbox
                                     NB. them into left / right
                                     NB. args ([ / ]) for the verb
 (|:@|.@[ , #@[ {. ]) ; #@[ }. ]     NB. breaking down verb in 
                                     NB. parens...
                      ; ....         NB. new "remaining items":
                            }. ]     NB. remove from remaining
                        #@[          NB. the size of a side of
                                     NB. the result matrix
                ....  ;              NB. new "result":
  |:@|.@[                            NB. rotate existing result
          ,                          NB. and put it on top of
            #@[ {. ]                 NB. the items we removed
                                     NB. from remaining items

Das heißt, dies ist nur der im OP beschriebene Algorithmus, der wörtlich in J übersetzt wurde.

Schließlich beschäftigen wir uns mit den (möglicherweise 0) verbleibenden Gegenständen, dem Schwanz unserer Teppichrolle:

(}:@[ , {:@[ , ])&>/

Dies sagt "nimm alle außer der letzten Ulme des Ergebnisses":

}:@[ 

und an ,die letzten Elemente des Ergebnisses anhängen, {:@[wobei die übrigen Elemente an das letzte Element angehängt werden, ]

Jona
quelle
Ah, J ... Briefe sind für Noobs
RK.
,.kann tun, was 1 1$]tut und $kann als verwendet werden {..
FrownyFrog
@ FrownyFrog ty. Ich habe es mit Ihrem ersten Vorschlag auf 70 Byte gebracht , war mir aber nicht sicher, ob ich es verstanden habe $ can be used as {.- können Sie das klären?
Jonah,
1
In der letzten Zeile der Erklärung verwenden Sie {. zu beschneiden, dass man ein $ sein kann, soweit ich das verstehe.
FrownyFrog
Sie können auch das Recht [ersetzen: mit einem @
FrownyFrog
1

R , 146 132 Bytes

function(s){m=F[F]
while({m=rbind(t(m)[,F:0],s[1:F])
s=s[-1:-F]
length(s)>sum(F<-dim(m))})0
write(m[F:1,],1,F[1],,"")
cat(s,sep="")}

Probieren Sie es online!

Implementiert den Teppichrollvorgang. Übernimmt die Eingabe als Liste von Zeichen und druckt auf Standardausgabe.

Es wurden 14 Bytes gespart, indem eine Möglichkeit zur Verwendung einer do-whileSchleife gefunden und mit initialisiert wurde F.

function(s){
m=F[F]					# logical(0); create an empty array (this gets automatically promoted to character(0) later
while(					# do-while loop
      {m=rbind(t(m)[,F:0],s[1:F])	# rotate m counterclockwise and add the first F characters of s to the bottom
       s=s[-1:-F]			# remove those characters
       length(s)>sum(F<-dim(m))})0	# while the number of characters remaining is greater than the sum of m's dimensions
write(m[F:1,],1,F[1],,"")		# write the rolled portion write writes down the columns, we reverse each column
cat(s,sep="")				# and write the remaining characters
}
Giuseppe
quelle
1

Gelee , 30 Bytes

Scheint zu lang ...

ḢW,ðZU;Ls@¥©ḢWɗ,®Ẏ¤ð/ẈṢƑ$¿ḢY;Ɗ

Probieren Sie es online!

Wie?

ḢW,ðZU;Ls@¥©ḢWɗ,®Ẏ¤ð/ẈṢƑ$¿ḢY;Ɗ - Main Link: list of characters
Ḣ                              - pop and yield head
 W                             - wrap in a list
  ,                            - pair with (the remaining list after Ḣ)
                         ¿     - while...
                        $      - ...condition: last two links as a monad:
                     Ẉ         -   length of each
                       Ƒ       -   is invariant under:
                      Ṣ        -     sort
                    /          - ...do: reduce by:
   ð               ð           -   the enclosed dyadic chain -- i.e. f(head, tail):
    Z                          -     transpose
     U                         -     reverse each (giving a rotated head)
              ɗ                -     last three links as a dyad:
          ¥                    -       last two links as a dyad:
       L                       -         length (i.e. number of rows in current roll)
         @                     -         with swapped arguments:
        s                      -           split (the tail) into chunks of that length
           ©                   -       (copy to register for later)
            Ḣ                  -       pop and yield head (Note register "copy" is altered too)
             W                 -       wrap in a list
      ;                        -     concatenate (the rotated head with the first chunk of the tail)
                  ¤            -     nilad followed by link(s) as a nilad:
                ®              -       recall from register (other chunks of tail, or an empty list)
                 Ẏ             -       tighten (the chunks to a flat list)
               ,               -     pair (the concatenate result with the tightened chunks)
                             Ɗ - last three links as a monad:
                          Ḣ    -   pop and yield head
                           Y   -   join with newline characters
                            ;  -   concatenate (the remaining tail)
                               - when running as a full program implicitly prints
Jonathan Allan
quelle
1

05AB1E , 41 Bytes

g©L¦€DD2šηO®>‹Ï©IŽ8OS®g4α._.ΛðÜI®O®g->.$«

Viel zu lange, aber ich wollte die Leinwand benutzen. Das war wahrscheinlich eine schlechte Wahl, jetzt wo ich fertig bin und es sich als so lang herausstellte.

Probieren Sie es online aus . (Keine Testsuite, da es ein seltsames Problem mit der eingebauten Software zu geben scheint .)

Erläuterung:

Lassen Sie mich zunächst eine allgemeine Erläuterung des Canvas-Bereichs geben und erläutern, was mit meinem Code erreicht werden soll. Detailliertere Informationen finden Sie in meinem relevanten 05AB1E-Tipp , aber für diese Herausforderung wollte ich Folgendes tun:

Das Canvas-Builtin akzeptiert drei Parameter:

  • ein[2,2,3,3,4,4,5,5,...]
  • b
  • c[2,0,6,4][,,,]ncarpet[0,6,4,2]0123456789ABCDEFGHI[6,4,2,0]

Wie für den Code:

g                # Get the length of the (implicit) input-string
 ©               # Store it in the register (without popping)
  L              # Create a list in the range [1,length]
   ¦             # Remove the first item to make the range [2,length]
    D           # Duplicate each to get the list [2,2,3,3,4,4,5,5,...]
      D2š        # Create a copy and prepend a 2: [2,2,2,3,3,4,4,5,5,...]
         η       # Get the prefixes: [[2],[2,2],[2,2,2],[2,2,2,3],...]
          O      # Sum each prefix: [2,4,6,9,12,16,20,...]
           ®     # Push the length from the register again
            >‹   # Check for each summed prefix if it's <= length
              Ï  # And only leave the truthy values
               © # And store this in the register (without popping)
                 # (This is our `a` for the Canvas builtin)
I                # Push the input-string
                 # (This is our `b` for the Canvas builtin)
Ž8O              # Push compressed integer 2064
   S             # Converted to a list of digits: [2,0,6,4]
    ®g           # Push the list from the register, and get its length
      4α         # Get the absolute difference with 4
        ._       # And rotate the [2,0,6,4] that many times towards the left
                 # (This is our `c` for the Canvas builtin)
               # Now use the Canvas builtin, without printing it yet
  ðÜ             # Remove any trailing spaces (since the Canvas implicitly makes a rectangle)
     ®O          # Push the sum of the list from the register
       ®g-       # Subtract the length of the list from the register
          >      # And add 1
    I      .$    # Remove that many leading characters from the input-string
             «   # And append it at the end of the roll created by the Canvas
                 # (after which the result is output implicitly)

Sehen Sie sich meinen Tipp 05AB1E (Abschnitt Wie komprimiere ich große ganze Zahlen? ) An, um zu verstehen, warum dies so Ž8Oist 2064.

Kevin Cruijssen
quelle
0

Python 3 , 112 Bytes

r=lambda t,h=[[]]:len(h)>len(t)and h[:-1]+[h[-1]+list(t)]or r(t[len(h):],list(zip(*h[::-1]))+[list(t)[:len(h)]])

In diesem Fall ist der Ausgang der Wert der Funktion.

Probieren Sie es online!

Wenn Sie es vorziehen, hier eine andere (längere, 129 Bytes ) Lösung, die direkt die gerollte Eingabe druckt:

r=lambda t,h=['']:len(h)>len(t)and set(map(print,h[:-1]+[h[-1]+t]))or r(t[len(h):],list(map(''.join,zip(*h[::-1])))+[t[:len(h)]])

Probieren Sie es online!

PieCot
quelle
1
muss es drucken
ASCII
@ Nur ASCII: Zitiert den Autor der Frage: „Wenn Rückkehr statt Druck zeigt eine große improvment oder einen netten Trick, schreiben eine Antwort (und ausdrücklich , dass Sie zurückkommen , nicht gedruckt wird )“ . Also ich denke es ist okay.
PieCot
0

MATLAB / Octave , 154 Bytes

Nicht die kürzeste, aber in MATLAB / Octave zu golfen macht immer Spaß :)

function h=r(t,h);n=fliplr(h');s=size(n,2);q=numel(t);if s<=q h=r(t(max(s,1)+1:end),[n; t(1:max(s,1))]);elseif q>0 h(:,end+q)=' ';h(end,end-q+1:end)=t;end

Probieren Sie es online!

PieCot
quelle
1
Leider sagt op, dass Sie drucken müssen
ASCII
@ ASCII-only Wie hier erklärt ( it.mathworks.com/matlabcentral/answers/… ) bezieht sich stdout in der Matlab-Welt auf das Befehlsfenster. Angesichts der Tatsache, dass das Ergebnis der Auswertung jedes Befehls automatisch im Befehlsfenster ausgegeben wird, kann diese Antwort als mit den Anforderungen der Frage vereinbar angesehen werden.
PieCot
Vielleicht möchten Sie das klarer machen
ASCII
@ ASCII-only Ich verstehe nicht was du meinst, wirklich. Es ist eine Funktion, die Sie nennen. Das Ergebnis wird automatisch im Befehlsfenster (dh stdout) ausgegeben. Was ist daran falsch? Sogar die R-Antwort funktioniert so ...
PieCot
1
Gerade jetzt Sie dispes, würde ich sagen , dass Sie das entfernen sollte , dispLeute zu informieren , die nicht R wissen , dass es funktioniert Schreiben in STDOUT standardmäßig
ASCII-only