Subtrair a matriz dobrada


21

Desafio:

Dada uma matriz NxN em que N≥2 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 (a−1) ' th fileira (teria sido (a−2) '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 (a−2) ' ª linha (teria sido (a−3) 'ª 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]]

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


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

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)0≤d≤7NaN

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()

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.


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 =).


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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.