줄을 Snakify


35

거친 문자열은 다음과 같습니다.

T AnE eOf ifi ing
h s x l A k e r
isI amp Sna dSt

당신의 작업

문자열 s과 크기를 n취한 다음 스키닝 된 문자열을 출력하십시오. 입력 ThisIsAnExampleOfaSnakifiedString하고 3위의 예제를 생성 할 것입니다.

사양

  • s 코드 포인트 33에서 126 사이의 ASCII 문자 만 포함합니다 (공백 또는 줄 바꿈 없음).
  • s 길이는 1 ~ 100 자입니다.
  • n는 각 출력 문자열 세그먼트의 크기를 나타내는 정수입니다. "뱀"에서 곡선을 구성하는 각 문자 줄 (위 / 아래 또는 왼쪽 / 오른쪽)은 n문자 길이입니다. 예제는 테스트 사례를 참조하십시오.
  • n 3에서 10 사이입니다.
  • 출력 문자열은 항상 아래쪽을 가리 키기 시작합니다.
  • 각 줄의 후행 공백이 허용됩니다.
  • 출력 끝에 줄 바꿈도 허용됩니다.
  • 선행 공백은 허용되지 않습니다.
  • 는 바이트 단위의 최단 코드를 의미합니다.

테스트 사례

a 3

a

----------

Hello,World! 3

H Wor
e , l
llo d!

----------

ProgrammingPuzzlesAndCodeGolf 4

P  ngPu  Code
r  i  z  d  G
o  m  z  n  o
gram  lesA  lf

----------

IHopeYourProgramWorksForInputStringsWhichAre100CharactersLongBecauseThisTestCaseWillFailIfItDoesNot. 5

I   gramW   tStri   100Ch   gBeca   CaseW   DoesN
H   o   o   u   n   e   a   n   u   t   i   t   o
o   r   r   p   g   r   r   o   s   s   l   I   t
p   P   k   n   s   A   a   L   e   e   l   f   .
eYour   sForI   Which   cters   ThisT   FailI

----------

!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~ 10

