Salida de la espiral interna antihoraria de una matriz 2D

15

De esta pregunta de stackoverflow

Dada una matriz 2D de tamaño M×N , genera los valores en sentido antihorario. La salida debe comenzar desde afuera hacia adentro y el punto inicial siempre será (0,0) .

Ejemplo dado:

[12345678910111213141516]

Los valores de borde en sentido antihorario son entonces 1,5,9,13,14,15,16,12,8,4,3,2 .

Ahora repetimos el proceso para los valores internos. Esto terminará con una matriz como la siguiente

[671011]

Y los valores internos son entonces 6,10,11,7

El resultado final será 1,5,9,13,14,15,16,12,8,4,3,2,6,10,11,7


Reglas

  • Asumir entrada no vacía
  • Asumir valores de matriz como enteros positivos
  • Se aplican los métodos estándar de E / S
  • Se aplican las reglas estándar de y los criterios ganadores

Algunos casos de prueba

Input
[
  [1, 2, 3, 4, 5, 6, 7],
  [8, 9, 10,11,12,13,14],
  [15,16,17,18,19,20,21]
]
Output
1,8,15,16,17,18,19,20,21,14,7,6,5,4,3,2,9,10,11,12,13

--------------------------------------------------------

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

-----------------------------------------------------
Input
[
    [1]
]
Output
1
-----------------------------------
Input
[
    [1, 2],
    [2, 1]
]
Output
1,2,1,2
-----------------------------------------------------
Input
[
    [1,2,3,6,7],
    [2,4,3,2,1],
    [3,2,4,5,6],
    [6,5,6,5,4],
    [10,4,7,8,9],
    [12,4,9,8,7]
]
Output
1,2,3,6,10,12,4,9,8,7,9,4,6,1,7,6,3,2,4,2,5,4,7,8,5,5,2,3,4,6
Luis felipe De jesus Munoz
fuente
Entonces, ¿vamos en sentido horario o antihorario?
LegionMammal978
@ LegionMammal978 en sentido antihorario (aunque pensé que se llamaba en sentido antihorario)
Luis felipe De jesus Munoz
77
Tanto en sentido antihorario como en sentido antihorario son correctos, y cada uno es más común en BrEng y AmEng, respectivamente. Si realmente quieres confundir, también puedes usar widdershins .
Trauma digital

Respuestas:

12

R , 54 bytes

Varios bytes guardados por @Giuseppe y @ J.Doe.

f=function(m)if(ncol(m))c(m[,1],f(t(m[nrow(m):1,-1])))

Pruébalo en línea!

Retire recursivamente la primera columna y revierta / transponga la fila (haciendo que la fila inferior sea la nueva primera columna) el resto de la matriz hasta que termine con una sola columna. Versión "tradicional" sin golf:

f <- function(m) {
 if(ncol(m) == 1) {
    m
  } else {
    c(m[,1], f(t(m[nrow(m):1,-1])))
  }
}

Se señaló que se ncol(m)podría aprovechar para sum(m)guardar otro byte porque se nos permite asumir valores de matriz enteros positivos. Pero lo dejaré así, ya que funciona para todas las matrices (¡incluso las matrices de cadenas!)

ngm
fuente
¡Guauu! ¡Me encanta cómo el uso de t()evita que el drop=TRUEvalor predeterminado `[`arruine la ifcondición!
Giuseppe
y divulgación completa, tenía una solución de 200 bytes que ni siquiera funcionaba, ¡así que felicitaciones! Probablemente llegue a otorgarle una recompensa por esto una vez que la pregunta sea elegible para una recompensa.
Giuseppe
@Giuseppe de vuelta a 59 bytes! Me sorprendió gratamente t()no tener que usar una is.nullprueba que estaba en mis intentos originales.
ngm
¿No mserá el último nulo de todos modos, por lo que puede cambiar la instrucción if por 54 bytes ? Parece funcionar para los casos de prueba.
J.Doe
7

Pyth , 9 bytes

shMM.utC_

Pruébalo aquí!

¿Cómo?

