행렬 지그재그 화


43

압축 알고리즘의 일부로 JPEG 표준은 교차 방향의 대각선을 따라 벡터로 행렬을 언 롤링합니다.

여기에 이미지 설명을 입력하십시오

당신의 임무는 반드시 정사각형이 아닌 행렬을 취하여 펼쳐진 형태로 반환하는 것입니다. 예로서:

[1 2 3 4
 5 6 7 8
 9 1 2 3]

양보해야한다

[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]

규칙

행렬 요소가보다 작은 양의 정수라고 가정 할 수 있습니다 10.

STDIN (또는 가장 가까운 대안), 명령 행 인수 또는 함수 인수를 통해 입력을 받고 STDOUT (또는 가장 가까운 대안), 함수 리턴 값 또는 함수 (out) 매개 변수를 통해 결과를 출력하는 프로그램 또는 함수를 작성할 수 있습니다.

입력 행렬은 임의의 편리한 모호하지 않은 중첩 목록 또는 문자열 형식으로 제공되거나 두 행렬 차원과 함께 플랫 목록으로 제공 될 수 있습니다. (또는 귀하의 언어에 매트릭스 유형이있는 경우 물론 매트릭스 유형으로도 사용됩니다.)

출력 벡터는 편리하고 모호하지 않은 플랫 목록 또는 문자열 형식 일 수 있습니다.

표준 규칙이 적용됩니다.

테스트 사례

[[1]]                                               => [1]
[[1 2] [3 1]]                                       => [1 2 3 1]
[[1 2 3 1]]                                         => [1 2 3 1]
[[1 2 3] [5 6 4] [9 7 8] [1 2 3]]                   => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 3 4] [5 6 7 8] [9 1 2 3]]                     => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 6 3 1 2] [5 9 4 7 8 3]]                       => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1 2 5 9 6 3 4 7 1 2 8 3]]                         => [1 2 5 9 6 3 4 7 1 2 8 3]
[[1] [2] [5] [9] [6] [3] [4] [7] [1] [2] [8] [3]]   => [1 2 5 9 6 3 4 7 1 2 8 3]

관련 도전


1
입력이 J의 실제 행렬이 될 수 있습니까? 아니면 함수의 일부로 중첩 목록에서 행렬로 바꿔야합니까?
Gareth

4
행렬을 2D 배열로 가져와도 차원을 입력으로 사용할 수 있습니까?
xnor

1
@Gareth yes 입력으로 행렬 유형을 사용할 수 있습니다.
Martin Ender

1
@ xnor Hmmm, 조금 까다 롭습니다. 나는 그 양의 중복 정보를 가져 와서 입력을 사전 처리하는 데 약간의 느낌이 듭니다.
Martin Ender

플랫리스트가 언어의 기본 순서 인 경우 열 순서로 정렬 될 수 있습니까?
Luis Mendo

답변:


27

J, 31 30 14 12 11 바이트

