다차원 반전


23

음이 아닌 정수로 구성된 N 차원 직교 (비정규) 배열과 반전 할 차원 표시가 있으면 배열을 반환하지만 해당 차원을 따라 반전됩니다. 표시는 길이 N의 부울 목록 또는 0 또는 1에서 색인 된 첫 번째 N 차원의 서브 세트 목록으로 제공 될 수 있습니다.

입력 형식을 명시하십시오. 코드 설명은 대단히 감사합니다.

연습 예제

우리는 2 층 3 열 4 열 3D 배열을 제공받습니다.

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

 [[13,14,15,16],
  [17,18,19,20],
  [21,22,23,24]]]

그리고 중 하나

[true,false,true](부울리스트)
[0,2](0 인덱스리스트)
[1,3](1 인덱스리스트)

첫 번째 차원과 마지막 차원의 순서, 즉 행과 레이어 (행)의 요소 (각 레이어의 행은 아님)의 순서를 바꿔야합니다. 먼저 (실제 순서는 중요하지 않습니다) 레이어의 순서를 반대로 바꿉니다.

[[[13,14,15,16],
  [17,18,19,20],
  [21,22,23,24]],

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

그런 다음 각 행의 요소 순서를 반대로 바꿉니다.

[[[16,15,14,13],
  [20,19,18,17],
  [24,23,22,21]],

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

테스트 사례

[[[1,2,3,4],[5,6,7,8],[9,10,11,12]],[[13,14,15,16],[17,18,19,20],[21,22,23,24]]]
[true,false,true]/ [0,2]/ [1,3]
 ↓ 
[[[16,15,14,13],[20,19,18,17],[24,23,22,21]],[[4,3,2,1],[8,7,6,5],[12,11,10,9]]]


[[1,2,3],[4,5,6]]
[true,false]/ [0]/ [1]
 ↓
[[4,5,6],[1,2,3]]


[[1],[4]]
[true,false]/ [0]/ [1]
 ↓
[[4],[1]]


[[7]]
[true,true]/ [0,1]/ [1,2]
 ↓
[[7]]


[1,2,3,4,5,6,7]
[true]/ [0]/ [1]
 ↓
[7,6,5,4,3,2,1]


[]
[true]/ [0]/ [1]
 ↓
[]


[[],[]]
[false,false]/ []/ []
 ↓
[[],[]]


[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[true,false,true,true]/ [0,2,3]/ [1,3,4]
 ↓
[[[[4,6,2,6],[4,8,3,2]],[[5,9,7,2],[3,8,3,3]]],[[[6,2,9,5],[1,4,1,3]],[[3,9,7,9],[8,5,3,5]]]]


[[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]]
[false,true,false,false]/ [1]/ [2]
 ↓
[[[[5,3,5,8],[9,7,9,3]],[[3,1,4,1],[5,9,2,6]]],[[[3,3,8,3],[2,7,9,5]],[[2,3,8,4],[6,2,6,4]]]]


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


나는 정적으로 타이핑 된 언어에서 가장 어려운 부분은 관련된 타입의 시그니처를 골프로 칠 것입니다.
OUurous

@ Οurous이 언어는 일반적으로 임의의 배열 데이터를 어떻게 처리합니까?
Adám

1
"정상적인"사용에 대한 세 가지 경우가 있습니다 : 배열의 한 수준에 대해서만 걱정합니다 (예 : reverse임의의 배열에 대해서는 작동하지만 첫 번째 수준에만 관심), 제네릭 또는 재귀 클래스 (기능에 따라 유형 / 객체 클래스) 또는 OOP이지만 유사한 유스 케이스). 후자는 일반적으로 훨씬 더 장황합니다.
많은

메모리에 모든 것이 인접한 적절한 다차원 배열 대신 포인터에 대한 포인터 배열 (C 또는 asm)로 행렬을 저장할 수 있습니까 ? 임의의 목록 중첩을 가진 모든 일반적인 상위 수준 / 동적 유형 언어가 이미 항목을 행렬이 아닌 목록 목록으로 처리하고 있다고 확신하므로 괜찮습니다.
Peter Cordes

@PeterCordes 물론입니다.
Adám

답변:


8

APL (Dyalog) , 20 9 바이트

⊃{⌽[⍺]⍵}/

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

방법?

/ -축소-입력 (배열)에서 가장 오른쪽에있는 요소를 가져 와서 다음 왼쪽 요소가있는 함수를 왼쪽 인수로 적용

{⌽[⍺]⍵}- left argument( ) 치수 에서 반대로

-동봉 된 배열을 평평하게



8

자바 스크립트 (Node.js) , 58 55 53 45 bytes

@Shaggy 덕분에 8 바이트 절약

입력을로 가져옵니다 (indications)(array). 여기서 표시 는 부울 목록입니다.

f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a

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

댓글

f = (                // f is a function taking:
  [r,                //   r = next 'reverse' Boolean flag
      ...b]          //   b = array of remaining flags
) =>                 // and returning an anonymous function taking:
  a =>               //   a = array (or sub-array) to process, or atomic element
    1 / r ?          // if r is defined:
      a.sort(_ => r) //   reverse a if r = 1; leave it unchanged otherwise
      .map(f(b))     //   for each element in the resulting array: do a recursive call,
                     //   using f to generate a new callback function for the next flag
    :                // else:
      a              //   a must be an atomic element and is simply left unchanged

r대신에 사용 r||-1 하면 효과 가있는 것 같습니다 .
얽히고 설킨

시겠습니까 f=([r,...b])=>a=>1/r?a.sort(_=>r).map(f(b)):a일? 휴대 전화에서 제대로 테스트 할 수 없습니다.
얽히고 설킨

@Shaggy Nice! 나는 다소 이례적인 처리 흐름을 좋아한다.
Arnauld


5

젤리 , 8 바이트

”€ẋ”ṚpFv

0- 색인 차원 목록을 가져옵니다.

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

작동 원리

”€ẋ”ṚpFv  Main link. Left arg: D (dimensions, 0-based), Right arg: A (array)

”€ẋ       Repeat '€' d times, for each d in D.
   ”Ṛp    Perform Cartesian product of ['Ṛ'] and each string of '€'s, prepending a
          'Ṛ' to each string of '€'s.
      F   Flatten the result.
          If, e.g., D = [0,2,4], we build the string "ṚṚ€€Ṛ€€€€".
       v  Eval the resulting string, using A as left argument.

1
그건 정말 나쁘다. 아주 좋아요!
Adám

5

R , 80 78 77 바이트

[표시된 곳에서 반대로 된 시퀀스 목록을 만들어 R 추출기 에 대한 호출을 작성하십시오 . 실제로는 0이 포함되어 있으며 자동으로 무시됩니다. 는 drop=F차원의 R의 기본 낙하를 방지하기 위해 필요하다. revR이 배열을 채우는 방식 때문에 차원 반전 표시기를 호출 해야합니다 .

감사합니다-@Giuseppe

인라인 할당을 사용하는 -1

function(x,a,d=dim(x))do.call("[",c(list(x),Map(seq,r<-d*rev(a),d-r),drop=F))

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

동일한 길이로 동일한 결과를 얻는 유사 콘텐츠를 만든 @JayCe에 대한 훌륭한 언급 :

function(x,a,d=dim(x))array(x[t(t(expand.grid(Map(seq,r<-d*rev(a),d-r))))],d)

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


1
78 바이트 아주 좋은 답변!
주세페

1
매우 심오한 답변입니다. 그것을 완전히 이해하는 데 시간이 걸렸습니다. 나는 사용하지 않고 그것을 복제 시도 do.call- 그것은 83 바이트에서 이상이다, 여전히 참조 할 수 있도록 주석으로이 여기에 게시 : TIO
JayCe

실제로 @JayCe, 훌륭한 답변도 78 바이트
J.Doe

5

하스켈, 120 119 바이트

함수 f는 N 차원리스트와 bool리스트를 입력으로받습니다.

class F r where f::[Bool]->r->r
instance F Int where f=seq
instance F r=>F[r]where f(a:y)=last(id:[reverse|a]).map(f y)

1
주위에 괄호가 필요하지 않습니다 F r.
Ørjan Johansen 님이

1
테스트 케이스 및 OJ의 1 바이트 골프와의 TIO 링크 .
Khuldraeseth na'Barya

4

05AB1E , 23 11 10 바이트

'€s×'R«J.V

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

@ Mr.Xcoder 덕분에 -12 바이트 .

[0,2,3]첫 번째 입력 인 0으로 색인 된 참값 (예 :)으로 입력합니다.

설명:

'€s×           # Repeat "€" the indices amount of times
               #  i.e. [0,2,3] → ["","€€","€€€"]
    'R«        # Append each with "R"
               #  i.e. ["","€€","€€€"] → ["R","€€R","€€€R"]
        J      # Join them all together
               #  i.e. ["R","€€R","€€€R"] → R€€R€€€R
         .V    # Execute string as 05AB1E code

예를 들어, 색인 input-list가 [0,2,3]인 경우 다음 문자열을 작성합니다.

R€€R€€€R

어느 것 :

    €€€R    # Reverse the items in the most inner (4th level) lists
 €€R        # Reverse the most inner (3rd level) lists themselves
            # Do nothing with the inner (2nd level) lists 
R           # Reverse the entire outer (1st level) list

원래 23 바이트 답변 :

ćURvy„ RèJ…εÿ}}„ RXèJ.V

부울리스트 (예 :)로 입력하며 [1,0,1,1], 첫 번째 입력입니다.

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

설명:

ćU                 # Pop and save the first boolean in variable `X`
  R                # Reverse the remaining boolean-list
   v    }          # Loop `y` over each of them:
     Rè           #  Take the string "R ", and index the current boolean (0 or 1) in it
    J              #  Join it together with the string of the previous iteration
    …εÿ}           #  Surround it with "ε" and "}"
          RXè     # Index variable `X` also in "R "
              J    # Join it together with the rest
