ม้วนพรม


15

คำถามนี้เป็นแรงบันดาลใจคำถามเควิน Cruijssen ของ

ตอนนี้เราวางพรมออกแล้ว งานของคุณคือการเขียนโปรแกรมที่ใช้สตริงและส่งกลับเกลียวที่ทำจากสายนี้ (แสดงถึงพรมที่ถูกรีดจากด้านข้าง)

ขั้นตอนสำหรับการรีดพรมหนึ่งขั้นตอนมีดังต่อไปนี้ มีตัวอย่างเพื่ออธิบายสิ่งที่ฉันหมายถึง ขอให้สังเกตว่าตัวอย่างเริ่มต้นด้วยพรมรีดบางส่วนเพื่อความเข้าใจที่ดีขึ้น:

ac
rpet
  • แยก "หัว" ออกจาก "หาง" ของพรม: หัวคือสิ่งที่ได้รับการม้วนจนถึงหางเป็นสิ่งที่เหลืออยู่จะต้องรีด
Head: ac   Tail:
      rp          et
  • หมุนหัว 90 °ตามเข็มนาฬิกา
Rotated head: ra   Tail (unchanged):
              pc                       et
  • ถ้าความกว้างของหัวใหม่ (ที่นี่2) น้อยกว่าหรือเท่ากับความยาวของหาง (ที่นี่2)
    • จากนั้นวางไว้บนหาง
    • มิฉะนั้นพรม (เหมือนที่จุดเริ่มต้นของขั้นตอน) ถูกรีด
New carpet: ra
            pc
            et

ทำซ้ำขั้นตอนซ้ำหลาย ๆ ครั้งตามต้องการ


สองตัวอย่างแสดงขั้นตอนทั้งหมดของการกลิ้งพรม:

carpet

 c
 arpet

  ac
  rpet

    ra
    pc
    et
0123456789

 0
 123456789

  10
  23456789

    21
    30
    456789

      432
      501
      6789

บางประการ:

  • คุณไม่จำเป็นต้องแสดงขั้นตอนกลางทั้งหมดเฉพาะพรมรีด (เช่นหากคุณพบวิธีที่ไม่ซ้ำในการคำนวณผลลัพธ์มันสมบูรณ์แบบ) นอกจากนี้คุณไม่จำเป็นต้องพิมพ์ช่องว่างนำหน้าในตัวอย่างด้านบนฉันแสดงให้พวกเขาจัดตำแหน่งสิ่งต่างๆเท่านั้น
  • อินพุตเป็นสตริงรายการ / อาร์เรย์ของถ่าน
  • เอาต์พุตถูกพิมพ์ไปยัง stdout หรือไปที่ไฟล์
  • อินพุตเป็นสิ่งที่ดี: ความยาวอย่างน้อย 1 อักขระและอย่างน้อยที่สุดก็มีขนาดเล็กพอที่จะไม่ทำให้เกิดปัญหา แต่คุณไม่สามารถใช้ค่าคงที่นั้นในโปรแกรมของคุณ เนื้อหาของสตริงเป็นเพียงอักขระที่สวยงาม ([a-zA-Z0-9]) ซึ่งเข้ารหัสตามความต้องการของคุณ
  • นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ อย่าปล่อยให้ภาษารหัสกอล์ฟกีดกันคุณจากการโพสต์คำตอบด้วยภาษาที่ไม่ได้เข้ารหัส พยายามหาคำตอบสั้น ๆ ที่เป็นไปได้สำหรับภาษาโปรแกรม 'ใด ๆ '
  • ช่องโหว่เริ่มต้นเป็นสิ่งต้องห้าม
  • หากเป็นไปได้โปรดเพิ่มลิงค์พร้อมทดสอบรหัสของคุณ
  • นอกจากนี้ให้เพิ่มคำอธิบายสำหรับคำตอบของคุณหากคุณคิดว่าจำเป็น


2
นอกจากนี้อันนี้: codegolf.stackexchange.com/questions/125966/…แต่ไม่มีใครรวมถึงการตรวจสอบการยกเลิก
Bromind