shMM.utC_     Full program. Takes a 2D array (matrix) from STDIN.
    .u        Until a result that has occurred before is found, loop and collect...
        _     Reverse the matrix (reverse the order of its rows).
       C      Transpose.
      t       Remove first element.
 hMM          For each element in the resulting 3D array, get the heads of its elements.
s             Flatten.
Sr. Xcoder
fuente
Eso es genial. Como principiante de Pyth, ahora sé que tengo mucho que aprender,
ElPedro
5

Stax , 7 bytes

ôQÖG·í<

Ejecutar y depurarlo

Toma una matriz de filas en una línea y produce una salida separada por una nueva línea.

Desempaquetado, sin golf y comentado, se ve así.

W       repeat the rest of the program until cancelled explicitly
  rM    rotate matrix *clock-wise* (yes, this is the opposite of the challenge)
  |c    assert matrix is truthy. (has rows) cancel otherwise.
  B     remove the top row of the matrix, and push separately to main stack
  rm    reverse the top row (this fixes the rotation direction), and print each value

Ejecute este

recursivo
fuente
4

Pyth, 20 bytes

J.TQWJ=+YhJ=J_.TtJ)Y

Pruébalo aquí

Explicación

J.TQWJ=+YhJ=J_.TtJ)Y
J.TQ                    Call the transposed input J.
    WJ            )     While J is not empty...
      =+YhJ             ... put the top row into Y (initially [])...
           =J   tJ      ... remove the top row...
             _.T        ... reverse and transpose (rotate clockwise).
                   Y    Output the result.

fuente
4

ok , 12 bytes

*+,/(1_+|:)\

Pruébalo en línea!

Esto abusa del hecho de que a oK no parece importarle demasiado la forma para la transposición. En k esto sería 13 bytes : *:',/(1_+|:)\.

       +|:   /reverse, then transpose (rotate right)
     1_      /remove first line
    (     )\ /fixpoint of the above, keeping intermediate results (scan)
  ,/         /concatenate all the rows
*+           /get the first element of each row
zgrep
fuente
3

Limpio , 69 bytes

import StdEnv,StdLib
? =transpose
@[h:t]=h++ @(reverse(?t))
@_=[]

@o?

Pruébalo en línea!

Mueve la siguiente fila / columna al encabezado de la lista para que pueda coincidir con el patrón en el argumento.

Para el primer ejemplo en el desafío, esto se ve así:

@o? [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
@ h=:[1, 5, 9, 13] t=:[[2, 6, 10, 14], [3, 7, 11, 15], [4, 8, 12, 16]]
[1, 5, 9, 13] ++ @ h=:[14, 15, 16] t=:[[10, 11, 12], [6, 7, 8], [2, 3, 4]]
[1, 6, 9, 13, 14, 15, 16] ++ @ h=:[12, 8, 4] t=:[[11, 7, 3], [10, 6, 2]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4] ++ @ h=:[3, 2] t=:[[7, 6], [11, 10]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2] ++ @ h=:[6, 10] t=:[[7, 11]]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10] ++ @ h=:[11, 7] t=:[]
[1, 6, 9, 13, 14, 15, 16, 12, 8, 4, 3, 2, 6, 10, 11, 7] ++ @ []
Οurous
fuente
3

Julia 0.7 , 47 bytes

f(m)=[m[:,1];sum(m)<1?[]:f(rotr90(m[:,2:end]))]

Pruébalo en línea!

Julia tiene un conveniente incorporado para rotar la matriz 90 grados, eliminando la necesidad de operaciones de transposición-reversa.

Como puede ver en las advertencias del compilador, insiste en que todos los componentes del condicional ternario deben estar separados por espacios, y en la versión 1.0 esto se ha aplicado realmente.

Curiosamente, en esta situación, la forma más corta que encontré para salir de la recursión fue usar un bloque try-catch:

Julia 1.0 , 50 bytes

f(m)=[m[:,1];try f(rotr90(m[:,2:end]))catch;[]end]

Pruébalo en línea!

Kirill L.
fuente
2

JavaScript (Node.js) , 89 bytes