.V                 # Execute string as 05AB1E code

예를 들어 : 부울 입력 목록이 [1,0,1,1]인 경우 다음 문자열을 작성합니다.

εεεR}R} }R

어느 것 :

  εR}         # Reverse the items in the most inner (4th level) lists
 ε   R}       # Reverse the most inner (3rd level) lists themselves
ε       }     # Do nothing with the inner (2nd level) lists 
         R    # Reverse the entire outer (1st level) list

1
좋은 대답이지만 .. 음 .. 11 시가 효과가 있을까요?
Mr. Xcoder

@ Mr.Xcoder 감사합니다! 실제로 훨씬 더 쉽습니다. 그리고 앞에 붙이고 뒤집는 대신 각각을 추가하여 1 바이트 더 골프를 칠 수있었습니다.
Kevin Cruijssen

Mr.Xcoder @, BTW 않는 이유 'x*반복에 작업을 x사용하지 않고 배의 N 양의 sWAP을하지만, 함께 일을하지 않습니다 '€*.. 편집 : 만 기존에 ..하지만
케빈 Cruijssen

레거시 버전은 매우 버그가 있습니다 . 문자 리터럴로되어 있어도 여전히 연산자로 구문 분석 되었기 때문일 수 있습니다 . 정직하지 않다. *그럼에도 불구하고 새 버전에서는 같은 방식으로 동작하지 않습니다.
Mr. Xcoder