3
กรณีทดสอบที่แนะนำ: ProgrammingPuzzlesAndCodeGolf- ความยาวหางสุดท้ายที่มากกว่า 1 ทำให้ฉันสะดุด
Sok

1
ฉันคิดว่าคุณสลับคำว่า "หัว" และ "หาง" ที่นี่: "ถ้าความกว้างของหัวใหม่ [... ] มากกว่าหรือเท่ากับความยาวของหาง [... ]"
Erik the Outgolfer

1
ลดลงเนื่องจากกฎอินพุต / เอาต์พุตที่เข้มงวดเกินไป ฉันลบของฉันหลาม 2 คำตอบตั้งแต่หนึ่งไม่สามารถใช้ภายในprint lambda
Chas Brown

คำตอบ:


7

ถ่าน 15 ไบต์

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

ลองออนไลน์! การเชื่อมโยงคือการใช้รหัสเวอร์ชันอย่างละเอียด คำอธิบาย:

FS«

วนรอบพรม

F¬℅§KV⁰

ตรวจสอบว่ามีสิ่งใดเหนือเคอร์เซอร์หรือไม่

⟲⁶

หากไม่หมุนพรม

→Pι

เลื่อนไปทางขวาและส่งออกอักขระปัจจุบัน

ตัวอย่าง: สำหรับอินพุต0123456789การดำเนินการต่อไปนี้เกิดขึ้น:

0

0 ถูกพิมพ์

01

เคอร์เซอร์เลื่อนไปทางขวาและ1ถูกพิมพ์

0
1

เนื่องจากไม่มีสิ่งใดอยู่เหนือ1ผืนผ้าใบจึงหมุน

0
12

เคอร์เซอร์เลื่อนไปทางขวาและ2ถูกพิมพ์

10
2

เนื่องจากไม่มีสิ่งใดอยู่เหนือ2ผืนผ้าใบจึงหมุน

10
23

เคอร์เซอร์เลื่อนไปทางขวาและ3ถูกพิมพ์

10
234

เคอร์เซอร์เลื่อนไปทางขวาและ4ถูกพิมพ์

21
30
4

เนื่องจากไม่มีสิ่งใดอยู่เหนือ4ผืนผ้าใบจึงหมุน

21
30
45

เคอร์เซอร์เลื่อนไปทางขวาและ5ถูกพิมพ์

21
30
456

เคอร์เซอร์เลื่อนไปทางขวาและ6ถูกพิมพ์

432
501
6

เนื่องจากไม่มีสิ่งใดอยู่เหนือ6ผืนผ้าใบจึงหมุน

432
501
67

เคอร์เซอร์เลื่อนไปทางขวาและ7ถูกพิมพ์

432
501
678

เคอร์เซอร์เลื่อนไปทางขวาและ8ถูกพิมพ์

432
501
6789

เคอร์เซอร์เลื่อนไปทางขวาและ9ถูกพิมพ์


ที่น่ากลัว. ดังนั้นโดยทั่วไปถ่านมีตัวดำเนินการ "ม้วน" ในตัวหรือไม่
โยนาห์

1
@Jonah เอาล่ะมันจะไม่ม้วนสำหรับฉันไป แต่โดยการแสดงผลตัวอักษรสตริงโดยตัวละครฉันสามารถหมุนตามที่ฉันไปใช่
Neil

3

Pyth, 37 ไบต์

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

ลองออนไลน์ได้ที่นี่หรือตรวจสอบทุกกรณีการทดสอบในครั้งเดียวที่นี่

.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 ไบต์

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

ลองออนไลน์!

คำอธิบาย

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 ไบต์

-3 ไบต์ขอบคุณ FrownyFrog

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

ลองออนไลน์!

คำอธิบาย

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

อัลกอริทึมนั้นตรงไปตรงมาแม้จะเป็น verbose เล็กน้อยสำหรับ J

กลยุทธ์โดยรวม: ลดการป้อนข้อมูลลงในตารางสี่เหลี่ยมด้วยชิ้นส่วนที่เหลือ (อาจว่างเปล่า)

