Keluarkan spiral ke dalam anti-searah jarum jam dari array 2D

15

Dari pertanyaan stackoverflow ini

Diberikan array 2D ukuran M×N , menampilkan nilai-nilai dengan cara yang berlawanan arah jarum jam. Output harus mulai dari luar ke dalam dan titik awal selalu menjadi (0,0) .

Contoh Yang Diberikan:

[12345678910111213141516]

Nilai tepi dalam berlawanan arah jarum jam adalah 1,5,9,13,14,15,16,12,8,4,3,2 .

Sekarang kita ulangi proses untuk nilai-nilai batin. Ini akan berakhir dengan matriks seperti berikut

[671011]

Dan nilai-nilai batin adalah 6,10,11,7

Hasil akhirnya adalah 1,5,9,13,14,15,16,12,8,4,3,2,6,10,11,7


Aturan

  • Asumsikan input tidak kosong
  • Asumsikan nilai matriks sebagai bilangan bulat positif
  • Metode I / O Standar berlaku
  • Standar aturan dan kriteria pemenang berlaku

Beberapa test case

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
sumber
Jadi, apakah kita akan searah atau berlawanan arah jarum jam?
LegionMammal978
@ LegionMammal978 berlawanan arah jarum jam (saya pikir itu disebut berlawanan arah jarum jam)
Luis felipe De jesus Munoz
7
Anti dan berlawanan arah jarum jam keduanya benar, dengan masing-masing lebih umum di BrEng dan AmEng. Jika Anda benar-benar ingin bingung, Anda bisa menggunakan widdershins juga.
Trauma Digital

Jawaban:

12

R , 54 byte

Beberapa byte disimpan oleh @Giuseppe dan @ Joe.

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

Cobalah online!

Keluarkan kolom pertama secara rekursif dan baris-mundur / transpos (menjadikan baris bawah kolom pertama yang baru) sisa dari matriks sampai Anda berakhir hanya dengan satu kolom. Versi "tradisional" yang tidak disatukan:

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

Itu menunjukkan bahwa ncol(m)bisa golf sum(m)untuk menyimpan byte lain karena kita diizinkan untuk mengasumsikan nilai matriks integer positif. Tetapi saya akan membiarkannya seperti ini karena ini bekerja untuk semua matriks (bahkan matriks string!)

ngm
sumber
Wow! Saya suka bagaimana penggunaan t()mencegah drop=TRUEdefault `[`dari mengacaukan ifkondisi!
Giuseppe
dan pengungkapan penuh, saya punya sekitar 200 byte solusi yang bahkan tidak berfungsi, jadi kudos to ya! Saya mungkin akan berkeliling untuk memberi Anda hadiah untuk ini setelah pertanyaan memenuhi syarat untuk hadiah.
Giuseppe
@Giuseppe kembali ke 59 byte! Saya terkejut karena t()tidak harus menggunakan is.nulltes yang ada dalam upaya asli saya.
ngm
Bukankah yang terakhir makan menjadi nol, jadi Anda dapat mengubah pernyataan if untuk 54 byte . Tampaknya bekerja untuk kasus uji.
J.Otoh
9

Python 2 , 52 byte

f=lambda a:a and zip(*a)[0]+f(zip(*a[::-1])[1:])or()

Cobalah online!

TFeld
sumber
7

Pyth , 9 byte

shMM.utC_

Coba di sini!

Bagaimana?

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.
Tuan Xcoder
sumber
Itu keren. Sebagai pemula Pyth saya sekarang tahu saya harus banyak belajar,
ElPedro
5

Stax , 7 byte

ôQÖG·í<

Jalankan dan debug itu

Dibutuhkan array baris pada satu baris, dan menghasilkan keluaran yang dipisahkan baris baru.

Dibongkar, tidak diserang, dan dikomentari, sepertinya ini.

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

Jalankan yang ini

rekursif
sumber
4

Pyth, 20 byte

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

Coba di sini

Penjelasan

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.

sumber
4

OK , 12 byte

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

Cobalah online!

Ini menyalahgunakan fakta bahwa oK tampaknya tidak terlalu peduli dengan bentuk untuk transposisi. Dalam k ini akan menjadi 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
sumber
3

Bersih , 69 byte

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

@o?

Cobalah online!

Memindahkan baris / kolom berikutnya ke kepala daftar sehingga pola dapat cocok dengan argumen.

Untuk contoh pertama dalam tantangan, ini terlihat seperti:

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

Julia 0.7 , 47 byte

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

Cobalah online!

Julia memiliki built-in yang nyaman untuk memutar matriks dengan 90 derajat menghilangkan kebutuhan untuk operasi transpos-balik.

Seperti yang dapat Anda lihat dari peringatan kompiler, itu menegaskan bahwa semua komponen kondisional ternary harus dipisahkan oleh spasi, dan dalam v. 1.0 ini sebenarnya telah ditegakkan.

Anehnya, dalam situasi ini cara terpendek yang saya temukan untuk keluar dari rekursi adalah dengan menggunakan blok uji coba:

Julia 1.0 , 50 byte

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

Cobalah online!

Kirill L.
sumber
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))]:[]

Cobalah online!

Mengambil kolom pertama, transpos yang tersisa lalu balikkan setiap baris (= putar matriks 90 derajat CW), dan kemudian ulangi sampai array tidak memiliki entri lagi.

Shieru Asakoto
sumber
2

APL (Dyalog) , 24 22 byte

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

Cobalah online!

Bagaimana?

{×≢⍵:⍵[;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ý
sumber
Penjelasan operator akan menyenangkan.
Arc676
1
@ Arc676, ditambahkan!
Zacharý
2

05AB1E , 13 11 10 byte

ΔRøćRˆ}¯˜þ

-2 byte terima kasih @Emigna .

Cobalah secara online atau verifikasi semua kasus uji .

Penjelasan:

Δ         # 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
sumber
1

Jelly , 9 byte

ZḊUƊƬḢ€€Ẏ

Cobalah online!

Erik the Outgolfer
sumber
1

Arang , 25 byte

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

Cobalah online! Tautan adalah untuk mengucapkan versi kode. Penjelasan:

≔⮌EA⮌ιθ

Putar input sebesar 180 °. Ini karena dua alasan: a) baris terakhir adalah yang paling mudah untuk dihapus, dan b) lebih mudah untuk diulang jika baris dihapus di akhir loop. (Saya memang mencoba memantulkan dan mengeluarkan searah jarum jam tetapi itu membutuhkan byte tambahan.)

Wθ«

Ulangi sampai array kosong.

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

Putar array sebesar 90 °.

I⊟θ

Hapus baris terakhir dari array dan cetak elemen sebagai string pada baris terpisah.

Neil
sumber
1

Ruby , 65 byte

->a{x,*a=a.transpose;(w,*a=a.transpose.reverse;x+=w)while a[0];x}

Cobalah online!

GB
sumber
1

PowerShell , 266 byte

Ya .. PowerShell bukan yang terbaik untuk menangani matriks. Tapi, algoritme pada dasarnya sama dengan di atas .. Setiap baris direpresentasikan sebagai string yang dipisahkan koma, dan kami pada dasarnya melakukan rotasi dan transposisi untuk setiap lapisan. Saya mungkin bisa mencukur lebih off, tapi ... aku saya sudah di piyama ...

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

Cobalah online!

Jeff Freeman
sumber