[:;<@|.`</.

Ych . 너무 큰.

행렬을 입력으로받습니다.

설명

J는 여기에 이점이 있습니다. 비스듬한 선을 차례로 가져 와서 동사를 적용하는 oblique ( /.) 라는 명령 이 있습니다. 이 경우 나는 gerund를 사용하여 두 개의 동사를 교대로 적용합니다 : <( box ) 및 <@|.( reverse and box). 그런 다음 ;( raze )를 사용하여 모든 것을 개봉하는 문제입니다 .


26
J는 영어를 이해하기 위해 고급 학위가 필요하다고 느끼는 유일한 언어입니다.
Alex A.

2
@AlexA. btw, "command"라는 단어는 "adverb"여야합니다.
Adám

11

Pyth, 24 23 21 20 19 18 17 바이트

ssm_W=!Td.T+LaYkQ

대체 17 바이트 버전 : ssuL_G=!T.T+LaYkQ

                Q  input
           +L      prepend to each subarray...
             aYk   (Y += ''). Y is initialized to [], so this prepends [''] to
                     the first subarray, ['', ''] to the second, etc.
                   ['' 1  2  3  4
                    '' '' 5  6  7  8
                    '' '' '' 9  1  2  3]
         .T        transpose, giving us
                   ['' '' ''
                    1  '' ''
                    2  5  ''
                    3  6  9
                    4  7  1
                    8  2
                    3]
  m_W=!Td          black magic
 s                 join subarrays together
s                  join *everything* on empty string (which means ''s used for
                     padding disappear)

덕분에 @FryAmTheEggman 바이트에 대한, @Jakube 2 바이트, 및 @isaacg 바이트에!

위에서 언급 한 "black magic"에 대한 설명 : m_W=!Td본질적으로 다른 모든 하위 배열을 반대로합니다. _W=!T각 하위 배열 에 매핑 하여이를 수행합니다. W조건부 응용이므로, _모든 부분 배열을 =!T참 (역수)시킵니다 . T는 10 (사실)으로 사전 초기화 된 변수이며를 =!T의미 (T = !T)합니다. 그래서 그것은 진실로 시작하는 변수의 값을 토글하고 새로운 값을 반환합니다.

여기에서 스위트를 테스트하십시오 .


11

젤리, 24 19 15 13 11 바이트

pS€żị"¥pỤị⁵

행 수, 열 수 및 단순 목록을 별도의 명령 줄 인수로 사용합니다.

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

작동 원리

pS€żị"¥pỤị⁵  Main link. Argument: m (rows), n (columns), A (list, flat)

p            Compute the Cartesian product [1, ..., m] × [1, ..., n]. This yields
             the indices of the matrix M, i.e., [[1, 1], [1, 2], ..., [m, n]].
 S€          Compute the sums of all index pairs.
       p     Yield the Cartesian product.
      ¥      Dyadic chain. Arguments: Sums, Cartesian product.
    ị"       For each index pair in the Cartesian product, retrieve the coordinate
             at the index of its sum, i.e., map [i, j] to i if i + j is odd and to
             j if i + j is even.
   ż         Zip the sums with the retrieved indices.
       Ụ     Sort [1, ..., mn] by the corresponding item in the resulting list.
        ị⁵   Retrieve the corresponding items from A.

Tsk. 내가 더 짧게 만들 수 있는지 확실하지 않습니다. : -S
Gareth

내가 시도하지 않겠다고 말하는 것은 아닙니다.
Gareth

젤리는 왜 오블 리크를 물려받지 않았을까? 나는 APL 글리프 제안 할 수 있습니다 ? 아니면 스칸디나비아 øǿ?
Adám

7

MATL , 28 27 바이트

tZyZ}:w:!+-1y^7MGn/*-X:K#S)

내 대답 에서 여기에 적응했습니다 . 일반적인 아이디어는 입력과 동일한 크기의 지그재그 경로와 같은 순서로 증가하는 값으로 채워진 2D 배열을 만드는 것입니다. 그런 다음 해당 배열의 선형화 된 (평평한) 버전이 정렬되고 해당 정렬 의 인덱스 가 유지됩니다. 지그재그 경로를 생성하기 위해 입력에 적용해야하는 인덱스입니다.

입력 양식

[1 2 3; 5 6 4; 9 7 8; 1 2 3]

설명

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

t       % input 2D array. Duplicate
ZyZ}    % get size as length-2 vector. Split into two numbers: r, c
:       % range [1,2,...,c] as a row vector
w:!     % swap, range [1;2;...;r] as a column vector
+       % add with broadcast. Gives a 2D array
-1      % push -1
y^      % duplicate previous 2D array. Compute -1 raised to that
7M      % push [1;2;...;r] again
Gn/     % divide by input matrix size, that is, r*c
*       % multiply
-       % subtract
X:      % linearize 2D array into column array
K#S     % sort and push the indices of the sorting. Gives a column vector
)       % index input matrix with that column vector

4

Matlab, 134 바이트

방금 전보와 같이 Matlab에서 코드를 줄이려고 최선을 다했습니다.

function V=z(M)
[m,n]=size(M);
a=(1:m)'*ones(1,n);
b=ones(m,1)*(1:n);
A=a+b-1;
B=a-b;
C=(A.^2+(-1).^A.*B+1);
[~,I]=sort(C(:));
V=M(:);
V=V(I)';

노트:

  1. Mm×n행렬.
  2. ab행렬은 크기가 모두 같고 M, 각 행은 a행 번호와 동일한 숫자로 구성되며의 각 열은 b열 번호와 동일합니다. 따라서 a+ b는 요소가 행과 열 번호의 합과 같은 행렬입니다 matrix(p,q)=p+q.
  3. 따라서 A(p,q)=p+q-1; 그리고 B(p,q)=p-q.
  4. C수학적으로 아래 방정식으로 표시됩니다. 지그재그로 증가하는 행렬 방정식으로, 지그재그로 증가하는 행렬은 아래와 같이 만들 수 있습니다.
C =
     1     2     6     7
     3     5     8    14
     4     9    13    18
    10    12    19    25
  1. C지그재그 결과에서 M의 요소 순서를 나타냅니다. 그런 다음, [~,I]=sort(C(:));즉, 순서를 반환 I, 따라서 V=V(I)'결과입니다.

예, 방금 찾았습니다. 이제 업데이트합니다.
Guoyang Qin

@AlexA. 고마워, 알렉스 나는 이것에 익숙하지 않고 가능한 한 짧게하고 발췌문으로 만들고 싶습니다. 이제 코드를 아직 수정했습니다.
Guoyang Qin

좋아 보인다 좋은 첫 포스트! :)
Alex A.

3

자바 스크립트 (SpiderMonkey 30+), 99 바이트

x=>[for(y of[...x,...x[0]].keys())for(z of Array(y+1).keys())if(a=x[y%2?z:y-z])if(b=a[y%2?y-z:z])b]

Firefox 44에서 테스트되었습니다. 2D 배열로 입력을받습니다.


3

파이썬 2, 84 바이트

lambda N,w,h:[N[i*w+s-i]for s in range(w+h+1)for i in range(h)[::s%2*2-1]if-1<s-i<w]

포팅 nimi의 답변 . 주어진 너비와 높이로 평면 배열을 취합니다. xsot가 바이트를 저장했습니다.


88 바이트 :

lambda M,w,h:[M[i]for i in sorted(range(w*h),key=lambda i:(i/w+i%w,-i*(-1)**(i/w+i%w)))]

주어진 너비와 높이로 평면 배열을 취합니다. (i/w,i%w)행 + 열이 홀수인지 짝수인지에 따라 행 값을 늘리거나 줄임으로써 대각선을 얻기 위해 지그재그 순서로 지그재그 순서로 해당 2D 좌표 를 정렬합니다 .


만약 상황이 더 단축 될 수 있다면.
xsot

@xsot 좋은 캐치.
xnor

3

하스켈, 79 78 73 바이트

(m#h)w=[m!!(y*w+x-y)|x<-[0..h+w],y<-g!!x$[0..x],y<h,x-y<w]
g=reverse:id:g

입력은 행과 열의 수를 나타내는 단순 목록입니다 (예 : ( [1,2,6,3,1,2,5,9,4,7,8,3] # 2) 6->) [1,2,5,9,6,3,4,7,1,2,8,3].

작동 방식 : 두 개의 중첩 루프에서 행렬의 x 및 y 좌표 ( h행, w열)를 살펴 봅니다.

  | 0 1 2 3 4 5 6 7 8    outer loop               Index is y*w+x-y, i.e.
--+------------------    x from 0 to h+w          the elements are accessed
0 | 1 2 6 3 1 2                                   in the following order:
1 | 5 9 4 7 8 3
2 |                                               1 2 4 6  8 10 
3 |                                               3 5 7 9 11 12
4 |
5 |
6 |
7 | inner loop:
8 | y from 0 to x

즉 위에서 오른쪽 / 아래로 / 바운드 인덱스 밖으로 건너 왼쪽으로 ( y그리고 x만족해야 y<h하고 x-y<w). 경우 x에도, 내부 루프의 순서가 역전된다 y에서 진행 x하는 0. [0..x]xth 요소 인 y- 범위에 대한 수정 함수를 선택하여이 작업을 수행합니다 [reverse,id,reverse,id,...].

편집 : @xnor는 루프를 다시 정렬하고 5 바이트를 저장했습니다. 감사!


당신이 할 수 있다고 생각합니다 g=id:reverse:g.
xnor

다음 (y-x)*w과 같은 문제를 바꿈으로써 멀티 양이온의 파렌 을자를 수 있습니다 (m#h)w=[m!!(x*w+y-x)|y<-[0..h+w],x<-g!!y$[0..y],x<h,y-x<w] g=reverse:id:g. 파이썬으로 번역하면 내가 가진 것보다 3 문자가 절약됩니다.
xnor

1

Python 2 + NumPy, 122 바이트

내가 인정할 께. 나는 앞서 일했다. 불행히도이 같은 방법은 다른 두 가지 관련 문제를 해결하기 위해 쉽게 수정할 수 없습니다 ...

import numpy
def f(m):w=len(m);print sum([list(m[::-1,:].diagonal(i)[::(i+w+1)%2*-2+1])for i in range(-w,w+len(m[0]))],[])

numpy 배열을 입력으로 사용합니다. 리스트를 출력합니다.

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

설명:

def f(m):
    w=len(m)    # the height of the matrix, (at one point I thought it was the width)
    # get the anti-diagonals of the matrix. Reverse them if odd by mapping odd to -1
    d=[list(m[::-1,:].diagonal(i)[::(i+w+1)%2*-2+1])for i in range(-w,w+len(m[0]))]
            # w+len(m[0]) accounts for the width of the matrix. Works if it's too large.
    print sum(d,[]) # join the lists

람다는 길이가 같습니다.

import numpy
lambda m:sum([list(m[::-1,:].diagonal(i)[::(i+len(m)+1)%2*-2+1])for i in range(-len(m),len(m)+len(m[0]))],[])

1

파이썬 3 131 118 115 107 바이트

Deusovi의 도전에 대한 나의 대답 과 동일한 원칙에 근거

입력 행렬에서 0을 가질 수 없다고 가정합니다.

e=enumerate
lambda s:[k for j,i in e(zip(*[([0]*n+i+[0]*len(s))for n,i in e(s)]))for k in i[::j%2*2-1]if k]

설명

작동 방식 :

            pad with 0      transpose    remove 0    reverse line           concatenate 
                                                     with even index
1 2 3       1 2 3 0 0        1 0 0        1            1                
4 5 6   --> 0 4 5 6 0    --> 2 4 0    --> 2 4     -->  2 4              -->  1 2 4 7 5 3 6 8 9
7 8 9       0 0 7 8 9        3 5 7        3 5 7        7 5 3             
                             0 6 8        6 8          6 8               
                             0 0 9        9            9

결과

>>> [print([i,f(i)]) for i in [[[1]], [[1, 2], [3, 1]], [[1, 2, 3, 1]], [[1, 2, 3], [5, 6, 4], [9, 7, 8], [1, 2, 3]], [[1, 2, 3, 4], [5, 6, 7, 8], [9, 1, 2, 3]], [[1, 2, 6, 3, 1, 2], [5, 9, 4, 7, 8, 3]], [[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]], [[1], [2], [5], [9], [6], [3], [4], [7], [1], [2], [8], [3]]]]
# [input,                                                          output]
[[[1]],                                                            [1]]
[[[1, 2], [3, 1]],                                                 [1, 2, 3, 1]]
[[[1, 2, 3, 1]],                                                   [1, 2, 3, 1]]
[[[1, 2, 3], [5, 6, 4], [9, 7, 8], [1, 2, 3]],                     [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 3, 4], [5, 6, 7, 8], [9, 1, 2, 3]],                       [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 6, 3, 1, 2], [5, 9, 4, 7, 8, 3]],                         [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]],                           [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]
[[[1], [2], [5], [9], [6], [3], [4], [7], [1], [2], [8], [3]],     [1, 2, 5, 9, 6, 3, 4, 7, 1, 2, 8, 3]]

해야 reverse even linereverse odd lines대신?
nwp

@nwp 지수는 0에서 시작 ^^
Erwan

아, 줄 길이가 아니라 줄 번호에 대해 이야기하고 있습니다. 죄송합니다.
nwp

@nwp np, btw 혼란을 피하기 위해 변경
Erwan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.