3

자바 스크립트 (Node.js) , 60 바이트

다른 (재귀) 접근 방식. Arnauld의 대답을 이길 수 없습니다 ... 아직 ....

입력을 다음과 같이 취합니다. array, boolean list

f=(a,r)=>r>[]?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a

f=(a,r)=>r>[]?(r[0]?a.reverse():a).map(c=>f(c,r.slice(1))):a

console.log(f([[[[3,1,4,1],[5,9,2,6]],[[5,3,5,8],[9,7,9,3]]],[[[2,3,8,4],[6,2,6,4]],[[3,3,8,3],[2,7,9,5]]]],[true,false,true,true]))


3

Pyth , 15 바이트

.v+jk.n*\_*L\ME

여기 사용해보십시오!

성가 시게, 빈 차원 목록 케이스를 처리하는 것은 오히려 사용하는 거라고 ... 2 바이트보다 덜 취하지 않는 ss대신에 jk.n있지만 : | 변환 될리스트가 원시 Pyth 구문으로 문자열로 제공 될 수 있다고 가정합니다. 테스트를 쉽게하기 위해 Pyth 구문 으로 변환기를 작성했습니다 . 불행히도 OP가이를 허용하지 않기로 선택한 경우 17 바이트는이를 "수정"합니다.

.v+jk.n*\_*L\ME\E

