Trải thảm


15

Câu hỏi này được lấy cảm hứng từ câu hỏi của Kevin Cruijssen .

Bây giờ thảm được đặt ra, chúng tôi muốn cuộn nó. Nhiệm vụ của bạn là viết một chương trình lấy một chuỗi và trả về một vòng xoắn được tạo từ chuỗi này (đại diện cho một tấm thảm cuộn nhìn từ bên cạnh).

Thủ tục cho một bước cuộn thảm là như sau. Có một ví dụ để minh họa những gì tôi muốn nói. Lưu ý rằng ví dụ bắt đầu với một tấm thảm cuộn một phần để hiểu rõ hơn:

ac
rpet
  • tách "đầu" ra khỏi "đuôi" của thảm: đầu là những gì đã được cuộn cho đến nay, đuôi là những gì còn lại để được cuộn.
Head: ac   Tail:
      rp          et
  • Xoay đầu 90 °, theo chiều kim đồng hồ.
Rotated head: ra   Tail (unchanged):
              pc                       et
  • nếu chiều rộng của đầu mới (ở đây 2) nhỏ hơn hoặc bằng chiều dài của đuôi (ở đây 2)
    • Sau đó, đặt nó lên trên đuôi
    • mặt khác, tấm thảm (như lúc bắt đầu bước) đã được cuộn
New carpet: ra
            pc
            et

Lặp lại thủ tục nhiều lần nếu cần.


Hai ví dụ cho thấy tất cả các bước của thảm lăn:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

Một số giới hạn:

  • Bạn không cần phải hiển thị tất cả các bước trung gian, chỉ thảm cuộn (ví dụ: nếu bạn tìm thấy một cách không lặp để tính kết quả, nó hoàn hảo). Ngoài ra, bạn không cần in bất kỳ khoảng trắng hàng đầu nào, trong các ví dụ ở trên, tôi chỉ hiển thị chúng để căn chỉnh công cụ.
  • Đầu vào là một Chuỗi, một danh sách / mảng char
  • Đầu ra được in ra thiết bị xuất chuẩn hoặc vào một tệp.
  • Đầu vào là tốt: độ dài ít nhất là 1 char và tối đa là một hằng số đủ nhỏ để nó không gây ra vấn đề, nhưng bạn không thể sử dụng hằng số đó trong chương trình của mình; nội dung của chuỗi chỉ là các ký tự đẹp ([a-zA-Z0-9]), mã hóa theo sở thích của bạn.
  • Đây là , vì vậy câu trả lời ngắn nhất bằng byte thắng. Đừng để ngôn ngữ mã-golf ngăn cản bạn đăng câu trả lời với các ngôn ngữ không mã hóa. Cố gắng đưa ra một câu trả lời càng ngắn càng tốt cho ngôn ngữ lập trình 'bất kỳ'.
  • Lỗ hổng mặc định bị cấm.
  • Nếu có thể, vui lòng thêm một liên kết với một bài kiểm tra cho mã của bạn.
  • Ngoài ra, thêm một lời giải thích cho câu trả lời của bạn nếu bạn nghĩ rằng nó là cần thiết.


2
Ngoài ra cái này: codegolf.stackexchange.com/questions/125966/ , nhưng không bao gồm kiểm tra chấm dứt.
Bromind

3
Trường hợp thử nghiệm được đề xuất: ProgrammingPuzzlesAndCodeGolf- chiều dài đuôi cuối cùng lớn hơn 1 lần tăng gấp ba lần tôi.
Sok

1
Tôi nghĩ rằng bạn đã hoán đổi các từ "đầu" và "đuôi" ở đây: "nếu chiều rộng của đầu mới [...] lớn hơn hoặc bằng chiều dài của đuôi [...]".
Erik the Outgolfer

1
Bị từ chối vì các quy tắc đầu vào / đầu ra quá hạn chế; Tôi đã xóa câu trả lời Python 2 của mình vì người ta không thể sử dụng printbên trong a lambda.
Chas Brown

Câu trả lời:


7

Than , 15 byte

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

Hãy thử trực tuyến! Liên kết là phiên bản dài dòng của mã. Giải trình:

FS«

Vòng qua thảm.

F¬℅§KV⁰

