Subtrair a matriz dobrada

21

Desafio:

Dada uma matriz NxN em que N2 e uma das oito 'opções de dobra' distintas, gera uma lista / matriz 2D com os valores subtraídos.

As oito opções de dobragem são: da esquerda para a direita; direita para esquerda; de cima para baixo; de baixo para cima; da esquerda para a direita; do topo à direita; da esquerda para a direita; direito ao pé direito.

Exemplos passo a passo:

Matriz de entrada:

[[ 1, 3, 5, 7],
 [ 0, 8, 6, 4],
 [ 1, 1, 1, 1],  (a'th row in the explanation below)
 [ 1,25, 0,75]]

Com a opção de dobrar de cima para baixo, produzimos o seguinte como resultado:

[[ 1,-7,-5,-3],
 [ 0,22,-5,68]]

Por quê? Dobramos de cima para baixo. Como as dimensões da matriz são uniformes, não temos uma camada intermediária para preservar como está. A a 'th fila [1, 1, 1, 1]serão subtraídos pelo (a1) ' th fileira (teria sido (a2) 'th linha para matrizes de dimensão ímpares); assim [1-0, 1-8, 1-6, 1-4]se torna [1, -7, -5, -3]. A (a+1) 'ª linha [1, 25, 0, 75]será subtraída pela (a2) ' ª linha (teria sido (a3) 'ª linha para matrizes de dimensões ímpares); então[1-1, 25-3, 0-5, 75-7]torna-se [0, 22, -5, 68].

Com a opção de dobrar de baixo para a direita para topleft (com a mesma matriz de entrada acima), produzimos o seguinte como resultado:

[[-74,  2,  1,  7],
 [  0,  7,  6],
 [-24,  1],
 [  1]]

Com as seguintes subtrações dobráveis:

[[1-75,  3-1,  5-4,    7],
 [ 0-0,  8-1,    6],
 [1-25,    1],
 [   1]]

Regras do desafio:

  • Você pode usar oito letras distintas [A-Za-z]ou números distintos no intervalo [99,99] para as opções de dobra. Os números [1..8] ou [0..7] são provavelmente as opções mais comuns, mas se você quiser usar números diferentes dentro do intervalo para alguns cálculos inteligentes, fique à vontade para fazê-lo. Indique quais opções de dobragem você usou em sua resposta.
  • A matriz de entrada sempre será uma matriz NxN quadrada, portanto você não precisa manipular nenhuma matriz NxM retangular. N também sempre será pelo menos 2, pois uma matriz vazia ou 1x1 não pode ser dobrada.
  • A entrada da matriz sempre conterá números não negativos no intervalo [0,999] (os números na saída estarão, portanto, no intervalo [999,999] ).
  • Com a dobra (anti) diagonal ou a dobra vertical / horizontal de dimensão ímpar, a 'camada' do meio permanecerá inalterada.
  • A E / S é flexível. Pode ser uma matriz / lista 2D de números inteiros; pode ser retornado ou impresso como uma string delimitada por espaço e nova linha; você pode modificar a matriz de entrada e substituir os números que devem desaparecer nullou um número fora do [-999, 999]intervalo para indicar que eles desapareceram; etc etc.

Regras gerais:

  • Isso é , então a resposta mais curta em bytes vence.
    Não permita que idiomas com código de golfe o desencorajem a postar respostas com idiomas que não sejam codegolf. Tente encontrar uma resposta o mais curta possível para 'qualquer' linguagem de programação.
  • As regras padrão se aplicam à sua resposta com as regras de E / S padrão , para que você possa usar STDIN / STDOUT, funções / método com os parâmetros adequados e programas completos do tipo retorno. Sua chamada.
  • As brechas padrão são proibidas.
  • Se possível, adicione um link com um teste para o seu código (ou seja, TIO ).
  • Além disso, é altamente recomendável adicionar uma explicação para sua resposta.

Casos de teste:

Matriz de entrada 1:

Input-matrix (for the following eight test cases):
[[ 1, 3, 5, 7],
 [ 0, 8, 6, 4],
 [ 1, 1, 1, 1],
 [ 1,25, 0,75]]

Input-folding option: left-to-right
Output: [[2,6],[-2,4],[0,0],[-25,74]]

Input-folding option: right-to-left
Output: [[-6,-2],[-4,2],[0,0],[-74,25]]

Input-folding option: top-to-bottom
Output: [[1,-7,-5,-3],[0,22,-5,68]]

Input-folding option: bottom-to-top
Output: [[0,-22,5,-68],[-1,7,5,3]]

Input-folding option: topleft-to-bottomright
Output: [[7],[6,-1],[1,-7,-2],[1,24,0,74]]

Input-folding option: topright-to-bottomleft
Output: [[1],[-3,8],[-4,-5,1],[-6,21,-1,75]]

Input-folding option: bottomleft-to-topright
Output: [[1,3,4,6],[8,5,-21],[1,1],[75]]

Input-folding option: bottomright-to-topleft
Output: [[-74,2,1,7],[0,7,6],[-24,1],[1]]

Matriz de entrada 2:

Input-matrix (for the following eight test cases):
[[17, 4, 3],
 [ 8, 1,11],
 [11, 9, 7]]

Input-folding option: left-to-right
Output: [[4,-14],[1,3],[9,-4]]

Input-folding option: right-to-left
Output: [[14,4],[-3,1],[4,9]]

Input-folding option: top-to-bottom
Output: [[8,1,11],[-6,5,4]]

Input-folding option: bottom-to-top
Output: [[6,-5,-4],[8,1,11]]

Input-folding option: topleft-to-bottomright
Output: [[3],[1,7],[11,1,-10]]

Input-folding option: topright-to-bottomleft
Output: [[17],[4,1],[8,-2,7]]

Input-folding option: bottomleft-to-topright
Output: [[17,-4,-8],[1,2],[7]]

Input-folding option: bottomright-to-topleft
Output: [[10,-7,3],[-1,1],[11]]
Kevin Cruijssen
fonte
A ordem das opções de dobra é importante?
Data expirada
Além disso, podemos apenas gerar a matriz 8xNxN de todas as dobras possíveis?
Data expirada
Esta amostra de teste não deve Opção de dobra de entrada: saída de baixo para cima: [[-1,7,5,3], [0, -22,5, -68]] deve ser invertido?
OrangeCherries 17/06
também para a matriz 2, 17-11 é 6, não 4?
OrangeCherries 17/06
@ExpiredData Conforme especificado nas regras, você pode usar qualquer letra A-Za-zou número inteiro no intervalo [-999,999], portanto, a ordem não importa. E desculpe, mas você deve produzir a dobra correta com base na entrada, portanto, a saída das oito não é permitida.
Kevin Cruijssen 17/06

Respostas:

5

Octave , 256 248 244 248 bytes

m=d=x=@(a,b=1)rot90(a,b)
y=@(a,b=2)flip(a,b)
z=@(a,b=1)tril(a+1e3,-1)+a-x(y(tril(a)))+b*diag(diag(a))
f=@(a,b){m=((a-y(a))(:,1:(d=size(a,2)/2))),-y(m),m=y(x((a=x(a))-y(a)))(d+1:end,:),y(m,1),-y(z(a,-1)),x(z(x(a,2)),2),z(a=x(a,3)),x(z(x(a,2)),2)}{b}

Experimente online!

-2 bytes (e um pouco de arrumação) graças a Luis Mendo

+2 bytes devido à correção para TB

Operações indexadas a 1 para valores de b de 1 a 8:

R-L
L-R
B-T
T-B
BR-TL
TR-BL
BL-TR
TL-BR

Isso me deu uma dor de cabeça, eu vou jogar golfe mais tarde

Dados expirados
fonte
Sugerir em rows(a)vez desize(a,2)
ceilingcat 15/10
5

Geléia ,  39  34 bytes

É possível haver ainda mais golfe combinando algumas das duas "funções".
... sim: -5 graças a NickKennedy!

ṃ“Z“Ṛ“U“ “ŒDṙL ZZṚ”ŒḄFḲj“ŒH_Ṛ}¥/”v