f=a=>a>[]?[...a.map(x=>x[0]),...f(a[0].map((_,i)=>a.map(y=>y[i]).reverse()).slice(1))]:[]

Pruébalo en línea!

Toma la primera columna, transpone la restante y luego invierte cada fila (= gira la matriz 90 grados CW), y luego repite hasta que la matriz no tenga más entradas.

Shieru Asakoto
fuente
2

APL (Dyalog) , 24 22 bytes

{×≢⍵:⍵[;1],∇⍉⊖0 1↓⍵⋄⍬}

Pruébalo en línea!

¿Cómo?

{×≢⍵:⍵[;1],∇⍉⊖0 1↓⍵⋄⍬}
{                    } - a function
 ×≢⍵:                  - if non-empty:
     ⍵[;1]             - the left column
          ,∇⍉⊖0 1↓⍵    - repeat this function without the left column, rotated counter clockwise
                   ⋄⍬  - otherwise, return an empty vector
Zacharý
fuente
Una explicación de los operadores estaría bien.
Arc676
1
@ Arc676, añadido!
Zacharý
2

05AB1E , 13 11 10 bytes

ΔRøćRˆ}¯˜þ

-2 bytes gracias a @Emigna .

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

Δ         # Loop until the stack no longer changes:
 R        #  Reverse the order of the rows
          #   i.e. [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14,15,16]]
          #    → [[13,14,15,16],[9,10,11,12],[5,6,7,8],[1,2,3,4]]
  ø       #  Zip, swapping rows and column
          #   → [[13,9,5,1],[14,10,6,2],[15,11,7,3],[16,12,8,4]]
   ć      #  Head extracted
          #   → [[14,10,6,2],[15,11,7,3],[16,12,8,4]] and [13,9,5,1]
    R     #  Reverse this row
          #   → [1,5,9,13]
     ˆ    #  Pop and push it to the global array
}         # After the loop:
 ¯        #  Push the global array
          #   i.e. [[1,5,9,13],[14,15,16],[12,8,4],[3,2],[6,10],[11],[7],"",""]
  ˜       #  Flatten it
          #   → [1,5,9,13,14,15,16,12,8,4,3,2,6,10,11,7,"",""]
   þ      #  Remove all empty string by only leaving all digits
          #   → ["1","5","9","13","14","15","16","12","8","4","3","2","6","10","11","7"]
          # (and output it implicitly)
Kevin Cruijssen
fuente
1

Carbón de leña , 25 bytes

≔⮌EA⮌ιθWθ«≔E§θ⁰⮌Eθ§μλθI⊟θ

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

≔⮌EA⮌ιθ

Gire la entrada 180 °. Esto se debe a dos razones: a) la última fila es la más fácil de eliminar yb) es más fácil hacer un bucle si la fila se elimina al final del bucle. (Intenté reflexionar y mostrar en sentido horario, pero eso tomó un byte adicional).

Wθ«

Repita hasta que la matriz esté vacía.

≔E§θ⁰⮌Eθ§μλθ

Gire la matriz 90 °.

I⊟θ

Elimine la última fila de la matriz e imprima el elemento como cadenas en líneas separadas.

Neil
fuente
1

PowerShell , 266 bytes

Sí ... PowerShell no es el mejor para manejar matrices. Pero, el algoritmo es básicamente el mismo que el anterior. Cada fila se representa como una cadena separada por comas, y básicamente hacemos una rotación y transposición para cada capa. Es probable que pueda afeito más fuera, pero ... yo estoy ya en pijama ...

Filter F{$a=$_-replace"],|]|\s",''-split'\['|?{$_-ne''};$b=@();while($a-ne $null){$N=($a[0]-split',').Count-1;$a=0..$N|%{$i=$_;($a|%{($_-split',')[$i]})-join','};if($d){[array]::Reverse($a)}if($N-gt0){$b+=$a[0];$a=$a[1..$N]}else{$b+=$a;$a=$null};$d=$true}$b-join','}

Pruébalo en línea!

Jeff Freeman
fuente