Roll the carpet
Charcoal, 15 bytes
FS«F¬℅§KV⁰⟲⁶→Pι
Try it online! Link is to verbose version of code. Explanation:
FS«
Loop over the carpet.
F¬℅§KV⁰
Check whether there's anything above the cursor.
⟲⁶
If not then roll the carpet.
→Pι
Move right and output the current character.
Example: For the input 0123456789
, the following actions occur:
0
0
is printed.
01
The cursor moves right and 1
is printed.
0
1
Since there is nothing above the 1
, the canvas is rotated.
0
12
The cursor moves right and the 2
is printed.
10
2
Since there is nothing above the 2
, the canvas is rotated.
10
23
The cursor moves right and the 3
is printed.
10
234
The cursor moves right and the 4
is printed.
21
30
4
Since there is nothing above the 4
, the canvas is rotated.
21
30
45
The cursor moves right and the 5
is printed.
21
30
456
The cursor moves right and the 6
is printed.
432
501
6
Since there is nothing above the 6
, the canvas is rotated.
432
501
67
The cursor moves right and the 7
is printed.
432
501
678
The cursor moves right and the 8
is printed.
432
501
6789
The cursor moves right and the 9
is printed.
Pyth, 37 bytes
.U+j;bZ.WgleHJlhH,+_MChZ<eZJ>eZJ,]hQt
Try it online here, or verify all the test cases at once here.
.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
Husk, 24 bytes
►S=ÖLmFȯ:T↔ø§z:oΘḣĠ+CṘ2N
Try it online!
Explanation
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.