เมื่อเราลดเราจะใช้รายการองค์ประกอบ 2 กล่อง "ผลลัพธ์จนถึงตอนนี้" ของเราจะเป็นช่องแรกและ "รายการที่เหลือเพื่อดำเนินการ" จะเป็นช่องที่สอง กล่องแรกจะเริ่มต้นที่ส่วนหัวของอินพุต (แต่แปลงเป็นตาราง):

1 1 $ {.

และ "รายการที่เหลืออยู่ที่ต้องดำเนินการ" จะเป็นส่วนท้ายของอินพุต:

}. ;~

ตอนนี้เรามี:

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

โดยที่ 'c' เป็นตาราง 1x1

เราลดขนาดลงโดยใช้ J Do ... ขณะที่วนซ้ำ:

^:(...)^:_

ส่วนที่อยู่ในวงเล็บคือสภาพ "ก้าวต่อไป":

<:&#&>/

ซึ่งบอกว่า "ไปต่อในขณะที่ความยาวของกล่องด้านขวามีค่ามากกว่าหรือเท่ากับความยาวของกล่องด้านซ้าย (เช่นความยาวด้านของเมทริกซ์จตุรัส)

"ไปต่อ" หมายความว่าอะไร ที่ถูกกำหนดในคำกริยาทางด้านซ้ายของแรก^:ซึ่งบอกให้เราทราบถึงวิธีการใช้ผลในปัจจุบันและผลิตซ้ำต่อไป คำกริยานั่นคือ:

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

มาทำลายมันกันเถอะ:

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

นั่นคือนี่เป็นเพียงอัลกอริทึมที่อธิบายไว้ใน OP แปลตามตัวอักษรเป็น J

ในที่สุดเราก็จัดการกับสิ่งของที่เหลืออยู่ (อาจเป็น 0) ส่วนท้ายของม้วนพรมของเรา:

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