Experimente online!

Um link diádico que aceita um número inteiro (a instrução) e uma lista de listas de números (a matriz).

[99,99]

           Instruction  |  integer
------------------------+---------
         left-to-right  |     4
         right-to-left  |    14
         top-to-bottom  |     9
         bottom-to-top  |    39
topleft-to-bottomright  |    65
topright-to-bottomleft  |    15
bottomleft-to-topright  |    10
bottomright-to-topleft  |     0

Quão?

O link cria o código Jelly, que é então avaliado usando M como uma entrada ...

ṃ“Z“Ṛ“U“ “ŒDṙL ZZṚ”ŒḄFḲj“ŒH_Ṛ}¥/”v - Link: integer, I; matrix, M
 “Z“Ṛ“U“ “ŒDṙL ZZṚ”                - list of lists of characters = ["Z", "Ṛ", "U", " ", "ŒDṙL ZZṚ"]
ṃ                                  - base decompress (I) using those lists as the digits
                                   -  ...i.e. convert to base 5 and then convert the digits:
                                   -          [1,2,3,4,0] -> ["Z", "Ṛ", "U", " ", "ŒDṙL ZZṚ"]
                   ŒḄ              - bounce
                                   -  ...e.g. [a, b, c] -> [a, b, c, b, a]
                     F             - flatten to a list of characters
                      Ḳ            - split at spaces
                       j           - join with:
                        “ŒH_Ṛ}¥/”  -   list of characters = "ŒH_Ṛ}¥/"
                                 v - evaluate as Jelly code with an input of M