3

Japt , 15 14 바이트

Arnauld의 솔루션 에서 영감을 얻었습니다 .

표시를 1s 및 0s 의 부울 배열로 첫 번째 입력으로 사용합니다 .

Ê?Vn@ÎãßUÅX:V

시도 해봐


설명

                   :Implicit input of boolean array U=indications and multi-dimensional integer array V
Ê                  :Get the length of U
 ?                 :If truthy (i.e., >0)
  Vn               :  Sort V
    @ÎÃ            :   Function that gets the first element of U; 0 will leave the array untouched, 1 will reverse it.
       £           :  Map each X
        ß          :  Run the programme again with the following inputs
         UÅ        :   U with the first element removed
           X       :   X will serve as the new value of V
            :      :Else
             V     :  Just return V

3

클린 , 122112 바이트

import StdEnv
class$r::[Bool]->r->r
instance$r where$_=id
instance$[r]| $r where$[a:y]=if(a)reverse id o map($y)

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

Clean의 골퍼 타입 시스템을 사용하여 Damien의 Haskell 버전에 응답합니다. 두 언어 사이의 광범위한 유사성을 실제로 보여줍니다.

설명 :

import StdEnv                 // import basic stuff
class $ r :: [Bool] -> r -> r // $ takes a boolean list and returns a function on r to r
instance $ r                  // instance on all types, taken when no more specific instances exist
    where $ _ = id            // return the identity function for all arguments
instance $ [r] | $ r          // instance for lists of a type which has an instance itself
    where $ [a: y]
        = if(a) reverse id    // reverse if the head of the argument is true
            o map ($ y)       // composed with the map function acting on $ applied to the tail


1

( 정확 하지만 생각 합니다. 컴파일러 asm 출력은 예상 한 것 같습니다.이 데이터 구조를 작성하고 인쇄하는 테스트 하네스를 작성할 시간을 찾으면 업데이트합니다.)

GNU C ++ (휴대용) 148 바이트

#include<algorithm>
#include<cstdint>
struct m{intptr_t d,l,a[];void R(int*r){if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));}};

GNU C ++ (int = 포인터이며 비 공백 함수 UB에서 떨어짐) 120 바이트

#include<algorithm>
struct m{int d,l,a[],R(int*r){if(*r)std::reverse(a,a+l);for(int i=0;d&&i<l;((m*)a[i++])->R(r+1));}};

이것은 깊이 카운터, 길이, {integers 또는 pointer}의 배열입니다. 이 이진이 아닌 트리 ( depth==0) 의 맨 아래 레벨 intptr_t에서 배열은 정수 배열입니다. 높은 수준에서는에 struct m*저장됩니다 intptr_t. 순회가 캐스팅됩니다.

R()반전 함수는 인수가 선언 저장하기 때문에 멤버 함수이며, 많은 저장 p->암시 대 구조체 멤버를 참조하는 구문 this포인터.