สิ่งนี้บอกว่า "ใช้เวลาทั้งหมดยกเว้น elm สุดท้ายของผลลัพธ์":

}:@[ 

และผนวกเข้า,กับรายการสุดท้ายของผลลัพธ์{:@[โดยมีรายการที่เหลืออยู่ต่อท้ายรายการสุดท้าย, ]


อ้า J ... ตัวอักษรสำหรับ noobs
RK

,.สามารถทำสิ่งที่1 1$]ไม่และสามารถใช้เป็น$ {.
FrownyFrog

@FrownyFrog ty ฉันได้รับถึง70 ไบต์ด้วยคำแนะนำแรกของคุณแต่ไม่แน่ใจว่าฉันเข้าใจ$ can be used as {.หรือไม่คุณสามารถชี้แจงได้ไหม
โยนาห์

1
บรรทัดสุดท้ายของคำอธิบายคุณใช้ {. เพื่อตัดทอนให้ได้ $ เท่าที่ฉันเข้าใจ
FrownyFrog

นอกจากนี้คุณสามารถแทนที่ถูกต้อง [: ด้วย @
FrownyFrog

1

R , 146 132 ไบต์

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

ลองออนไลน์!

ใช้ขั้นตอนการรีดพรม รับอินพุตเป็นรายการของอักขระและพิมพ์เป็น stdout

บันทึก 14 ไบต์ด้วยการหาวิธีใช้ do-whileFห่วงและการเริ่มต้นใช้

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

วุ้น 30 ไบต์

ดูเหมือนจะยาวเกินไป ...

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

ลองออนไลน์!

อย่างไร?

Ḣ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 ไบต์

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

นานเกินไป แต่ฉันต้องการใช้ Canvas .. ซึ่งอาจเป็นตัวเลือกที่ไม่ดีตอนนี้ที่ฉันทำเสร็จแล้วและมันกลับกลายเป็นว่ามันยาวนานขนาดนี้ ..

ลองมันออนไลน์ (ไม่มีชุดทดสอบเพราะดูเหมือนว่าจะมีปัญหาแปลก ๆกับbuiltin .. )

คำอธิบาย:

ให้ฉันเริ่มต้นด้วยการให้คำอธิบายทั่วไปของ Canvas และสิ่งที่ฉันต้องการให้รหัสของฉันสำเร็จ สามารถดูข้อมูลรายละเอียดเพิ่มเติมได้ที่ส่วนปลายของ 05AB1E ที่เกี่ยวข้องแต่สำหรับความท้าทายนี้ฉันต้องการทำสิ่งต่อไปนี้:

Canvas builtin ใช้พารามิเตอร์สามตัว:

  • a: ขนาดของบรรทัด [2,2,3,3,4,4,5,5,...]สำหรับความท้าทายนี้นี้จะเป็นรายการ
  • : ตัวละครที่เราต้องการแสดง สำหรับความท้าทายนี้สิ่งนี้จะเป็นเพียงอินพุต - สตริง
  • : ทิศทางที่เราต้องการวาดเส้นอักขระเหล่านี้ สำหรับความท้าทายนี้จะเป็นทิศทาง[2,0,6,4] ([,,,]) หมุน nจำนวนครั้งขึ้นอยู่กับอินพุตสตริงที่มีทิศทางเริ่มต้นที่แตกต่างกัน (เช่นอินพุตcarpetคือ[0,6,4,2]แทนและใส่0123456789ABCDEFGHIเป็น[6,4,2,0] แทน).

สำหรับรหัส:

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)

ดู 05AB1E นี้เคล็ดลับของฉัน (ส่วนวิธีการบีบอัดจำนวนเต็มขนาดใหญ่? )จะเข้าใจว่าทำไมเป็นŽ8O2064


0

Python 3 , 112 ไบต์

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

ในกรณีนี้ผลลัพธ์คือค่าของฟังก์ชั่น

ลองออนไลน์!

หากคุณต้องการนี่คืออีกโซลูชัน(ยาวกว่า129 ไบต์ ) ที่พิมพ์อินพุตรีดโดยตรง:

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

ลองออนไลน์!


1
จำเป็นต้องพิมพ์
ASCII เท่านั้นเท่านั้น

@ ASCII เท่านั้น: Quoting ผู้เขียนคำถาม: "ถ้ากลับมาแทนการพิมพ์การแสดง improvment ดีหรือเคล็ดลับดีโพสต์คำตอบ (และอย่างชัดเจนว่าคุณจะกลับมาไม่ได้พิมพ์)" ดังนั้นฉันคิดว่ามันโอเค
PieCot

0

MATLAB / Octave , 154 ไบต์

ไม่ใช่คนที่สั้นที่สุด แต่การเล่นกอล์ฟใน MATLAB / Octave สนุกเสมอ :)

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

ลองออนไลน์!


1
น่าเศร้าที่ op บอกว่าคุณต้องพิมพ์
ASCII-only

@ ASCII เท่านั้นตามที่อธิบายไว้ที่นี่ ( it.mathworks.com/matlabcentral/answers/ ...... ) stdout ใน Matlab world อ้างถึงหน้าต่างคำสั่ง เนื่องจากผลลัพธ์ของการประเมินของทุกคำสั่งถูกพิมพ์โดยอัตโนมัติไปยังหน้าต่างคำสั่งฉันคิดว่าคำตอบนี้อาจถูกพิจารณาว่าสอดคล้องกับข้อกำหนดของคำถาม
PieCot


@ ASCII- เท่านั้นฉันไม่เข้าใจความหมายของคุณจริงๆ มันเป็นฟังก์ชั่นที่คุณเรียกว่าผลลัพธ์จะถูกพิมพ์โดยอัตโนมัติในหน้าต่างคำสั่ง (เช่น stdout) เกิดอะไรขึ้นกับสิ่งนี้? แม้แต่คำตอบ R ก็ทำงานเช่นนี้ ...
39432

1
ตอนนี้คุณdispก็ผมว่าคุณควรจะเอาdispไปให้คนที่ไม่ทราบ R ว่ามันไม่เขียนไป STDOUT โดยค่าเริ่มต้น
ASCII เท่านั้น
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.