Gulung karpet

15

Pertanyaan ini terinspirasi oleh pertanyaan Kevin Cruijssen .

Sekarang karpet sudah ditata, kami ingin menggulungnya. Tugas Anda adalah menulis program yang mengambil string dan mengembalikan spiral yang dibuat dari string ini (mewakili karpet yang digulung dilihat dari samping).

Prosedur untuk satu langkah menggulung karpet adalah sebagai berikut. Ada contoh untuk menggambarkan apa yang saya maksud. Perhatikan bahwa contoh dimulai dengan karpet yang digulung sebagian untuk pemahaman yang lebih baik:

ac
rpet
  • pisahkan "kepala" dari "ekor" karpet: kepala adalah apa yang telah digulung sejauh ini, ekor adalah apa yang masih harus digulung.
Head: ac   Tail:
      rp          et
  • Putar kepala 90 °, searah jarum jam.
Rotated head: ra   Tail (unchanged):
              pc                       et
  • jika lebar kepala baru (di sini 2) kurang atau sama dengan panjang ekor (di sini 2)
    • lalu, letakkan di atas ekor
    • selain itu, karpet (seperti pada awal langkah) digulung
New carpet: ra
            pc
            et

Ulangi prosedur ini sebanyak yang diperlukan.


Dua contoh yang menunjukkan semua langkah rolling karpet:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

Beberapa ketentuan:

  • Anda tidak perlu menunjukkan semua langkah perantara, hanya karpet yang digulung (mis. Jika Anda menemukan cara yang tidak berulang untuk menghitung hasilnya, itu sempurna). Juga, Anda tidak perlu mencetak spasi putih terkemuka, dalam contoh di atas, saya hanya menunjukkan mereka untuk menyelaraskan hal-hal.
  • Input adalah String, daftar / array char
  • Output dicetak ke stdout atau ke file.
  • Input bagus: panjangnya minimal 1 karakter, dan paling banyak konstanta cukup kecil sehingga tidak menimbulkan masalah, tetapi Anda tidak dapat menggunakan konstanta itu dalam program Anda; isi string hanya karakter yang bagus ([a-zA-Z0-9]), yang disandikan sesuai keinginan Anda.
  • Ini adalah , jadi jawaban tersingkat dalam byte menang. Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa yang bukan kode. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa pun'.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, silakan tambahkan tautan dengan tes untuk kode Anda.
  • Juga, tambahkan penjelasan untuk jawaban Anda jika menurut Anda diperlukan.
Bromind
sumber
3
Berhubungan erat
Giuseppe
2
Yang ini juga: codegolf.stackexchange.com/questions/125966/… , tetapi tidak ada yang menyertakan cek terminasi.
Bromind
3
Kasing uji yang disarankan: ProgrammingPuzzlesAndCodeGolf- panjang ekor akhir lebih dari 1 membuat saya tersandung.
Sok
1
Saya pikir Anda telah bertukar kata "kepala" dan "ekor" di sini: "jika lebar kepala baru [...] lebih besar atau sama dengan panjang ekor [...]".
Erik the Outgolfer
1
Turun karena aturan input / output yang terlalu ketat; Saya menghapus jawaban Python 2 saya karena tidak dapat digunakan printdi dalam lambda.
Chas Brown

Jawaban:

7

Arang , 15 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

FS«

Loop di atas karpet.

F¬℅§KV⁰

Periksa apakah ada sesuatu di atas kursor.

⟲⁶

Jika tidak maka gulung karpet.

→Pι

Bergerak ke kanan dan tampilkan karakter saat ini.

Contoh: Untuk input 0123456789, tindakan berikut terjadi:

0

0 dicetak.

01

Kursor bergerak ke kanan dan 1dicetak.

0
1

Karena tidak ada yang di atas 1 , kanvas diputar.

0
12

Kursor bergerak ke kanan dan 2dicetak.

10
2

Karena tidak ada yang di atas 2 , kanvas diputar.