Kiểm tra xem có bất cứ điều gì trên con trỏ.

⟲⁶

Nếu không thì cuộn thảm.

→Pι

Di chuyển sang phải và xuất ký tự hiện tại.

Ví dụ: Đối với đầu vào 0123456789, các hành động sau xảy ra:

0

0 được in.

01

Con trỏ di chuyển sang phải và 1 được in.

0
1

Vì không có gì ở trên 1, khung vẽ được xoay.

0
12

Con trỏ di chuyển sang phải và 2được in.

10
2

Vì không có gì ở trên 2, khung vẽ được xoay.

10
23

Con trỏ di chuyển sang phải và 3được in.

10
234

Con trỏ di chuyển sang phải và 4được in.

21
30
4

Vì không có gì ở trên 4, khung vẽ được xoay.

21
30
45

Con trỏ di chuyển sang phải và 5được in.

21
30
456

Con trỏ di chuyển sang phải và 6được in.

432
501
6

Vì không có gì ở trên 6, khung vẽ được xoay.

432
501
67

Con trỏ di chuyển sang phải và 7được in.

432
501
678

Con trỏ di chuyển sang phải và 8được in.

432
501
6789

Con trỏ di chuyển sang phải và 9được in.


Thật tuyệt vời. Vì vậy, về cơ bản Char than có một toán tử "cuộn" dựng sẵn trong ?
Giô-na

1
@Jonah Vâng, nó sẽ không cuộn cho tôi khi nó đi, nhưng bằng cách xuất ra chuỗi ký tự theo từng ký tự, tôi có thể cuộn khi tôi đi, vâng.
Neil

3

Bình thường, 37 byte

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

Dùng thử trực tuyến tại đây hoặc xác minh tất cả các trường hợp thử nghiệm cùng một lúc tại đây .

.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

3

Husk , 24 byte

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

Hãy thử trực tuyến!

Giải trình

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.

2

J , 69 byte

-3 byte nhờ FrownyFrog

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

Hãy thử trực tuyến!

giải trình

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

Thuật toán rất đơn giản mặc dù có một chút dài dòng cho J.

Chiến lược tổng thể: Giảm đầu vào thành một bảng vuông, với phần còn lại (có thể trống).

Khi chúng tôi giảm, chúng tôi sẽ sử dụng danh sách 2 yếu tố của các hộp. "Kết quả cho đến nay" của chúng tôi sẽ là hộp đầu tiên và "các mục còn lại sẽ được xử lý" sẽ là hộp thứ 2. Hộp đầu tiên sẽ được khởi tạo vào đầu của đầu vào (nhưng được chuyển đổi thành bảng):

1 1 $ {.

và "các mục còn lại sẽ được xử lý" sẽ là đuôi của đầu vào:

}. ;~

Bây giờ chúng tôi có:

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

trong đó 'c' thực sự là một bảng 1x1.

Chúng tôi giảm điều đó xuống bằng cách sử dụng vòng lặp J Do ... While:

^:(...)^:_

Trong đó phần trong ngoặc đơn là điều kiện "tiếp tục":

<:&#&>/

trong đó cho biết "tiếp tục đi trong khi chiều dài của hộp bên phải lớn hơn hoặc bằng chiều dài của hộp bên trái (nghĩa là độ dài cạnh của ma trận vuông)

"Tiếp tục đi" nghĩa là gì? Điều đó được định nghĩa trong động từ bên trái của từ đầu tiên ^:, cho chúng ta biết cách lấy kết quả hiện tại và tạo ra lần lặp tiếp theo. Động từ đó là:

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

Hãy phá vỡ nó:

