Emette la spirale verso l'interno in senso antiorario di un array 2D


15

Da questa domanda stackoverflow

Dato un array 2D di dimensioni , emette i valori in senso antiorario. L'output deve iniziare dall'esterno verso l'interno e il punto iniziale sarà sempre .M×N(0,0)

Esempio dato:

[12345678910111213141516]

I valori dei bordi in senso antiorario sono quindi .1,5,9,13,14,15,16,12,8,4,3,2

Ora ripetiamo il processo per i valori interiori. Questo finirà con una matrice come la seguente

[671011]

E i valori interni sono quindi6,10,11,7

Il risultato finale sarà quindi1,5,9,13,14,15,16,12,8,4,3,2,6,10,11,7


Regole

  • Assumi un input non vuoto
  • Assumi valori di matrice come numeri interi positivi
  • Si applicano i metodi I / O standard
  • Si applicano le regole standard del e i criteri di vincita

Alcuni casi di test

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

Quindi andiamo in senso orario o antiorario?
LegionMammal978,

@ LegionMammal978 in senso antiorario (pensavo fosse chiamato in senso antiorario)
Luis felipe De jesus Munoz,

7
Sia in senso antiorario che antiorario sono entrambi corretti, con ciascuno più comune in BrEng e AmEng, rispettivamente. Se vuoi davvero confondere, puoi usare anche widdershins .
Trauma digitale

Risposte:


12

R , 54 byte

Diversi byte salvati da @Giuseppe e @ J.Doe.

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

Provalo online!

Rimuovi in ​​modo ricorsivo la prima colonna e inverti / trasponi le righe (rendendo la riga inferiore la nuova prima colonna) il resto della matrice fino a finire con una sola colonna. Versione non tradizionale "tradizionale":

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

È stato sottolineato che si ncol(m)potrebbe giocare a golf per sum(m)salvare un altro byte perché ci è consentito assumere valori di matrice interi positivi. Ma lo lascerò così poiché funziona per tutte le matrici (anche le matrici di stringhe!)


Wow! Adoro come l'uso di t()impedisce al drop=TRUEdefault di `[`rovinare la ifcondizione!
Giuseppe,

e piena divulgazione, avevo una soluzione di circa 200 byte che non funzionava nemmeno, quindi complimenti a te! Probabilmente mi metterò in giro per assegnarti una taglia per questo una volta che la domanda è ammissibile per una taglia.
Giuseppe,

@Giuseppe torna a 59 byte! Sono stato piacevolmente sorpreso dal t()non dover usare un is.nulltest nei miei tentativi originali.
ngm

Quest'ultimo mnon sarà comunque nullo, quindi è possibile modificare l'istruzione if per 54 byte . Sembra funzionare per i casi di test.
J.Doe,


7

Pyth , 9 byte

shMM.utC_

Provalo qui!

Come?

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.

Questo è figo. Come principiante di Pyth ora so che ho molto da imparare,
ElPedro,

5

Stax , 7 byte

ôQÖG·í<

Esegui ed esegui il debug

Prende una matrice di righe su una riga e produce un output separato da newline.

Disimballato, non golfato e commentato, sembra così.

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

Esegui questo


4

Pyth, 20 byte

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

Provalo qui

Spiegazione

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.

4

OK , 12 byte

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

Provalo online!

Ciò abusa del fatto che oK non sembra preoccuparsi troppo della forma per la trasposizione. In k sarebbe 13 byte : *:',/(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

3

Pulito , 69 byte

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

@o?

Provalo online!

Sposta la riga / colonna successiva in testa all'elenco in modo che possa corrispondere al motivo nell'argomento.

Per il primo esempio della sfida, questo appare come:

@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] ++ @ []

3

Julia 0,7 , 47 byte

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

Provalo online!

Julia ha un comodo built-in per ruotare la matrice di 90 gradi eliminando la necessità di operazioni di trasposizione inversa.

Come puoi vedere dagli avvisi del compilatore, insiste sul fatto che tutti i componenti del condizionale ternario dovrebbero essere separati da spazi e in v. 1.0 questo è stato effettivamente applicato.

Stranamente, in questa situazione il modo più breve che ho trovato per uscire dalla ricorsione era usare un blocco try-catch:

Julia 1.0 , 50 byte

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

Provalo online!


2

JavaScript (Node.js) , 89 byte

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

Provalo online!

Prende la prima colonna, traspone quella rimanente, quindi inverte ogni riga (= ruota la matrice di 90 gradi CW), quindi ripete finché l'array non ha più voci.


2

APL (Dyalog) , 24 22 byte

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

Provalo online!

Come?

{×≢⍵:⍵[;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

Una spiegazione degli operatori sarebbe piacevole.
Arc676,

1
@ Arc676, aggiunto!
Zacharý,

2

05AB1E , 13 11 10 byte

ΔRøćRˆ}¯˜þ

-2 byte grazie a @Emigna .

Provalo online o verifica tutti i casi di test .

Spiegazione:

Δ         # 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)


1

Carbone , 25 byte

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

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione:

≔⮌EA⮌ιθ

Ruota l'ingresso di 180 °. Questo per due motivi: a) l'ultima riga è la più facile da rimuovere e b) è più facile eseguire il loop se la riga viene rimossa alla fine del loop. (Ho provato a riflettere e ad emettere in senso orario ma ciò ha richiesto un byte in più.)

Wθ«

Ripetere fino a quando l'array è vuoto.

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

Ruota l'array di 90 °.

I⊟θ

Rimuovere l'ultima riga dell'array e stampare l'elemento come stringhe su righe separate.



1

PowerShell , 266 byte

Sì. PowerShell non è il migliore per la gestione di matrici. Ma l'algoritmo è sostanzialmente lo stesso del precedente. Ogni riga è rappresentata come una stringa separata da virgola, e fondamentalmente facciamo una rotazione e trasposizione per ogni livello. Posso probabilmente la barba più fuori, ma ... io sono già in pigiama ...

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','}

Provalo online!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.