유일한 GNU 확장은 C99에서 가변 확장 구조체를 만드는 C99 가변 배열 멤버 이며, C ++에서 GNU 확장으로 지원됩니다. *a별도로 할당 된 배열을 가리키는 멤버를 사용하여 이것을 일반 ISO C ++로 만들 수있었습니다. (실제로 다른 변경없이 바이트를 절약 할 수 있습니다). 나는 이것을 asm 버전의 모형 / 참조 구현으로 썼다.


짧은 버전은 대신 대신 반환으로 int선언합니다 . 이 두 비트의 해커는 관련이 없습니다. 이것은 단지 "적어도 하나의 구현에서 작동"버전입니다.R()intvoid

intgcc7 또는 이전 버전으로 컴파일하거나 최적화를 비활성화하지 않는 한 32 비트 대상 ( 포인터를 보유 할 수있는 대상 )에서 제대로 작동합니다. ( UB가 아니기 때문에 gcc8 -O3실행이 void함수 의 맨 아래에 도달 할 수 없다고 가정합니다 .) x86 gcc -m32 -O3은 버전 (다른 네임 스페이스)과 멤버가 아닌 함수 버전을 모두 포함 한 Godbolt와 같이 gcc7에서 잘 작동합니다 . .

언 골프

arg 함수는 0/0 int r[]이 아닌 정수로 구성된 배열로, 최 외곽 레벨부터 시작하여 지정된 깊이를 교환해야하는지 여부를 나타냅니다.

#include<algorithm>  // for std::reverse
#include<cstdint>    // for intptr_t.  GNU C defines __intptr_t, so we could use that...

struct m{
    __intptr_t d,l,a[];    // depth = 0 means values, >0 means pointers.
    // l = length
    //__intptr_t a[];  // flexible array member: array contiguous with the struct

    void R(int r[]) {
        if(*r)
            std::reverse(a, a+l);   // *r && std::reverse() doesn't work because it returns void.

        if(d) // recurse if this isn't the bottom depth
            for(int i=0 ; i<l ; i++)  // tree traversal
                ((m*)a[i])->R(r+1);   // with the rest of the depth list
    }

}; // struct m

우리가 재귀 할 때 우리는 통과 r+1하므로 현재 깊이를 확인하는 것은 항상 *r입니다.

이전 버전은 r변경되지 않은 채 전달 되어 확인되었습니다 r[d]. 유연한 배열 멤버를 사용 a[]하면 포인터가 아니기 때문에 일종의 마지막 레벨 인디케이터를 저장 해야했습니다. 간접 배열이없는 진정한 배열입니다. 그러나 intptr_t *a멤버 와 함께 , 나는 nullptr그것이 잎이 될 가치를 가질 수 없었습니다 . 왜냐하면 그것이 가치이기를 원하기 때문입니다.

트리 순회 전후에 현재 레벨을 되 돌리는 것은 중요하지 않습니다. 나는 그것을 수행하려고하지 않았다 .

나는 아니에요 확실히std::reverse내가 전화에서 작동 할 수 있습니다 특히 가치가 수동 루프 대 바이트 수입니다 R()정확히 한 번만 어딘가 루프 내부의 각 포인터. 하지만d!=0


우와, 인상적입니다.
Adám

@ Adám : 고마워요. 글을 쓴 후에도 놀라 울 정도로 자연스럽고 훌륭했습니다. x86 머신 코드에서 할 수있는 일이 궁금합니다. : P
Peter Cordes

1

Mathematica, 7 바이트

Reverse

기능. 첫 번째 인수로 중첩 된 목록을 제공하고 두 번째 인수로 반전 할 1 기반 레벨 / 차원 목록을 제공하십시오. 온라인으로 사용해보십시오!

마지막으로 Mathematica에 내장 된 또 다른 도전!


반대로 층 ? TIO 링크일까요?
Adám

@ Adám 즉, 뒤집을 차원 의 목록으로 , 일반적으로 Mathematica에서 레벨 이라고합니다 .
LegionMammal978
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.