!        <=>?@ABCDE        `abcdefghi
"        ;        F        _        j
#        :        G        ^        k
$        9        H        ]        l
%        8        I        \        m
&        7        J        [        n
'        6        K        Z        o        ~
(        5        L        Y        p        }
)        4        M        X        q        |
*+,-./0123        NOPQRSTUVW        rstuvwxyz{

다음 도전은 snakified 문자열을 원래의 두 매개 변수로 다시 변환하는 것입니다 ...
abligh

@abligh 더 이상 계획이 없었지만 실제로는 괜찮은 아이디어처럼 들립니다. 그래도 어떤 형태의 복제가있을 수 있으므로 먼저 확인해야합니다. 계속 지켜봐주세요!
user81655

뱀이 임의의 모양이 될 수 있다면 반대 도전은 더 재미있을 것입니다 ...
abligh

@abligh 그것이 바로 하하를 계획하고 있었던 것입니다!
user81655

답변:



12

루비, 87 바이트

->s,n{p=0
a=(' '*(w=s.size)+$/)*n
w.times{|i|a[p]=s[i];p+=[w+1,1,-w-1,1][i/(n-1)%4]}
a}

규칙의 약간의 남용 Trailing spaces on each line are allowed.각 출력 줄은 w문자 길이와 줄 바꿈을 포함합니다. 여기 w에서 원래 문자열의 길이, 즉 전체 입력을 담을 수있을만큼 깁니다. 따라서 오른쪽에는 불필요한 공백이 많이 n있습니다.

테스트 프로그램에서 언 골프

f=->s,n{
  p=0                            #pointer to where the next character must be plotted to
  a=(' '*(w=s.size)+$/)*n        #w=length of input. make a string of n lines of w spaces, newline terminated
  w.times{|i|                    #for each character in the input (index i)
    a[p]=s[i]                    #copy the character to the position of the pointer
    p+=[w+1,1,-w-1,1][i/(n-1)%4] #move down,right,up,right and repeat. change direction every n-1 characters
  }
a}                               #return a

puts $/,f['a',3]

puts $/,f['Hello,World!',3]

puts $/,f['ProgrammingPuzzlesAndCodeGolf',4]

puts $/,f['IHopeYourProgramWorksForInputStringsWhichAre100CharactersLongBecauseThisTestCaseWillFailIfItDoesNot.',5]

puts $/,f['!"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~',10]

7

자바 스크립트 (ES6), 143 바이트

(s,n)=>[...s].map((c,i)=>(a[x][y]=c,i/=n)&1?y++:i&2?x--:x++,a=[...Array(n--)].map(_=>[]),x=y=0)&&a.map(b=>[...b].map(c=>c||' ').join``).join`\n`

어디 \n리터럴 개행 문자를 나타냅니다. 언 골프 드 :

function snakify(string, width) {
    var i;
    var result = new Array(width);
    for (i = 0; i < width; i++) result[i] = [];
    var x = 0;
    var y = 0;
    for (i = 0; i < string.length; i++) {
       result[x][y] = string[i];
       switch (i / (width - 1) & 3) {
       case 0: x++; break;
       case 1: y++; break;
       case 2: x--; break;
       case 3: y++; break;
    }
    for (i = 0; i < width; i++) {
        for (j = 0; j < r[i].length; j++) {
            if (!r[i][j]) r[i][j] = " ";
        }
        r[i] = r[i].join("");
    }
    return r.join("\n");
}

7

Pyth, 85 74 59 바이트

Kl@Q0J0=Y*]d-+*@Q1K@Q1 1FNr1@Q1=XY-+*KNN1b;VK=XYJ@@Q0N=+J@[+K1 1-_K1 1).&3/N-@Q1 1;sY

=G@Q1=H@Q0KlHJ0=Y*]dt+*GKGFNr1G=XYt+*KNNb;VK=XYJ@HN=+J@[hK1t_K1).&3/NtG;sY

Klz=Ym;+*QKQVQ=XYt+*KhNhNb;VK=XYZ@zN=+Z@[hK1_hK1).&3/NtQ;sY

나를 크게 도와 준 @FryAmTheEggman에게 감사합니다!

내가 할 수있는만큼 골프를 쳤다. 여기에서보십시오! 어떤 이유로, 줄 바꿈은 출력을 이상하게 만듭니다. 전체 페이지출력을 살펴볼 수 있습니다 .

설명

잠시 숨을 쉬고 집중하십시오. 이것은 거의 모든 "클래식"알고리즘과 같이 세 부분으로 나눌 수 있습니다.

첫 번째 섹션

변수가 초기화되는 곳입니다. 두 부분으로 나눌 수 있습니다.

Klz=Ym;+*QKQ
Klz                Assign len(input[0]) to K. (length of input String)
   =Ym;+*QKQ       Assign an empty list to Y of length K*input[1]-input[1]-1, where input[1] is the size of the snake 
                   (thus the height of the final string)

두 번째 부분 :

VQ=XYt+*KhNhNb;
VQ                       For N in range(0, input[1]), where input[1] is the size of the snake 
  =                        Assign to Y. Y is implicit, it is the last variable we used.
   XYt+*KhNhNb               Y[K*N+N-1]="\n". Can be broken down in four parts :
   X                           Replace function. X <A: list> <B: int> <C: any> is A[B]=C
    Y                          A: The array we initialized in the first section.
     t+*KhNhN                  B: K*(N+1)+N+1 (N is the for loop variable)
             b                 C: Newline character ("\n")
              ;          End the loop.

두 번째 섹션

실제 논리를 포함합니다.

VK=XYZ@zN=+Z@[hK1_hK1).&3/NtQ;
VK                                         For N in range(0, K), where K is the length of the input string (see first section)
  =                                          Assign to Y. Y is implicit, it is the last variable we used.
   XYZ@zN                                    Same as in section 2. This is a replacement function. Y[Z] = input[0][N]. Z is initially 0.
         =+Z@[hK1_hK1).&3/NtQ                Again this can be broken down :
         =+Z                                   Add to Z
             [hK1_hK1)                         Array containing directions. Respectively [K+1, 1, -K-1, 1]
            @         .&3/NtQ                  Lookup in the array, on index .&3/N-@Q1 1:
                      .&3                        Bitwise AND. .& <int> <int>
                         /NtQ                    (input[1]-1)/N, where input[1] is the size of the snake
                             ;             End the loop

세 번째 섹션

이것은 출력 부분입니다. 정말 흥미롭지 않은 ...

sY    Join the array Y. Implicitly print.

보너스

이 파이썬 스크립트에서 pyth 프로그램을 작성했습니다.

input=["ThisIsAnExampleOfASnakifiedString", 4];
width=len(input[0]);
height=input[1];
pointer=0;
directions = [width+1,1,-width-1,1] #Respectively Down, right, up, right (left is replaced by right because of snake's nature. Doesn't go left).
output=[' ' for i in range(0, width*height+height-1)];
for N in range(1, height):
    output[width*N+N-1]="\n";
for N in range(0, len(input[0])):  
    output[pointer]=input[0][N];
    pointer+=directions[3&(N/(height-1))];
print "".join(output);

5

자바 스크립트 (ES6), 122 바이트

document.write("<pre>"+(

// --- Solution ---
s=>n=>[...s].map((c,i)=>(a[p]=c,p+=[l+1,1,-l-1,1][i/n%4|0]),p=0,a=[...(" ".repeat(l=s.length)+`
`).repeat(n--)])&&a.join``
// ----------------

)("IHopeYourProgramWorksForInputStringsWhichAre100CharactersLongBecauseThisTestCaseWillFailIfItDoesNot.")(5))

@LevelRiverSt의 답변과 동일한 알고리즘.


4

C, 138 바이트

char*h[]={"\e[B\e[D","","\e[A\e[D",""},t[999];i;main(n){system("clear");for(scanf("%s%d",t,&n),--n;t[i];++i)printf("%c%s",t[i],h[i/n%4]);}

이것은 ANSI 이스케이프를 사용합니다. 리눅스 터미널에서 작동합니다.

언 골프 드 :

char*h[]={"\e[B\e[D","","\e[A\e[D",""},
    /* cursor movement - h[0] moves the cursor one down and one left,
    h[2] moves the cursor one up and one left. */
t[999];i;
main(n){
    system("clear");
    for(scanf("%s%d",t,&n),--n;t[i];++i)
        printf("%c%s",t[i],h[i/n%4]);
}

1

자바 스크립트 (ES6), 131

알고리즘 : 위치 매핑 x,y든 것처럼, 상기 입력 문자열의 인덱스를 출력하여 (관련없는) 않음.

@LevelRiverSt에서 가로 너비를 입력 길이와 동일하게 유지하는 트릭을 빌 렸습니다.

a=>m=>eval('for(--m,t=y=``;y<=m;++y,t+=`\n`)for(x=0;a[x];)t+=a[2*(x-x%m)+((h=x++%(2*m))?h-m?!y&h>m?h:y<m|h>m?NaN:m+h:m-y:y)]||`.`')

덜 골프

이것은 골프 전에 첫 번째 작업 초안이었습니다

f=(a,n)=>{
  l=a.length
  m=n-1
  s=m*2 // horizontal period

  b=-~(~-l/s)*m // total horizontal len, useless in golfed version
  t=''
  for(y=0;y<n;y++)
  {
    for(x=0;x<b;x++)
    {
      k = x / m | 0
      h = x % s
      if (h ==0 )
        c=k*s+y
      else if (h == m)
        c=k*s+m-y
      else if (y == 0 && h>m)
        c=k*s+h
      else if (y == m && h<m)
        c=k*s+m+h
      else
        c=-1
      t+=a[c]||' '
    }
    t+='\n'
  }
  return t
}  

테스트

F=a=>m=>eval('for(--m,t=y=``;y<=m;++y,t+=`\n`)for(x=0;a[x];)t+=a[2*(x-x%m)+((h=x++%(2*m))?h-m?!y&h>m?h:y<m|h>m?NaN:m+h:m-y:y)]||` `')

function test()
{
  var n=+N.value
  var s=S.value
  O.textContent=F(s)(n)
}  

test()
#S {width:80%}
#N {width:5%}
<input id=N value=5 type=number oninput='test()'>
<input id=S 5 oninput='test()'
value='IHopeYourProgramWorksForInputStringsWhichAre100CharactersLongBecauseThisTestCaseWillFailIfItDoesNot.'>
<pre id=O></pre>


0

Pyth, 122 바이트

=k@Q0J-@Q1 1K*4J=T*@Q1[*lkd;Vlk=Z+*%NJ/%N*J2J*/N*J2J=Y.a-+**/%N*J2J!/%NK*J2J*%NJ!/%N*J2J**!/%N*J2J/%NK*J2J XTYX@TYZ@kN;jbT

세그먼트 크기 / 모듈러스를 기준으로 각 문자의 x, y 위치를 계산하는 공식을 만들었지 만 예상보다 커졌습니다 .c

설명:

=k@Q0                                                                                                                     # Initialize var with the text
     J-@Q1 1                                                                                                              # Initialize var with the segment size (minus 1)
            K*4J                                                                                                          # Initialize var with the "block" size (where the pattern start to repeat)
                =T*@Q1[*lkd;                                                                                              # Initialize output var with an empty array of strings
                            Vlk                                                                                           # Interate over the text
                               =Z+*%NJ/%N*J2J*/N*J2J                                                                      # Matemagics to calculate X position
                                                    =Y.a-+**/%N*J2J!/%NK*J2J*%NJ!/%N*J2J**!/%N*J2J/%NK*J2J                # Matemagics to calculate Y position
                                                                                                          XTYX@TYZ@kN;    # Assign the letter being iterated at x,y in the output
                                                                                                                      jbT # Join with newlines and print the output

여기서 테스트

수학 공식의 경우, mod를 사용하여 0/1 플래그를 생성 한 다음 input을 기반으로하는 인수를 곱한 후 n스 니펫 벨로우즈의 각 단계에 스프레드 시트를 추가했습니다.


Matemagics을 설명 할 수 있습니까? 즉,보다 인간적인 방식으로 작성합니까?
FliiFe

@FliiFe 완료 c :
Rod

0

PHP, 127 126 124 120 119 118 117 110 106 바이트

ISO-8859-1 인코딩을 사용합니다.

for(;($q=&$o[$y+=$d]||$q=~ÿ)&&~Ï^$q[$x+=!$d]=$argv[1][$a];$a++%($argv[2]-1)?:$d-=-!$y?:1)?><?=join(~õ,$o);

다음과 같이 실행하십시오 ( -d미학에만 추가됨).

php -r 'for(;($q=&$o[$y+=$d]||$q=~ÿ)&&~Ï^$q[$x+=!$d]=$argv[1][$a];$a++%($argv[2]-1)?:$d-=-!$y?:1)?><?=join(~õ,$o);' "Hello W0rld!" 3 2>/dev/null;echo

언 골프 드 :

// Iterate over ...
for (
    ;
    // ... the characters of the input string. Prepend `0` so a 0 in the input
    // becomes truthy.
    0 . $char = $argv[1][$a];

    // Use modulo to determine the end of a stretch (where direction is
    // changed).
    // Change direction (`0` is right, `-1` is up and `1` is down). When
    // y coordinate is `0`, increment the direction, else decrement.
    $a++ % ($argv[2] - 1) ?: $direction += $y ? -1 : 1
)

    (
        // Increase or decrease y coordinate for direction -1 or 1 respectively.
        // Check whether the array index at new y coordinate is already set.
        $reference =& $output[$y += $direction] ||
        // If not, create it as a string (otherwise would be array of chars).
        // Null byte, won't be printed to prevent leading char.
        $reference = ~ÿ;

        // Increment x coordinate for direction 0. Set the output char at the
        // current coordinates to the char of the current iteration.
    ) & $reference[$x += !$direction] = $char;

// Output all lines, separated by a newline.
echo join(~õ, $output);

조정

  • <대신 에 사용하여 바이트를 저장했습니다.!=
  • 문자열을 0처음 에 설정하여 2 바이트를 절약 했으므로 다른 줄을 앞에 추가 할 필요가 없습니다 0(행의 첫 번째 출력이 0) 경우 진리를 산출합니다 00.
  • 반복하는 대신 참조를 사용하여 4 바이트 저장 $o[$y]
  • ==x 좌표를 변경하기 위해 방향을 1과 비교하는 대신 모듈로를 사용하여 바이트를 저장했습니다.
  • 문자열 오프셋이 어쨌든 int로 캐스팅되므로 문자열 오프셋 nullint대한 유형 캐스트 를 제거하여 바이트를 저장했습니다.
  • 짧은 인쇄 태그를 사용하여 바이트 저장
  • 방향 논리를 개선하여 7 바이트 절약
  • 중간을 막기 위해 문자를 직접 할당하여 4 바이트를 절약했습니다. $c
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.