Cada uma das oito opções é:

left-to-right           (4): ŒH_Ṛ}¥/
right-to-left          (14): ṚŒH_Ṛ}¥/Ṛ
top-to-bottom           (9): ZŒH_Ṛ}¥/Z
bottom-to-top          (39): ZṚŒH_Ṛ}¥/ṚZ
topleft-to-bottomright (65): ṚUŒDṙLŒH_Ṛ}¥/ZZṚUṚ
topright-to-bottomleft (15): UŒDṙLŒH_Ṛ}¥/ZZṚU
bottomleft-to-topright (10): ṚŒDṙLŒH_Ṛ}¥/ZZṚṚ
bottomright-to-topleft  (0): ŒDṙLŒH_Ṛ}¥/ZZṚ

Cada um deles (exceto 0e 4) aplica uma transformação ao Muso de alguns de Z(transposição), (reverso) e U(reverso cada); então, uma das duas funções (veja abaixo), o inverso da transformação da instalação (se houver) implementada com o inverso do código.

As duas funções internas são:

ŒH_Ṛ}¥/ - Function A: Fold bottom-to-top: matrix, M
ŒH       - split M into two equal lists of rows (first half bigger by 1 if need be)
      / - reduce by:
     ¥  - last two links as a dyad:
    }   -  using the right argument (i.e. second half):
   Ṛ    -    reverse
  _     -  subtract

ŒDṙLŒH_Ṛ}¥/ZZṚ - Function B: Fold topright-to-bottomleft: matrix, M
ŒD             - diagonals of M
  ṙ            - rotate left by:
   L           -   length of M (puts them in order from bottom left most)
    ŒH_Ṛ}¥/    - same action as calling Function A on the diagonals
           Z   - transpose
            Z  - transpose
             Ṛ - reverse
Jonathan Allan
fonte
1
Ah, legal, eu queria saber se alguém faria uso das opções de entrada um tanto flexíveis! É legal ver como você usou os valores para uma conveniente conversão de base em código Jelly para avaliar a dobra desejada. :)
Kevin Cruijssen 18/06
Usando parte do código da minha resposta e reutilizando o código comum a ambos, aqui está um texto de 34 bytes: tio.run/##y0rNyan8///…
Nick Kennedy
Se tivéssemos números inteiros de 16 bits, poderia ser ainda mais curto
Nick Kennedy
Resposta não concorrente de 23 bytes usando números inteiros de 16 bits como parâmetro para selecionar qual dobra: tio.run/##y0rNyan8///…
Nick Kennedy
@NickKennedy - obrigado. Eu gosto da divisão e participe! Terei que voltar mais tarde para alterar completamente a descrição.
Jonathan Allan
3

JavaScript (ES6),  149 ... 133  128 bytes

(matrix)(d)0d7NaN

0=1=2=3=4=5=6=7=

m=>d=>m.map((r,y)=>r.map((v,x)=>v-=(w=m.length+~y)-(p=[x+x-y,y,x,q=w+y-x][d&3])&&[r[q],m[w][x],m[q][w],m[x][y]][d>3^p>w?d&3:m]))

Experimente online!

Comentado

m => d =>                   // m[] = matrix; d = direction
  m.map((r, y) =>           // for each row r[] at position y in m[]:
    r.map((v, x) =>         //   for each value v at position x in r[]:
      v -=                  //     subtract from v:
        (                   //       define w as:
          w = m.length + ~y //         the width of input matrix - y - 1
        ) - (               //       and compare it with
          p = [             //       p defined as:
            x + x - y,      //         2 * x - y for vertical folding
            y,              //         y for horizontal folding
            x,              //         x for diagonal folding
            q = w + y - x   //         q = w + y - x for anti-diagonal folding
          ][d & 3]          //       using d MOD 4
        ) &&                //       if p is equal to w, leave v unchanged
        [                   //       otherwise, subtract:
          r[q],             //         r[q] for vertical folding
          m[w][x],          //         m[w][x] for horizontal folding
          m[q][w],          //         m[q][w] for diagonal folding
          m[x][y]           //         m[x][y] for anti-diagonal folding
        ][                  //       provided that we're located in the target area:
          d > 3 ^           //         test p < w if d > 3 
          p > w ? d & 3     //         or p > w if d <= 3
                : m         //         and yield either d MOD 4 or m[]
        ]                   //       (when using m[], we subtract 'undefined' from v,
                            //       which sets it to NaN instead)
    )                       //   end of inner map()
  )                         // end of outer map()
