이 질문에는 기복이 있습니다


33

입력은 다음 문자로 구성됩니다.

  • ^: 하나 올라가
  • v: 하나 내려가
  • 또는 k: 위로 올라가
  • 또는 j: 아래로 내려가

예를 들어 다음과 같은 입력이 있습니다.

^^▲^v▼▲^^v

다음과 같은 출력을 생성합니다.

        ^
   ^   ^ v
  ▲ v ▲

 ^   ▼
^

커서를 움직이는 이스케이프 시퀀스 \e[B는 허용되지 않습니다. 공백과 줄 바꾸기를 사용하여 출력을 생성해야합니다.

다음은 몇 가지 테스트 사례입니다.

▲v^v^v^v^v^v^v^v▲

                ▲
▲ ^ ^ ^ ^ ^ ^ ^ 
 v v v v v v v v

^^^^^^^▲▲▲▼▼▼vvvvvv

         ▲

        ▲ ▼

       ▲   ▼

      ^     ▼
     ^       v
    ^         v
   ^           v
  ^             v
 ^               v
^                 v

v^^vv^^vvv^v^v^^^vvvv^^v^^vv

  ^   ^         ^
 ^ v ^ v       ^ v       ^
v   v   v ^ ^ ^   v   ^ ^ v
         v v v     v ^ v   v
                    v

1
후행 공간이 허용됩니까? 빈 줄?
xnor

2
유니 코드를 지원하지 않는 언어는 어떻습니까? 대체 문자를 사용할 수 있습니까?
Doorknob

1
@xnor 후행 공백 및 / 또는 빈 줄이 허용됩니다.
absinthe

2
@Doorknob 나는 j두 번 내려 k가고 두 번 올라갈 수 있습니다.
absinthe

1
@xnor My bad : / 댓글이 정확하고 규칙을 잘못 편집했습니다. 지금 해결하겠습니다.
압생트

답변:


9

Pyth, 27 바이트

jCm.<.[*5lzd\ =+Ztx"v ^k"dz

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

나는 사용한다 k 하고 j대신 하고 . 앞뒤 빈 줄이 많이 있습니다. 이미지를 찾으려면 꽤 많이 검색해야합니다. 다음은 앞뒤 빈 줄을 모두 제거 하는 34 바이트 버전입니다.

j.sCm.<.[*5lzd\ =+Ztx"v ^k"dz]*lzd

온라인으로 사용해보십시오 : 데모 또는 테스트 스위트

설명:

jCm.<.[*5lzd\ =+Ztx"v ^k"dz  implicit: Z = 0
  m                       z  map each char d from input string z to:
                  x"v ^k"d     find d in the string "v ^k", -1 if not found
                 t             -1, that gives -2 for j, -1 for v, 1 for ^ and 2 for k
              =+Z              add this number to Z
     .[*5lzd\                  append spaces on the left and on the right of d, 
                               creating a 5*len(input_string) long string
   .<           Z              rotate this string to the left by Z chars
jC                           transpose and print on lines

16

읽을 수 없음 , 2199 2145 2134 2104 2087 2084 바이트

모두 지원 k/j 뿐만 아니라 / 구문을 합니다.

읽을 수없는 전통에서는 아포스트로피와 큰 따옴표를 구별하기 위해 비례 글꼴 형식의 프로그램이 있습니다.

' "" "" ""' "" "" "" "" ' "" "" ""' "" "" "" "" "" "" " '" "" "" "" "" "" "' ' "" ' "" "" "'" " '" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ' "" "" " " '" "" "" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""' "" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" " '" "" "" "" "" "" "" "" "" "" ' ""' "" ' ""' "" ' "" "'" "" "" "" "" "" "" "" " '" "" "" "" "" "" "" "" "" "" " '" "" "" "" "" "" "'" "" "" "" "" " '" "" ""' "" "" "" "" "" "" "" "" "" "" '" "" ""' "" ' ""' "" ' "" "" "" "" "" "" "" "" "" "" "" "" "" ""' "" "" "" ' ""' "" " '" "" "" "" "'" "" "" "" " '" "'" " '" "'" " '" "" "" "'" "" "" " ' "" "" "" "" "" "" "" "" "" "" "" "" ' "" "" "" "" "" "" "" "" "" "" "" "' '"" "" "" "" "" "" ' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" ' "" "" "" "" "'" " '" "" "" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ' "" "'" " '" "" "" "" ""' "" "" "" "" "" "" "" "" "" "" ""' ""' "" ' ""' "" ' ""' "" "" "" " '" "" "" "" "" "" "" "" "" "" ""' "" "" "" "" "" "" "" "" "" ' "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '" "'" " '" "'" "" "" "" ' "" "'" "" ' ""' "" "" "" ' "" "" """ '" "" "" "" ""' "" "" "" "" "" ' ""' "" "" " '" "" "" "" "" "" "" "" "" "" " "" ' "" "" "'" "" "" " '" "" "" "" "'" "" "" " '" "" "" "" "" "" "" "" "" "" " " '" "" ""' "" ' "" "'" "" "" "" "" ' "" "" "" "" "" "" "" "" "" "" "" ""' ""' "" " '" "" "" "'" " '" "" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" " " '" "" "" "" "" "'" " '" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " ' ""' "" " '" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ''"" "" "" "" ' "" "" "" "'" "" "" "" " '" "" "" "" "" "" "" "" "" "" "" "" "" " ' "" "" "" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " " '" "" "" "'" "" "" " '" "" "" "" ""' "" "" "" "" "" "" "" "" "" "" "" "' "" "" "" "'" "" "" " '" "" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" " ' "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" " '" "" "" "" "" "" "" "" "" " "" "" "" "" "" " '" "'" " '" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "' "" "" "" "" "" "'" " '" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ' ""' "" ' "" "'" " '" "" "" "" "" "" "" "" "" "'" "" "" "" "" "" "" "" "" "" " "" "" " '" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "'"" "" "" "" "" "" "" "" ' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " " '" "" "" "" "" "" "'" "" "" "" " '" "" "" ""' "" "" "" "" "" "" "" "" "" " ' "" "" ""' "" "" "" " '" "" "" ""' "" "" "" "" "" ' ""' "" "" "" "" " ''"" ' "" "" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '" "" "" "'" " '" ""' "" "" " '" "'" " '" "'" "" "" "" "" "" "" " '" "" "" " ' ""' "" " '" "" ""' "" "" "" "" "" "" "" "" "" ' "" "" "" "" "" "" "" "" """ '" "" "" "" "'" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " "" ' "" "" "'" "" "" "" ' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" '" "" "" "'" " '" "'" " '" "'" " '" "'" " '" "'" " '" "" ""' "" ' "" "" "" ' ""' "" ' ""' "" ' ""' "" "" "" "" "" "" "" "" " '" "" "" "" "" "" "" "" "" "" "" ' "" "" "" "" ""' "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" " '" "" """" "" " '" "'" ""

이것은 놀라운 도전이었습니다. 게시 해 주셔서 감사합니다!

설명

읽을 수없는 것과 할 수없는 것에 대한 느낌을 얻으려면 양방향으로 무한 테이프를 사용하는 Brainfuck을 상상해보십시오. 그러나 한 번에 한 셀씩 이동하는 메모리 포인터 대신 포인터를 역 참조하여 모든 메모리 셀에 액세스 할 수 있습니다. 모듈로를 포함한 다른 산술 연산은 수작업으로 수행해야하지만, 이것은이 솔루션에서 매우 유용합니다.

다음은 director의 논평과 함께 의사 코드로 작성된 프로그램입니다.

// Initialize memory pointer. Why 5 will be explained at the very end!
ptr = 5

// FIRST PASS:
// Read all characters from stdin, store them in memory, and also keep track of the
// current line number at each character.

// We need the +1 here so that EOF, which is -1, ends the loop. We increment ptr by 2
// because we use two memory cells for each input character: one contains the actual
// character (which we store here); the other will contain the line number at which the
// character occurs (updated at the end of this loop body).
while ch = (*(ptr += 2) = read) + 1:

    // At this point, ch will be one more than the actual value.
    // However, the most code-economical way for the following loop is to
    // decrement inside the while condition. This way we get one fewer
    // iteration than the value of ch. Thus, the +1 comes in handy.

    // We are now going to calculate modulo 4 and 5. Why? Because
    // the mod 4 and 5 values of the desired input characters are:
    //
    //  ch  %5  %4
    //  ^   1
    //  v   2
    //  k   3
    //  j   4
    //  ▲   0   2
    //  ▼   0   0
    //
    // As you can see, %5 allows us to differentiate all of them except ▲/▼,
    // so we use %4 to differentiate between those two.

    mod4 = 0      // read Update 2 to find out why mod5 = 0 is missing
    while --ch:
        mod5 = mod5 ? mod5 + 1 : -4
        mod4 = mod4 ? mod4 + 1 : -3

    // At the end of this loop, the value of mod5 is ch % 5, except that it
    // uses negative numbers: -4 instead of 1, -3 instead of 2, etc. up to 0.
    // Similarly, mod4 is ch % 4 with negative numbers.

    // How many lines do we need to go up or down?
    // We deliberately store a value 1 higher here, which serves two purposes.
    // One, as already stated, while loops are shorter in code if the decrement
    // happens inside the while condition. Secondly, the number 1 ('""") is
    // much shorter than 0 ('""""""""'""").
    up = (mod5 ? mod5+1 ? mod5+3 ? 1 : 3 : 2 : mod4 ? 3 : 1)
    dn = (mod5 ? mod5+2 ? mod5+4 ? 1 : 3 : 2 : mod4 ? 1 : 3)

    // As an aside, here’s the reason I made the modulos negative. The -1 instruction
    // is much longer than the +1 instruction. In the above while loop, we only have
    // two negative numbers (-3 and -4). If they were positive, then the conditions in
    // the above ternaries, such as mod5+3, would have to be mod5-3 etc. instead. There
    // are many more of those, so the code would be longer.

    // Update the line numbers. The variables updated here are:
    // curLine = current line number (initially 0)
    // minLine = smallest linenum so far, relative to curLine (always non-positive)
    // maxLine = highest linenum so far, relative to curLine (always non-negative)
    // This way, we will know the vertical extent of our foray at the end.

    while --up:
        curLine--
        minLine ? minLine++ : no-op
        maxLine++

    while --dn:
        curLine++
        minLine--
        maxLine ? maxLine-- : no-op

    // Store the current line number in memory, but +1 (for a later while loop)
    *(ptr + 1) = curLine + 1

// At the end of this, minLine and maxLine are still relative to curLine.
// The real minimum line number is curLine + minLine.
// The real maximum line number is curLine + maxLine.
// The total number of lines to output is maxLine - minLine.

// Calculate the number of lines (into maxLine) and the real minimum
// line number (into curLine) in a single loop. Note that maxLine is
// now off by 1 because it started at 0 and thus the very line in which
// everything began was never counted.
while (++minLine) - 1:
  curLine--
  maxLine++

// Make all the row numbers in memory positive by adding curLine to all of them.
while (++curLine) - 1:
  ptr2 = ptr + 1
  while (ptr2 -= 2) - 2:    // Why -2? Read until end!
    *ptr2++

// Finally, output line by line. At each line, we go through the memory, output the
// characters whose the line number is 0, and decrement that line number. This way,
// characters “come into view” in each line by passing across the line number 0.
while (--maxLine) + 2:    // +2 because maxLine is off by 1
  ptr3 = 5
  while (ptr -= 2) - 5:
    print (*((ptr3 += 2) + 1) = *(ptr3 + 1) - 1) ? 32 : *ptr3   // 32 = space
  ptr = ptr3 + 2
  print 10  // newline

프로그램 논리에 너무 많은. 이제 이것을 읽을 수 없음 으로 변환 하고 몇 가지 더 재미있는 골프 트릭을 사용해야합니다.

변수는 읽을 수없는 상태에서 항상 숫자로 역 참조 a = 1됩니다 (예 : 와 유사 함 *(1) = 1). 일부 숫자 리터럴은 다른 문자보다 길다. 가장 짧은 것은 1, 그 뒤에 2 등이 있습니다. 음수가 얼마나 긴지를 보여주기 위해 -1에서 7까지의 숫자는 다음과 같습니다.

-1  '""""""""'""""""""'"""  22
 0  '""""""""'"""           13
 1  '"""                     4
 2  '""'"""                  7
 3  '""'""'"""              10
 4  '""'""'""'"""           13
 5  '""'""'""'""'"""        16
 6  '""'""'""'""'""'"""     19
 7  '""'""'""'""'""'""'"""  22

분명히, 변수 # 1을 코드에서 가장 자주 발생하는 변수할당 하려고 합니다. 첫 번째 while 루프에서 이것은 확실히 mod510 번 나타납니다. 그러나 mod5첫 번째 while 루프 이후에는 더 이상 필요하지 않으므로 동일한 메모리 위치를 나중에 사용하는 다른 변수에 다시 할당 할 수 있습니다. 이들은 ptr2ptr3. 이제 변수는 총 21 번 참조됩니다. (발생 횟수를 직접 계산하려는 경우 다음과 같이 계산하십시오.a++ 값을 얻기 위해 한 번 설정하고 설정하기 위해 한 번 두 번 .)

재사용 할 수있는 다른 변수는 하나뿐입니다. 모듈로 값을 계산 한 후에 ch는 더 이상 필요하지 않습니다. up그리고 dn그렇게 두 괜찮 동일한 횟수를 온다. ch와 합병합시다 up.

총 8 개의 고유 변수가 남습니다. 변수 0에서 7을 할당 한 다음 8에서 문자와 줄 번호를 포함하여 메모리 블록을 시작할 수 있습니다. 그러나! 7은 코드에서 -1과 길이가 같으므로 변수 -1에서 6까지를 사용하고 메모리 블록을 7에서 시작할 수 있습니다. 이렇게하면 메모리 블록의 시작 위치에 대한 모든 참조가 코드에서 약간 짧아집니다! 이것은 우리에게 다음과 같은 과제를 남깁니다.

-1    dn
 0                      ← ptr or minLine?
 1    mod5, ptr2, ptr3
 2    curLine
 3    maxLine
 4                      ← ptr or minLine?
 5    ch, up
 6    mod4
 7... [data block]

이제 이것은 맨 위의 초기화를 설명합니다 .7 (메모리 블록의 시작)에서 2를 뺀 값이므로 2입니다 (첫 번째 while 조건의 필수 증분). 마지막 루프에서 5의 다른 두 발생에 대해서도 마찬가지입니다.

0과 4 코드에서 같은 길이이며, 이후, 그 주 ptrminLine방법 주위 중 하나를 할당 할 수 있습니다. ... 아니면 그들이 할 수 있습니까?

두 번째 마지막 while 루프에서 신비한 2는 어떻습니까? 6이 아니어야합니까? 데이터 블록의 숫자 만 줄이려고합니다. 6에 도달하면 데이터 블록 외부에 있으므로 중지해야합니다! 버퍼 오버 플로우 버그 오류 실패 보안 취약점입니다!

우리가 멈추지 않으면 어떻게 될지 생각해보십시오. 변수 6과 4를 줄입니다 mod4. 변수 6은 입니다. 첫 번째 while 루프에서만 사용되며 더 이상 필요하지 않으므로 해를 끼치 지 않습니다. 변수 4는 어떻습니까? 당신은 어떻게 생각하십니까, 변수 4해야 ptr아니면해야 minLine? 그렇습니다 minLine.이 시점에서 더 이상 사용되지 않습니다! 따라서 변수 # 4는 minLine우리가 안전하게 감소시키고 피해를 줄 수 없습니다!

업데이트 1! 그 실현에 의해 2145 바이트로 2199에서 Golfed dn 합병 할 수 mod5에도 불구하고, mod5여전히 값의 계산에 사용됩니다 dn! 새로운 변수 할당은 다음과 같습니다 :

 0    ptr
 1    mod5, dn, ptr2, ptr3
 2    curLine
 3    maxLine
 4    minLine
 5    ch, up
 6    mod4
 7... [data block]

업데이트 2! while 루프에서 0으로 계산 되는와 mod5동일한 변수에 있으므로 더 이상 0으로 명시 적으로 초기화 할 필요가 없음 을 인식하여 2145 바이트에서 2134 바이트로 골프를 쳤습니다 .dnmod5

업데이트 3! 두 가지를 실현하여 2134 바이트에서 2104 바이트로 골프를 쳤다. 첫째, "네거티브 모듈로"아이디어는 그만한 가치가 있지만 mod5, mod4우리는 절대로 테스트하지 않기 때문에 동일한 추론이 적용되지 않습니다 mod4+2. 따라서 2110 바이트로 변경 mod4 ? mod4+1 : -3하면 mod4 ? mod4-1 : 3됩니다. 둘째, mod4항상 0 또는 2이므로 mod40 대신 2로 초기화 하고 두 삼항을 반대로 할 수 있습니다 ( mod4 ? 3 : 1대신 mod4 ? 1 : 3).

업데이트 4! 모듈로 값을 계산하는 while 루프는 항상 한 번 이상 실행된다는 것을 인식하여 2104에서 2087 바이트로 골프를 쳤으며,이 경우 읽을 수없는 경우 다른 명령문에서 마지막 명령문의 값을 재사용 할 수 있습니다. 따라서 while --ch: [...]; up = (mod5 ? mod5+1 ? [...]이제 우리 대신 up = ((while --ch: [...]) ? mod5+1 ? [...](그리고 while 루프 안에서 mod4먼저 계산 하므로 mod5마지막 문장입니다).

업데이트 5! 상수 3210(공백 및 줄 바꿈) 을 작성하는 대신 (현재 사용되지 않은) 변수 # 2에 전화 번호 10을 저장할 수 있음을 인식하여 2087에서 2084 바이트로 골프를 쳤 습니다 ten. 대신에 ptr3 = 5우리가 쓰기 ten = (ptr3 = 5) + 532하게 ten+22print 10된다 print ten.


이건 ... 끔찍 ... +1
kirbyfan64sos

6

CJam, 37 바이트

r_,2*:L3*S*f{\_iImd8-g\8>)*L+:L\t}zN*

이것은 OP가 허용 한 원하는 출력 전후에 빈 줄을 인쇄합니다 .

CJam 통역사 에서 온라인으로 사용해보십시오 .

작동 원리

r_     e# Read a token from STDIN and push a copy.
,2*:L  e# Compute its length, double it and save it in L.
3*S*   e# Push a string of 6L spaces.
f{     e# For each character C in the input, push C and the string of spaces; then
  \    e#   Swap C with the string of spaces.
  _i   e#   Push a copy of C and cast it to integer.
  Imd  e#   Push quotient and remainder of its division by 18.
  8-g  e#   Push the sign((C%18) - 8). Gives -1 for ^ and ▲, 1 for v and ▼.
  \    e#   Swap the result with the quotient.
  8>)  e#   Push ((C/18) > 1) + 1. Gives 2 for ▲ and ▼, 1 for ^ and v.
  *    e#   Multiply both results. This pushes the correct step value.
  L+:L e#   Add the product to L, updating L.
  \t   e#   Replace the space at index L with C.
}      e# We've built the columns of the output.
z      e# Zip; transpose rows with columns.
N*     e# Join the rows, separating by linefeeds.

귀하의 솔루션이 원하는 출력 전후에 많은 양의 추가 줄 바꿈을 생성한다는주의 사항으로 명시 적으로 언급하는 것이 공정하다고 생각합니다 ...
Timwi

추가되었습니다. (OP가 명시 적으로 빈 줄을 허용 한 이후로 그것이 필요하다고 생각하지 않았다.)
Dennis

3

파이썬 2, 102

s=input()
j=3*len(s)
exec"w='';i=j=j-1\nfor c in s:i-='kv_^j'.find(c)-2;w+=i and' 'or c\nprint w;"*2*j

한 줄씩 인쇄합니다.

입력에서 문자를 반복하고 현재 높이를 추적합니다. 높이는에 의해 +2, +1, -1, -2계산 된 것 중 하나로 업데이트 됩니다 'kv_^j'.find(c)-2. 더 짧은 모드 체인이있을 수 있습니다.

현재 높이가 줄 번호와 같으면 (음수 일 수 있음) 현재 문자를 줄에 추가하고 그렇지 않으면 공백을 추가합니다. 그런 다음 줄을 인쇄합니다. 실제로, 현재 줄 번호에서 높이를 시작하고 높이 변경을 빼서 값이 닿을 때 문자를 추가하는 것이 더 짧습니다 0.

라인 번호는 2 개 또는 2 개 시퀀스가 ​​그 안에 머무를 수있을 정도로 큰 범위를 포함합니다. 실제로, 상당한 양의 초과가 있습니다. 입력 길이에 상한이 있으면 작성하는 것이 더 짧습니다 j=999.

놀랍게도 i and' 'or c평소보다 짧았습니다 [' ',c][i==0]. 참고 i음수가 될 수있는 몇 가지 일반적인 트릭 밖으로 잘라냅니다.


2

MATLAB, 116

function o=u(a)
x=0;y=1;o='';for c=a b=find(c=='j^ vk')-3;y=y+b;if y<1 o=[zeros(1-y,x);o];y=1;end
x=x+1;o(y,x)=c;end

시작입니다. jk내가 수학에서지도하는 방법을 찾을 수 없습니다로 목에 통증이 만들 j^vk에를[-2 -1 1 2] 하고 MATLAB은 유니 코드를 인식하지와 (MATLAB. 이동 그림 26의 값이 아래로 분명히까지 모두와!)이 있습니다 매핑을 수행하는 데 많은 바이트가 낭비되었습니다.

@xnors 솔루션에서 영감을 얻어 for 루프 내부에 제어 문자를 매핑하여 코드를 14 자 더 줄일 수 있습니다.

입력 문자열이 패턴을 시작한 색인 아래로 패턴을 다시 보내는 지 고려하기 위해 많은 바이트가 낭비됩니다 (문자열 길이에 제한이있는 경우 해당 비트를 단순화 할 수 있음).

그리고 읽을 수있는 형태로 :

function o=u(a)
%We start in the top left corner.
x=0; %Although the x coordinate is 1 less than it should be as we add one before storing the character
y=1;
o=''; %Start with a blank array
for c=a
    %Map the current character to [-2 -1 1 2] for 'j^vk' respectively.
    b=find(c=='j^ vk')-3;
    y=y+b; %Offset y by our character
    if y<1 %If it goes out of range of the array
        o=[zeros(1-y,x); o]; %Add enough extra lines to the array. This is a bit of a hack as 0 prints as a space in MATLAB.
        y=1; %Reset the y index as we have now rearranged the array
    end
    x=x+1; %Move to the next x coordinate (this is why we start at x=0
    o(y,x)=c; %Store the control character in the x'th position at the correct height.
end

시겠습니까 b=[-2 -1 1 2](a==[106 107 94 118])일? 옥타브에서 작동합니다. 또는 b=[-2 -1 1 2](a-94==[12 13 0 24])하나 이상의 바이트를 면도하려는 경우 에도 !
wchargin

@WChargin은 MATLAB에서 작동하지 않습니다. 불행히도 ==중지 동작은 작동을 멈추고 MATLAB에서는 a ()다음을 넣을 수 없습니다 [].
Tom Carpenter

흠… 언어를 옥타브로 바꿀 수 있습니다! :) (옥타브는 또한 다음 +=과 같습니다.)
wchargin

@WChargin 부정 행위입니다 = P 그러나 Octave에는 Matlab에없는 단축키가 많이 있습니다.
flawr

2

자바 스크립트 (ES6), 140

EcmaScript 6 호환 브라우저 (Firefox에서 테스트)에서 아래 스 니펫 실행을 테스트하십시오.

f=s=>[...s].map(c=>{for(t=r[y+=c>'▲'?2:c>'v'?-2:c>'^'?1:-1]||x;y<0;y++)r=[,...r];r[y]=t+x.slice(t.length)+c,x+=' '},y=0,r=[x=''])&&r.join`
`

// Less golfed

f=s=>(
  y=0,
  x='',
  r=[],
  [...s].forEach( c =>
    {
      y += c > '▲' ? 2 : c > 'v' ? -2 : c > '^' ? 1 : -1;
      t = r[y] || x;
      while (y < 0)
      {
        y++;
        r = [,...r]
      }  
      r[y] = t + x.slice(t.length) + c;
      x += ' '
    }
  ),
  r.join`\n`
)  


//Test

;[
  '^^▲^v▼▲^^v'
, '▲v^v^v^v^v^v^v^v▲'
, '^^^^^^^▲▲▲▼▼▼vvvvvv'
, 'v^^vv^^vvv^v^v^^^vvvv^^v^^vv'  
].forEach(t=>document.write(`${t}<pre>${f(t)}</pre>`))
pre { border:1px solid #777 }


1

GS2, 34 바이트

이것은 출력 경계를 올바르게 계산하므로 여분의 공백이 생성되지 않습니다. 여기 16 진법으로 된 해결책이 있습니다.

5e 20 76 6a 05 3e 26 ea 30 e0 6d 40 28 26 cf d3
31 e9 d0 4d 42 5e e2 b1 40 2e e8 29 cf d3 5c e9
9a 54

작은 설명이 순서대로 있습니다. 스택에는 ASCII 코드 배열로 사용자 입력이 있습니다. 로 인해 문자열 리터럴로 프로그램이 시작됩니다 05. 여기 있습니다

  5e 20 76 6a      # ascii for "^ vj"
  05               # finish string literal and push to stack
  3e               # index - find index in array or -1 if not found
  26               # decrement
ea                 # map array using block of 3 instructions (indented)

  30               # add 
e0                 # create a block of 1 instruction
6d                 # scan (create running total array of array using block)
40                 # duplicate top of stack
28                 # get minimum of array
26                 # decrement
cf                 # pop from stack into register D (this is the "highest" the path goes)

  d3               # push onto stack from register D
  31               # subtract
e9                 # map array using block of 2 instructions

d0                 # push onto stack from register A (unitialized, so it contains stdin)

  4d               # itemize - make singleton array (also is single char string)
  42               # swap top two elements in stack
  5e               # rjust - right justify string
e2                 # make block from 3 instructions
b1                 # zipwith - evaluate block using parallel inputs from two arrays
40                 # duplicate top of stack

  2e               # get length of array/string
e8                 # map array using block of 1 instruction
29                 # get maximum of array
cf                 # pop from stack into register D (this is the "lowest" the path goes)

  d3               # push from register D onto stack
  5c               # ljust - left justify string
e9                 # map array using block of two instructions
9a                 # transpose array of arrays
54                 # show-lines - add a newline to end of each element in array

GS2, 24 바이트

또한 출력 크기를 계산하는 데 많은주의를 기울이지 않고 추가 공백으로 끝나는 24 바이트 솔루션이 있습니다. 그래도 공백이 최소 인 것을 선호합니다.

5e 20 76 6a 05 3e 26 ea 30 e0 6d d0 08 4d 42 d1
30 5e d1 5c 09 b1 9a 54

1

크레용 , 13 바이트 (비경쟁)

O"^ vj"\CynIq

온라인으로 사용해보십시오! 왜 진짜 화살표를 사용합니까?

크레용은이 도전보다 새로운 것이기 때문에 비경쟁입니다.

작동 원리

Crayon은 ASCII 기술 문제를 해결하기 위해 설계된 스택 기반 언어입니다. 이 캔버스는 2 차원 출력 "캔버스"와이 캔버스 주위를 이동하는 커서 인 "크레용"을 기반으로합니다. 출력으로 보내지는 것은 크레용의 위치와 크레용이 향하는 방향으로 캔버스에 그려집니다. 기본적으로 크레용은 동쪽 (오른쪽)을 가리 킵니다.

O"^ v▼"\CynIq   Implicit: input string is on top of the stack
O               For each char I in the input string:
 "^ v▼"          Push this string.
       \         Swap the top two items (so I is on top).
        C        Take the index of I in the string.
                 This returns 3 for ▼, 2 for v, 0 for ^, and -1 for ▲.
         y       Move the crayon by this number of spaces on the Y-axis (south).
          n      Move the crayon one position north.
                 The crayon has now been translated 2 positions south for ▼,
                 1 south for v, 1 north for ^, and 2 north for ▲.
           Iq    Draw I at the crayon. This automatically moves the crayon forward
                 by the length of I, which is 1 in this case.

0

pb -136 바이트

^w[B!0]{>}v[3*X]<[X]<b[1]^[Y]^>w[B!0]{t[B]<vw[B=0]{v}>w[T=107]{^^b[T]t[0]}w[T=94]{^b[T]t[0]}w[T=118]{vb[T]t[0]}w[T!0]{vvb[T]t[0]}^[Y]^>}

용도 kj대신 하고 .

몇 가지 메모 :

  • Escape sequences that move the cursor such as \e[B are not allowed. You must produce the output using spaces and newlines.나는이 규칙을 따른다! pb는 "브러시"개념을 사용하여 문자를 출력합니다. 브러시가 "캔버스"주위를 이동하고 바로 아래에 문자를 인쇄 할 수 있습니다. 그러나 실제 구현에서는 공백과 줄 바꿈을 사용하여 문자를 인쇄합니다.
  • 나는 판결을 볼 때까지 pb와 함께 재미있을 것이라고 생각했지만이 도전에 귀찮게하지 않을 것입니다 You are allowed trailing spaces and/or empty lines. 이것은 몇 가지 이유 때문입니다.
    • PB는 할 수 없습니다 후행 공백을했다. 필요한 경우 항상 공백으로 채워진 직사각형 출력을 생성합니다.
    • 이 프로그램은 많은 빈 줄을 생성합니다. 출력을 시작할 때 출력이 얼마나 키가 큰지 알지 못하므로 길이 입력은 n에서 시작합니다 Y=3n+1. 은 -1이 아래로 가고 있기 때문에이다 3n에서 Y=-1, 그리고 시작 Y=2n-1모든 입력 실패 k.

이 프로그램을 YouTube에서 실제로 볼 수 있습니다! 이 버전은로만 변경되어 약간 수정되었습니다 n-1. 이 입력에 대해서는 작동하지만 다른 사람에게는 실패합니다. 그러나 훨씬 더 잘 캡처합니다.

의견 :

^w[B!0]{>}             # Go to the end of the input
v[3*X]                 # Go down 3 times the current X value
<[X]<                  # Go to X=-1 (off screen, won't be printed)
b[1]                   # Leave a non-zero value to find later
^[Y]^>                 # Back to the beginning of the input
w[B!0]{                # For every byte of input:
    t[B]                 # Copy it to T
    <vw[B=0]{v}>         # Go 1 to the right of the character to the left
                         # (either the last one printed or the value at X=-1)
                         # Move the correct amount for each character and print it:
    w[T=107]{^^b[T]t[0]} # k
    w[T=94]{^b[T]t[0]}   # ^
    w[T=118]{vb[T]t[0]}  # v
    w[T!0]{vvb[T]t[0]}   # j (Every other possibility sets T to 0, so if T is not 0
                         #    it must be j. T!0 is shorter than T=106)
    ^[Y]^>               # To the next byte of input to restart the loop
}

0

실론, 447 바이트

import ceylon.language{o=null,v=variable,s=shared}s void y(){v L c;v L f;v L l;v Integer i=0;class L(v L?p,v L?n){s v String t="";s L u=>p else(f=p=L(o,this));s L d=>n else(l=n=L(this,o));s void a(Character c)=>t=t+" ".repeat(i-t.size)+c.string;}f=l=c=L(o,o);for(x in process.readLine()else""){switch(x)case('^'){c=c.u;}case('v'){c=c.d;}case('▲'|'k'){c=c.u.u;}case('▼'|'j'){c=c.d.d;}else{}c.a(x);i++;}print(f.t);while(f!=l){f=f.d;print(f.t);}}

또는 "가독성"을위한 줄 바꿈이있는 경우 : import ceylon.language{o=null,v=variable,s=shared}s void y(){v L c;v L f;v L l;v Integer i=0;class L(v L?p,v L?n){s v String t="";s L u=>p else(f=p=L(o,this));s L d=>n else(l=n=L(this,o));s void a(Character c)=>t=t+" ".repeat(i-t.size)+c.string;}f=l=c=L(o,o);for(x in process.readLine()else""){switch(x)case('^'){c=c.u;}case('v'){c=c.d;}case('▲'|'k'){c=c.u.u;}case('▼'|'j'){c=c.d.d;}else{}c.a(x);i++;}print(f.t);while(f!=l){f=f.d;print(f.t);}}

이는 ▲ / ▼ 및 j / k 입력 모두에서 작동합니다 (하나만 지원해야하는 경우 프로그램은 8 바이트 더 짧습니다). 시작 위치가에 때 마지막 출력 라인이 비어 (즉, 첫 번째 입력은이었다 또는 ^우리는 나중에 다시 그 이하도 없었어). 지정된 문자 중 하나가 아닌 입력은 행을 전환하지 않고 그대로 인쇄됩니다.

v^^vv^^vvv^v^v^^^Hellovvvv^^v^^vv

  ^   ^         ^Hello
 ^ v ^ v       ^      v       ^
v   v   v ^ ^ ^        v   ^ ^ v
         v v v          v ^ v   v
                         v

다음은 형식화 된 버전 (753 바이트)입니다.

shared void y() {
    variable L c;
    variable L f;
    variable L l;
    variable Integer i = 0;
    class L(variable L? p, variable L? n) {
        shared variable String t = "";
        shared L u => p else (f = p = L(null, this));
        shared L d => n else (l = n = L(this, null));
        shared void a(Character c) => t = t + " ".repeat(i - t.size) + c.string;
    }
    f = l = c = L(null, null);
    for (x in process.readLine() else "") {
        switch (x)
        case ('^') { c = c.u; }
        case ('v') { c = c.d; }
        case ('▲' | 'k') { c = c.u.u; }
        case ('▼' | 'j') { c = c.d.d; }
        else {}
        c.a(x);
        i++;
    }
    print(f.t);
    while (f != l) {
        f = f.d;
        print(f.t);
    }
}

이것은 거의 직관적 인 "객체 지향"프로그램입니다. (로컬) 클래스 L(라인 버퍼)는 텍스트 줄 (in )과 t다음 ( n) 및 이전 ( p)에 대한 (널 가능) 포인터를 저장합니다. 선. (널을 사용할 수 없음) 속성 u(위쪽) 및d (아래쪽)은 필요한 경우 (자체에 대한 역방향 포인터로 초기화하며,이 경우 전체 및 첫 번째 라인과 마지막 라인을 추적합니다 ( fl 변수 .

그만큼 a(추가) 방법은 결국 필요한 일부 공간을 포함하여,이 라인에 문자를 추가한다.

c현재 줄입니다. 우리는 입력 문자열을 구문 분석합니다 (readLine현재 줄을 업데이트하는 switch 문을 입력이 한 줄에 있어야 함)을 한 다음 append 메서드를 호출합니다.

구문 분석이 완료되면 첫 번째에서 마지막 행까지 반복하여 각 행을 인쇄합니다. (이것은f 포인터를 나중에 필요할 경우 별도의 변수를 사용해야합니다.)

골프에 사용 된 몇 가지 트릭 :

  • 다른 언어로 키워드가 될 수있는 일부는 실제로 ceylon.language패키지의 식별자 일 뿐이며 별명 가져 오기로 이름을 바꿀 수 있습니다 . 객체 shared( 주석) (5x) 및 variable( 6x) 에이 이름을 사용했습니다. null(4 배 사용) :

    import ceylon.language{o=null,v=variable,s=shared}
    

    (Trivia : Ceylon IDE의 Formatter는 주석 variableshared같은 줄에 주석이 달린 선언과 같은 줄에 배치하여 선언 위에 별도의 줄에있는 사용자 지정 주석과 대조하여 일부 내장 언어 주석을 형식화 합니다. 골프 프로그램의 서식이 지정된 버전을 읽을 수 없으므로이 버전의 별칭 가져 오기를 다시 변경했습니다.)

    this, void, case, else실제 키워드이며, 이런 식으로 이름을 바꿀 수 없습니다, 그리고 Integer, String그리고 Character그렇게 가져 얻게 될 것이없는, 단지 각하면 나타납니다.

  • 원래 별도의 ScreenBuffer 클래스 (링크 버퍼 목록, 현재 색인 등)를 추적했지만 객체가 하나뿐이므로 최적화되었습니다.

  • 그 Screenbuffer 클래스 에는 파서에서 호출 된 메소드 updown메소드가 있습니다 ( currentLine = currentLine.up각각 방금 수행 했습니다 currentLine = currentLine.down). 파서의 스위치에서 직접 수행하는 것이 더 짧다는 것을 보여주었습니다. 또한 대신에 currentLine = currentLine.up.up(나중에되었다 c = c.u.u) 쓸 수 있었다 currentLine = currentLine.up;currentLine = currentLine.up.

  • 원래 우리는 append 메소드 (그리고 루프의 파서)에 인자로 현재 인덱스를 전달했습니다. 포함 함수의 변수가 더 짧아졌습니다.

  • 원래 내 printAll 메소드는 현재 포인터를 사용하여 현재 줄이 비어있을 때까지 위로 이동 한 다음 각 줄을 인쇄하는 동안 아래로 이동했습니다. 이것은 라인을 뛰어 넘기 위해 ▲와 ▼를 사용할 때 끊어 졌으므로 대신 점프 한 라인에 무언가를 명시 적으로 추가해야했습니다. 첫 번째 / 마지막 줄을 추적하는 것이 더 쉬워졌습니다 (실론에는 do-while-loop가 없기 때문에 두 개의 인쇄 문을 사용해야했습니다).

  • 원래 나는 이와 같은 것을 가지고 있었다 :

      String? input = process.readLine();
      if(exists input) {
         for(x in input) {
             ...
         }
      }
    

    process.readLinenull읽을 수있는 행이 없으면 (입력이 닫 혔기 때문에) 반환 하고 Ceylon 컴파일러는 액세스하기 전에 확인해야합니다 input. 이 경우와 같이 아무것도하고 싶지 else않으므로 null이 아닌 경우 첫 번째 인수를 반환하고 두 번째 인수를 반환하여 변수와 if 문을 저장하는 연산자를 동등하게 사용할 수 있습니다 . 또한 테스트를 위해 기본 입력을 인코딩 할 수 있습니다.for (x in process.readLine() else "^^▲^v▼▲^^v") { )


0

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

E=(r,p=(' '[M='repeat'](Z=r.length)+',')[M](Z*4),i=Z*2,k=0)=>Z>k?E(r,(p.split(',').map((o,q)=>q==i?o.slice(0,k)+r[k]+o.slice(k++):o)).join`,`,i+(H={'^':-1,k:-2,j:2,v:1})[r[k]],k):p.split(',').join`
`.replace(/\s+\n$|^\s+\n/g,'')

자, 여기에 주어진 모든 테스트 사례를 통과하는 (오래 긴) 재귀 솔루션이 있습니다. 좋은 도전이었습니다. 이 사용 k하고j 대신 하고 .

테스트 스 니펫

제출 자체 만 처리 할 수 있지만 k,j, 다음 코드는 모두 처리 할 수 k,j▼,▲.

E=(r,p=(' '[M='repeat'](Z=r.length)+',')[M](Z*4),i=Z*2,k=0)=>Z>k?E(r,(p.split(',').map((o,q)=>q==i?o.slice(0,k)+r[k]+o.slice(k++):o)).join`,`,i+(H={'^':-1,k:-2,j:2,v:1})[r[k]],k):p.split(',').join`
`.replace(/\s+\n$|^\s+\n/g,'')
Input: <input type="text" oninput=o.textContent=E(this.value.replace(/▲/g,'k').replace(//g,'j'))></input>
<pre id='o'></pre>

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.