카펫 롤


15

이 질문은 Kevin 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

일부 정밀도 :

  • 모든 중간 단계를 표시 할 필요는없고 롤 카펫 만 표시 할 수 있습니다 (예 : 결과를 계산하는 반복적이지 않은 방법을 찾으면 완벽 함). 또한 선행 공백을 인쇄 할 필요가 없습니다. 위의 예에서는 물건을 정렬하기 위해 보여줍니다.
  • 입력은 문자열, char의 목록 / 배열
  • 출력은 stdout 또는 파일로 인쇄됩니다.
  • 입력은 훌륭합니다. 길이는 1 자 이상이고 최대 상수는 충분히 작아서 문제를 일으키지 않지만 프로그램에서 상수를 사용할 수는 없습니다. 문자열의 내용은 단지 좋은 문자 ([a-zA-Z0-9])이며 원하는대로 인코딩합니다.
  • 이것은 이므로 바이트 단위의 최단 답변이 이깁니다. 코드 골프 언어가 코드 골프 언어 이외의 언어로 답변을 게시하지 못하게하십시오. '모든'프로그래밍 언어에 대한 가능한 한 짧은 대답을 생각해보십시오.
  • 기본 허점 은 금지되어 있습니다.
  • 가능하면 코드 테스트 링크를 추가하십시오.
  • 또한 필요하다고 생각되면 답변에 대한 설명을 추가하십시오.


2
또한 codegolf.stackexchange.com/questions/125966/… 이지만 종료 검사는 포함되지 않습니다.
Bromind

3
권장 테스트 사례 : ProgrammingPuzzlesAndCodeGolf-1보다 큰 최종 테일 길이가 저를 넘어 뜨 렸습니다.
Sok

1
"머리"와 "꼬리"라는 단어를 여기에 바꿨다고 생각합니다. "새 머리의 폭 [...]이 꼬리의 길이 [...]보다 크거나 같은 경우"
아웃 골퍼 Erik

1
지나치게 제한적인 입 / 출력 규칙으로 인해 하향 투표 됨; print내부에서 사용할 수 없으므로 Python 2 답변을 삭제 했습니다 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

껍질 , 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 바이트

FrownyFrog 덕분에 -3 바이트

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

온라인으로 사용해보십시오!

설명

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

알고리즘은 J에 대해 조금 장황함에도 불구하고 간단합니다.

전체 전략 : 남은 부분이 비어있는 사각형 테이블로 입력을 줄입니다.

축소하면서 2 개의 요소 목록 상자를 사용합니다. "지금까지의 결과"가 첫 번째 상자가되고 "처리 될 나머지 항목"이 두 번째 상자가됩니다. 첫 번째 상자는 입력 헤드로 초기화되지만 테이블로 변환됩니다.

1 1 $ {.

"처리 될 나머지 항목"은 입력의 꼬리가됩니다 :

}. ;~

이제 우리는 :

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

여기서 'c'는 실제로 1x1 테이블입니다.

J Do ... While 루프를 사용하여 줄입니다.

^:(...)^:_

괄호 안의 부분이 "계속 진행"상태 인 경우 :

<:&#&>/

"오른쪽 상자의 길이가 왼쪽 상자의 길이 (즉, 정사각 행렬의 측면 길이) 이상인 동안 계속 진행

"계속 가다"는 무슨 뜻입니까? 그것은 첫 번째의 왼쪽 동사에 정의되어 있으며 ^:, 현재 결과를 가져오고 다음 반복을 생성하는 방법을 알려줍니다. 그 동사는 :

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

그것을 분해하자 :

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

즉, 이것은 문자 그대로 J로 번역 된 OP에 설명 된 알고리즘 일뿐입니다.

마지막으로 카펫 롤의 꼬리 인 (아마도 0) 남은 항목을 처리합니다.

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

이것은 "결과의 마지막 느릅 나무 만 빼고"라고 말합니다 :

}:@[ 

나머지 항목을 마지막 항목에 추가 ,하여 결과의 ​​마지막 항목에 추가하십시오.{:@[, ]


아, J. 편지는 멍청한 놈들을위한 것입니다
RK.

,.무엇 1 1$]$할 수 있고로 사용할 수 있습니다 {..
FrownyFrog

@FrownyFrog ty. 첫 번째 제안 으로 70 바이트로 얻었 지만 이해했는지 확실하지 않습니다. $ can be used as {.명백 할 수 있습니까?
요나

1
설명의 마지막 줄에서 {를 사용합니다. 자르기 위해, 나는 내가 이해하는 한 $가 될 수 있습니다.
FrownyFrog

또한 당신은 바로 [을 대체 할 수와 @
FrownyFrog

1

R , 146132 바이트

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에 인쇄합니다.

do-while루프 를 사용하는 방법을 찾고를 사용하여 초기화하여 14 바이트를 절약했습니다 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

젤리 , 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->.$«

너무 길지만 캔버스를 사용하고 싶었습니다. 아마도 마무리 작업을 마치고이 길이가 길었을 것입니다.

온라인으로 사용해보십시오 . ( 내장에 이상한 문제 가있는 것 같아서 테스트 스위트가 없습니다 ..)

설명:

캔버스에 대한 일반적인 설명과 코드가 달성하기를 원하는 것으로 시작하겠습니다. 보다 자세한 정보는 이 관련 05AB1E 팁 에서 찾을 수 있습니다. 있지만이 문제에 대해 다음을 수행하고 싶었습니다.

Canvas 내장은 세 가지 매개 변수를 취합니다.

  • : 선의 크기입니다. 이 도전에 대한 목록 [2,2,3,3,4,4,5,5,...]입니다.
  • : 표시하고자하는 문자. 이 문제의 경우 이는 단순히 입력 문자열입니다.
  • : 캐릭터 라인을 그리려는 방향. 이 도전에 대한 방향은 다음과 같습니다[2,0,6,4] ([,,,]) 회전 입력 문자열에 따라 다른 시작 방향을 갖는 횟수 (즉, 입력 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 팁을 참조하십시오 (섹션 얼마나 큰 정수를 압축하는 방법을? ) 이유를 이해하는 Ž8O것입니다 2064.


0

파이썬 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 전용 : 질문의 저자를 인용 : "인쇄 대신 반환하면 큰 개선 또는 좋은 트릭이 표시되는 경우, 답변을 게시하십시오 (인쇄하지 않고 반환하고 있음을 명시하십시오)" . 그래서 괜찮습니다.
PieCot

0

MATLAB / 옥타브 , 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 전용

여기에 설명 된대로 @ASCII 전용 ( it.mathworks.com/matlabcentral/answers/… ), Matlab 세계의 stdout은 명령 창을 나타냅니다. 모든 명령의 평가 결과가 자동으로 명령 창에 인쇄되면이 답변이 질문의 요구 사항과 일치하는 것으로 간주 될 수 있다고 생각합니다.
PieCot


@ASCII 전용 나는 당신이 정말로 무엇을 의미하는지 이해하지 못합니다. 이것은 함수이며, 호출하면 결과가 명령 창에 자동으로 인쇄됩니다 (예 : stdout). 이게 뭐가 문제 야? R 답변조차도 이렇게 작동합니다 ...
PieCot

1
지금 당신 disp은, 당신은 제거해야합니다라고 말하고 싶지만 disp는 것을 R을 모르는 사람 수 있도록 않습니다 기본적으로 STDOUT에 쓰기
ASCII 전용
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.