Arnauld
fonte
3

Geléia , 71 34 bytes

ḃ2ŒḄ,UZṚŒDṙLƊŒH_Ṛ}¥/$ZZṚƊṚZ8ƭ$ị@¥ƒ

Experimente online!

Suíte de teste

Um programa completo. O argumento certo é a matriz. O argumento à esquerda é o tipo de dobra:

44 = L-R
40 = R-L
36 = T-B
32 = B-T
50 = TL-BR
34 = TR-BR
54 = BL-TR
38 = BR-TL

Reescrito para usar o binário bijetivo de 5 bits como entrada. Observe que o programa fornecido acima não funcionará repetidamente para várias dobras.

Nick Kennedy
fonte
1

Oitava , 482 bytes , 459 bytes

As entradas para decidir as direções de dobragem são:
1) da esquerda para a direita
2) de baixo para cima
3) da direita para a esquerda
4) de cima para baixo
5) tr para bl
6) br para tl
7) bl para tr
8) tl para br
Cada chamada gera apenas a dobra especificada, em vez de todas elas (o que provavelmente levaria menos bytes). O maior problema é que, neste caso, não consigo descobrir como colocar as dobras 1-4 e 5-8 no mesmo loop. Mas pelo menos a oitava tem matrizes bonitas.

    function[m]=f(n,o)
    k=length(n);m=NaN(k);if(o<5)
    if(mod(o,2)>0)n=n'end
    q=[0,0,k+1,k+1](o)
    for x=1:ceil(k/2)if(x*2>k)m(x,:)=n(x,:)else
    for a=1:k
    m(abs(q-x),a)=n(abs(q-x),a)-n(abs(q-(k+1-x)),a)end
    end
    end
    if(mod(o,2)>0)m=flipud(m')end
    else
    if(mod(o,2)>0)n=flip(n)end
    q=[0,0,k+1,k+1](o-4)
    for x=1:k
    for a=1:k+1-x
    if(a==k+1-x)m(x,a)=n(x,a)else
    m(abs(q-x),abs(q-a))=n(abs(q-x),abs(q-a))-n(abs(q-(k+1-a)),abs(q-(k+1-x)))end
    end
    end
    end
    if(mod(o,2)>0)m=flip(m)end
    end

Experimente online!

A supressão de saída custa bytes, então ignore tudo o que não é a instrução de retorno (ans =).

OrangeCherries
fonte
Quantos bytes você perdeu ao escrever "end"?
Data
você não tem que escrever final?
OrangeCherries
Você faz a menos que a reestruture para que não seja um monte de declarações if / else e de declarações
Data
uau, olhando para o seu código, há toneladas de coisas que eu nem sabia que você poderia fazer no matlab.
OrangeCherries 17/06
Eu não sei muito sobre oitava tbh provavelmente pode salvar 50-100 bytes com bastante facilidade
Data de
1

Carvão , 78 77 bytes

F⁴«UMηE⮌η§μλ¿⁼ιθUMηEκ⎇‹⊕⊗νLη⁻μ§⮌κν⎇›⊕⊗νLηωμ¿⁼ι﹪θ⁴UMηEκ⎇‹λν⁻짧ηνλ⎇›λνωμ»Eη⪫ι,

Experimente online! Link é a versão detalhada do código. Usa as seguintes opções de dobra:

0   top-to-bottom
1   left-to-right
2   bottom-to-top
3   right-to-left
4   bottomright-to-topleft
5   topright-to-bottomleft
6   topleft-to-bottomright
7   bottomleft-to-topright

Os valores dobrados são substituídos por cadeias vazias. Explicação:

F⁴«≔UMηE⮌η§μλ

Gire a matriz quatro vezes.

¿⁼ιθUMηEκ⎇‹⊕⊗νLη⁻μ§⮌κν⎇›⊕⊗νLηωμ

Dobre a matriz horizontalmente quando apropriado.

¿⁼ι﹪θ⁴UMηEκ⎇‹λν⁻짧ηνλ⎇›λνωμ

Dobre a matriz na diagonal quando apropriado.

»Eη⪫ι,

Saída da matriz, uma vez que é girada de volta à sua orientação original.

Neil
fonte