10
23

Kursor bergerak ke kanan dan 3dicetak.

10
234

Kursor bergerak ke kanan dan 4dicetak.

21
30
4

Karena tidak ada yang di atas 4 , kanvas diputar.

21
30
45

Kursor bergerak ke kanan dan 5dicetak.

21
30
456

Kursor bergerak ke kanan dan 6dicetak.

432
501
6

Karena tidak ada yang di atas 6 , kanvas diputar.

432
501
67

Kursor bergerak ke kanan dan 7dicetak.

432
501
678

Kursor bergerak ke kanan dan 8dicetak.

432
501
6789

Kursor bergerak ke kanan dan 9dicetak.

Neil
sumber
Itu luar biasa. Jadi pada dasarnya Charcoal memiliki operator "roll" bawaan ?
Jonah
1
@ Jonah Yah, itu tidak akan menggelinding bagi saya seperti yang terjadi, tetapi dengan mengeluarkan karakter string-by-karakter saya bisa roll saat saya pergi, ya.
Neil
3

Pyth, 37 byte

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

Coba online di sini , atau verifikasi semua uji sekaligus di sini .

.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
sumber
3

Sekam , 24 byte

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

Cobalah online!

Penjelasan

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
sumber
2

J , 69 byte

-3 byte terima kasih kepada FrownyFrog

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

Cobalah online!

penjelasan

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

Algoritma ini mudah meskipun sedikit bertele-tele untuk J.

Strategi Keseluruhan: Kurangi input ke tabel persegi, dengan bagian sisa (mungkin kosong).

Saat kami mengurangi, kami akan menggunakan daftar elemen 2 kotak. "Hasil sejauh ini" kami akan menjadi kotak pertama, dan "barang yang tersisa untuk diproses" akan menjadi kotak ke-2. Kotak pertama akan diinisialisasi ke kepala input (tetapi dikonversi ke tabel):

1 1 $ {.

dan "item yang tersisa untuk diproses" akan menjadi ekor input:

}. ;~

Sekarang kita punya:

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

di mana 'c' sebenarnya adalah tabel 1x1.

Kami mengurangi itu menggunakan loop J Do ... While:

^:(...)^:_

Di mana bagian dalam tanda kurung adalah kondisi "terus berjalan":

<:&#&>/

yang mengatakan "terus berjalan sementara panjang kotak kanan lebih besar dari atau sama dengan panjang kotak kiri (yaitu, panjang sisi matriks persegi)

Apa artinya "terus berjalan"? Itu didefinisikan dalam kata kerja di sebelah kiri yang pertama ^:, yang memberitahu kita bagaimana mengambil hasil saat ini dan menghasilkan iterasi berikutnya. Kata kerja itu adalah:

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

Mari kita jabarkan:

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

Artinya, ini hanya algoritma yang dijelaskan dalam OP yang diterjemahkan secara harfiah ke J.

Akhirnya kita berurusan dengan (mungkin 0) barang sisa, ekor dari karpet kami:

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