((|:@|.@[ , #@[ {. ]) ; #@[ }. ])&>/
(  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

Đó là, đây chỉ là thuật toán được mô tả trong OP được dịch theo nghĩa đen thành J.

Cuối cùng, chúng tôi xử lý các mục còn lại (có thể là 0), phần đuôi của cuộn thảm của chúng tôi:

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

Điều này nói rằng "lấy tất cả trừ elm cuối cùng của kết quả":

}:@[ 

và nối nó vào ,các mục cuối cùng của kết quả {:@[với các mục còn lại được thêm vào mục cuối cùng đó, ]


À, J ... các chữ cái dành cho noobs
RK.

,.có thể làm những gì 1 1$]không và $có thể được sử dụng như {..
FrownyFrog

@FrownyFrog ty. Tôi đã nhận được tới 70 byte với đề xuất đầu tiên của bạn nhưng không chắc chắn nếu tôi hiểu $ can be used as {.- bạn có thể làm rõ không?
Giô-na

1
Dòng cuối cùng của lời giải thích, bạn sử dụng {. để cắt ngắn, cái đó có thể là một $ theo như tôi hiểu.
FrownyFrog

Ngoài ra, bạn có thể thay thế quyền [: bằng @
FrownyFrog

1

R , 146 132 byte

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="")}

Hãy thử trực tuyến!

Thực hiện các thủ tục lăn thảm. Đưa đầu vào dưới dạng danh sách các ký tự và in ra thiết bị xuất chuẩn.

Đã lưu 14 byte bằng cách tìm cách sử dụng do-whilevòng lặp và khởi tạo bằng cách sử dụng 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
}

1

Thạch , 30 byte

Có vẻ quá dài ...

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

Hãy thử trực tuyến!

Làm sao?

Ḣ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

1

05AB1E , 41 byte

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

Quá lâu, nhưng tôi muốn sử dụng Canvas .. Đó có lẽ là một lựa chọn tồi khi tôi đã hoàn thành nó và hóa ra là lâu như vậy ..

Hãy thử trực tuyến . (Không có bộ kiểm tra, vì dường như có một vấn đề kỳ lạ với nội dung ..)

Giải trình:

Hãy để tôi bắt đầu bằng cách đưa ra lời giải thích chung về Canvas và những gì tôi muốn mã của mình hoàn thành. Thông tin chi tiết hơn có thể được tìm thấy trong mẹo 05AB1E có liên quan này của tôi , nhưng đối với thử thách này, tôi muốn thực hiện như sau:

Nội dung Canvas có ba tham số:

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

Đối với mã:

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)

Xem 05AB1E mẹo này của tôi (phần Làm thế nào để nén các số nguyên lớn? ) Để hiểu tại sao Ž8O2064.


0

Python 3 , 112 byte

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)]])

Trong trường hợp này, đầu ra là giá trị của hàm.

Hãy thử trực tuyến!

Nếu bạn thích, ở đây một giải pháp khác (dài hơn, 129 byte ) in trực tiếp đầu vào cuộn:

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)]])

Hãy thử trực tuyến!


1
cần in nó
ASCII chỉ

@ ASCII-only: Trích dẫn tác giả của câu hỏi: "Nếu quay lại thay vì in cho thấy một sự ngẫu hứng hay một mẹo hay, hãy đăng câu trả lời (và nói rõ rằng bạn đang quay lại, không in)" . Vì vậy, tôi nghĩ rằng nó ổn.
PieCot

0

MATLAB / Octave , 154 byte

Không phải là ngắn nhất, nhưng để chơi golf trong MATLAB / Octave luôn vui vẻ :)

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

Hãy thử trực tuyến!


1
thật đáng buồn, op nói rằng bạn phải in
ASCII chỉ

@ ASCII - chỉ như được giải thích ở đây ( it.mathworks.com/matlabcentral/answers/iêu ), thiết bị xuất chuẩn trong thế giới Matlab đề cập đến cửa sổ lệnh. Cho rằng kết quả đánh giá của mọi lệnh được tự động in ra cửa sổ lệnh, tôi nghĩ rằng câu trả lời này có thể được coi là phù hợp với yêu cầu của câu hỏi.
PieCot


@ ASCII-chỉ tôi không hiểu ý bạn là gì. Đó là một chức năng, bạn gọi nó, kết quả sẽ được tự động in trên cửa sổ lệnh (tức là thiết bị xuất chuẩn). Có chuyện gì với cái này vậy? Ngay cả câu trả lời R cũng hoạt động như thế này ...
PieCot

1
Ngay bây giờ bạn dispnó, tôi muốn nói rằng bạn nên loại bỏ dispđể cho mọi người mà không biết R mà nó không ghi vào STDOUT theo mặc định
ASCII chỉ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.