Ini mengatakan "ambil semua kecuali bagian terakhir dari hasil":

}:@[ 

dan menambahkannya ke ,item terakhir hasil {:@[dengan item yang tersisa ditambahkan ke item terakhir, ]

Jonah
sumber
Ah, J ... surat untuk noobs
RK.
,.dapat melakukan apa yang dapat 1 1$]dan $dapat digunakan sebagai {..
FrownyFrog
@FrownyFrog ty. Saya mendapatkannya hingga 70 byte dengan saran pertama Anda tetapi tidak yakin apakah saya mengerti $ can be used as {.- dapatkah Anda mengklarifikasi?
Jonah
1
Baris terakhir dari penjelasan, Anda menggunakan {. untuk memotong, yang satu bisa menjadi $ sejauh yang saya mengerti.
FrownyFrog
Anda juga dapat mengganti hak [: dengan @
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="")}

Cobalah online!

Menerapkan prosedur menggulung karpet. Mengambil input sebagai daftar karakter dan mencetak ke stdout.

Disimpan 14 byte dengan menemukan cara untuk menggunakan do-whilelingkaran dan menginisialisasi menggunakan 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
sumber
1

Jelly , 30 byte

Tampaknya terlalu lama ...

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

Cobalah online!

Bagaimana?

Ḣ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
sumber
1

05AB1E , 41 byte

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

Terlalu lama, tapi saya ingin menggunakan Kanvas .. Yang mungkin merupakan pilihan yang buruk sekarang saya sudah selesai dan ternyata selama ini ..

Cobalah online . (Tidak ada test suite, karena sepertinya ada masalah aneh dengan builtin ..)

Penjelasan:

Mari saya mulai dengan memberikan penjelasan umum tentang Canvas dan apa yang saya ingin kode saya capai. Informasi lebih rinci dapat ditemukan di tip tambang 05AB1E relevan ini , tetapi untuk tantangan ini saya ingin melakukan hal berikut:

Canvas builtin mengambil tiga parameter:

  • Sebuah: Ukuran garis. Untuk tantangan ini, ini akan menjadi daftar [2,2,3,3,4,4,5,5,...].
  • b: Karakter yang ingin kami tampilkan. Untuk tantangan ini, ini hanya akan menjadi input-string.
  • c: Arah di mana kita ingin menggambar garis karakter ini. Untuk tantangan ini, ini akan menjadi arah[2,0,6,4] ([,,,]) diputar nJumlah kali tergantung pada input-string untuk memiliki arah awal yang berbeda (yaitu masukan carpetadalah[0,6,4,2]sebagai gantinya dan inputnya 0123456789ABCDEFGHIadalah[6,4,2,0] sebagai gantinya).

Adapun kode:

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)

Lihat ini 05AB1E ujung tambang (bagian Cara kompres bilangan bulat besar? ) Untuk memahami mengapa Ž8Oadalah 2064.

Kevin Cruijssen
sumber
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)]])

Dalam hal ini, output adalah nilai fungsi.

Cobalah online!

Jika Anda suka, di sini solusi lain (lebih lama, 129 byte ) yang mencetak secara langsung input yang digulung:

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

Cobalah online!

PieCot
sumber
1
perlu mencetaknya
hanya ASCII
@ Khusus ASCII: Mengutip penulis pertanyaan: "Jika mengembalikan alih-alih mencetak menunjukkan perbaikan besar atau trik yang bagus, poskan jawaban (dan jelas bahwa Anda kembali, bukan mencetak)" . Jadi saya pikir tidak apa-apa.
PieCot
0

MATLAB / Oktaf , 154 byte

Bukan yang terpendek, tetapi untuk golf di MATLAB / Oktaf selalu menyenangkan :)

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

Cobalah online!

PieCot
sumber
1
Sayangnya, op mengatakan Anda harus mencetak
hanya ASCII
@ ASCII-hanya seperti yang dijelaskan di sini ( it.mathworks.com/matlabcentral/answers/… ), stdout di dunia Matlab merujuk ke jendela perintah. Mengingat bahwa hasil evaluasi setiap perintah secara otomatis dicetak ke jendela perintah, saya pikir jawaban ini dapat dianggap konsisten dengan persyaratan pertanyaan.
PieCot
mungkin ingin membuatnya lebih jelas
ASCII-only
@ ASCII-saja saya tidak mengerti maksud Anda, sungguh. Ini adalah fungsi, Anda menyebutnya, hasilnya akan dicetak secara otomatis pada jendela perintah (yaitu stdout). Ada apa dengan ini? Bahkan jawaban R berfungsi seperti ini ...
PieCot
1
Sekarang Anda dispitu, aku akan mengatakan Anda harus menghapus dispuntuk membiarkan orang yang tidak tahu R bahwa itu tidak menulis untuk STDOUT secara default
ASCII-satunya