Spiral penggandaan yang unik

13

Yang ini terinspirasi oleh tantangan tabel perkalian terbaru Calvin Hobbies .

Tulis fungsi atau program yang mengambil integer Nsebagai input dan mencetak atau mengembalikan spiral multiplikasi unik N-by-N. Kode harus (dalam teori) bekerja untuk N antara 0 dan 1000 (mengeluarkan ini bisa jadi sulit). Output harus setara dengan tabel yang dihasilkan oleh prosedur berikut:

  1. Isi tabel perkalian N-by-N. Misalnya untuk N = 3:

    1 2 3
    2 4 6
    3 6 9
    
  2. Ikuti spiral searah jarum jam dari sudut kiri atas, perhatikan angka yang Anda kunjungi. Ketika Anda mengunjungi nomor yang sudah Anda kunjungi, gantilah dengan 0.

Beberapa contoh mungkin membuatnya lebih jelas:

n = 0:
0

n = 1:
1

n = 2:       //   Spiral order:
1  2         //   1  2
0  4         //   4  3

n = 3:
1  2  3      //   1  2  3
0  4  6      //   8  9  4
0  0  9      //   7  6  5

n = 4:
1  2  3  4   //   1   2   3   4
0  0  6  8   //  12  13  14   5
0  0  9 12   //  11  16  15   6
0  0  0 16   //  10   9   8   7

n = 5:
1   2   3   4   5
0   0   6   8  10
0   0   9  12  15
0   0   0  16  20
0   0   0   0  25

n = 10:
1   2   3   4   5   6   7   8   9  10
0   0   0   0   0  12  14  16  18  20
0   0   0   0  15   0  21  24  27  30
0   0   0   0   0   0  28  32  36  40
0   0   0   0  25   0  35   0  45  50
0   0   0   0   0   0  42  48  54  60
0   0   0   0   0   0  49  56  63  70
0   0   0   0   0   0   0  64  72  80
0   0   0   0   0   0   0   0  81  90
0   0   0   0   0   0   0   0   0 100

Jumlahnya ditemukan seperti ini:

masukkan deskripsi gambar di sini

Setiap format output yang masuk akal diterima, tetapi harus berupa matriks N-by-N, tidak bisa hanya daftar. Format seperti yang di bawah ini diterima, karena ada N kolom 1-by-N yang mudah dibedakan, atau baris N-by-1:

[[1 2 3][0 4 6][0 0 9]]   <-- OK

[[1 0 0][2 4 0][3 6 9]]   <-- OK

ans =                     <-- OK
    1  2  3
    0  4  6
    0  0  9   

Kode terpendek dalam byte menang.

Stewie Griffin
sumber
Saya memata-matai saringan modifikasi dari eratosthenes dengan mata kecil saya! Saya cukup yakin ada pola yang dapat Anda gunakan di sini yang pernah saya lihat di suatu tempat.
Addison Crump
2
Mengapa ada output di n=0mana tidak ada nol dalam tabel perkalian. Saya bisa mengerti n=1akan menghasilkan 1, tetapi mengapa termasuk nol?
Tom Carpenter
@ TomCarpenter, itu mungkin keputusan yang buruk, tapi saya tahu akan ada "Bagaimana dengan N = 0?" - pertanyaan, jadi saya membuat aturan N = 0 -> 0. Dalam retrospeksi, mungkin lebih baik untuk mengatakan bahwa N> 0, tapi sudah agak terlambat sekarang saya takut = /
Stewie Griffin
2
@StewieGriffin Anda mengatakan bahwa output harus berupa matriks N-by-N, sehingga output n=0harus berupa matriks 0-by-0, atau pertanyaannya tidak konsisten.
alephalpha

Jawaban:

3

J, 22 byte

,~$[:(*~:)[:,1*/~@:+i.

Ini menghasilkan 0-by-0 matrix untuk n=0.

alephalpha
sumber
8

Mathematica 123 122 117 98 98 73 byte

Dengan 24 byte disimpan berkat LegionMammal978 dan 19 by alephalpha!


Anehnya, dalam tabel ini, beberapa contoh dari bilangan bulat mana pun nakan memiliki urutan relatif yang sama dalam spiral seperti yang mereka lakukan dalam tabel itu sendiri! Penampilan pertama suatu angka nterletak pada sel di mana angka itu muncul pertama kali dalam tabel (ketika seseorang mengisi baris demi baris tabel). Ini berarti bahwa pendekatan tersebut dapat mengabaikan kendala spiral sama sekali, karena tidak ada hubungannya dengan hasilnya. (Lihat penjelasan di bawah.)

ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&

Contoh

ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&[10]

{{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, {0, 0, 0, 0, 0, 12, 14, 16, 18, 20}, {0, 0, 0, 0, 15, 0, 21, 24, 27, 30}, {0, 0, 0, 0, 0, 0, 28, 32, 36, 40}, {0, 0, 0, 0, 0, 25, 0, 35, 0, 45, 50}, {0, 0, 0, 0, 0, 0, 42, 48, 54, 60}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 56, 63, 70}, {0, 0, 0, 0, 0, 0, 0, 64, 72, 80}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 81, 90}, { 0, 0, 0, 0, 0, 0, 0, 0, 0, 100}}


Grid[%]

tble


Penjelasan

Kami mengeksploitasi fakta bahwa urutan spiral dari posisi digit mana pun, n, sama dengan urutan posisi row-col yang dikembalikan oleh fungsi Positions,!

Lokasi kemunculan pertama setiap angka (apakah satu pesanan oleh spiral atau oleh posisi tabel) akan menjadi elemen pertama yang dikembalikan oleh Position. Sel yang muncul pertama kali akan dibiarkan apa adanya. Contoh jumlah yang tersisa diganti dengan 0.

Mari kita lihat bagaimana ini bekerja, memeriksa kasus n==18. Idenya adalah mulai dengan tabel perkalian:

(t = Table[k Range@#, {k, #}] &[10]) // Grid

dan cari posisi baris-col dari setiap nomor. Misalnya, 18 terletak di Baris 2, Kol 9 (contoh pertama); Baris 3, Kol 6; Baris 6, Kolom 3; dan Baris 9, Kol 2. Ini memiliki posisi urutan spiral masing-masing {44, 58, 68, 82}.

Position[t, 18]

{{2, 9}, {3, 6}, {6, 3}, {9, 2}}

seperti yang ditunjukkan tabel berikut.

Meja 2

3 contoh terakhir dari 18 harus diganti dengan 0. (Kami akan menggunakan nol biru tebal besar sehingga mudah dilihat.)

ReplacePart[%, {{3, 6}, {6, 3}, {9, 2}} -> Style[0, {Blue, Bold, 16}]]// Grid

table3

DavidC
sumber
Apakah ada alasan untuk tidak menulis Function?
LegionMammal978
1
Saya mengalami masalah dengan fungsi murni bersarang, tetapi iterasi ini tidak mengharuskan itu. Terima kasih.
DavidC
Saya menghitung 117 byte tidak termasuk baris baru.
LegionMammal978
Juga, beberapa golf lagi
LegionMammal978
Beberapa golf lagi:ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&
alephalpha
2

Python, 99 95 90 89 87 81 byte

Kode golf:

n=range(1,input()+1);m=[]
for x in n:l=[(x*y,0)[x*y in m]for y in n];m+=l;print l

Tidak Disatukan:

n=range(1,input()+1);
m=[]
for x in n:
  l=[(x*y,0)[x*y in m]for y in n];
  m+=l;
  print l

Keluaran:

10 
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
[0, 0, 0, 0, 0, 12, 14, 16, 18, 20]
[0, 0, 0, 0, 15, 0, 21, 24, 27, 30] 
[0, 0, 0, 0, 0, 0, 28, 32, 36, 40]
[0, 0, 0, 0, 25, 0, 35, 0, 45, 50] 
[0, 0, 0, 0, 0, 0, 42, 48, 54, 60]
[0, 0, 0, 0, 0, 0, 49, 56, 63, 70] 
[0, 0, 0, 0, 0, 0, 0, 64, 72, 80]
[0, 0, 0, 0, 0, 0, 0, 0, 81, 90] 
[0, 0, 0, 0, 0, 0, 0, 0, 0, 100]
CSᵠ
sumber
thanx @valuah untuk mencukur byte input
CSᵠ
2

MATLAB, 96 88 87 86 79 byte

Ini adalah kode 79 byte, yang mengikuti contoh output (untuk n = 0 khusus)

n=input('');m=+(n>0);for i=1:n;a=i*(1:i);for j=a;m(m==j)=0;end;m(1:i,i)=a;end;m

Yang ini adalah 75 byte, memiliki perilaku yang sama kecuali untuk n = 0 yang akan menghasilkan array kosong sesuai dengan implikasi dari pertanyaan (N oleh N array = 0 oleh 0 = array kosong).

n=input('');m=[];for i=1:n;a=i*(1:i);for j=a;m(m==j)=0;end;m(1:i,i)=a;end;m

Ini juga berfungsi dengan Oktaf . Anda dapat mencobanya online di sini . Kode sudah ditambahkan sebagai file bernama 'multspiral.m'. Jadi pada prompt Oktaf, ketik multspiraldan tekan enter. Anda kemudian harus memasukkan ukuran tabel (mis. 4). Output kemudian akan dicetak.


Bagaimana cara kerjanya?

Pertama-tama ini mengambil nomor input sesuai kebutuhan (misalnya 6, 4, dll.)

n=input('');

Kemudian kami menangani kasus untuk n=0dan n=1- ini diberi perlakuan khusus karena mereka adalah dua yang tidak mengikuti aturan yang saya gunakan untuk menghasilkan array - sebenarnya ini bisa menjadi 5 byte lebih pendek jika bukan untuk n=0kasus yang tidak jelas .

m=+(n>0);

Kemudian untuk semua nilai n>2, kita melakukan perulangan sampai matriks tumbuh ke ukuran yang benar.

for i=2:n;

Sebenarnya hanya ada tiga perbedaan sederhana antara ndan n+1untuk semua n>=2. Ini adalah:

  1. Kolom baru ditambahkan paling kanan di array yang berisi angka-angka n(1:n). Ini mudah dihitung dengan:

     a=i*(1:i);
    
  2. Setiap elemen yang akan ditambahkan dalam kolom baru harus dihapus dari matriks yang ada (set ke nol) karena mereka akan selalu datang kemudian di spiral daripada kolom baru. Ini dihapus menggunakan nestled for loop untuk mengatur semua elemen dalam matriks saat ini yang ada di kolom baru menjadi nol.

    for j=a;
        m(m==j)=0;
    end;
    
  3. Ada paling bawah baris baru di mana setiap elemen kecuali yang ada di kolom baru akan menjadi nol. Ketika kolom baru ditambahkan, karena indeks di luar batas yang telah sengaja dibuat diisi secara otomatis dengan 0. Salah satu fitur kuat MATLAB adalah dapat menumbuhkan array tanpa penanganan khusus, sehingga kita dapat menambahkan baris dan kolom baru dengan mudah dengan:

    m(1:i,i)=a;
    

Akhirnya kita memiliki akhir dari for loop - yang setelah tercapai, matriks mberisi output kita. Karena Anda fleksibel dengan format output Anda, matriks ditampilkan dengan hanya memiliki msebagai baris baru tanpa titik koma

end;
m

Sebagai contoh, jika kita menjalankan program, masukkan angka 10, kita mendapatkan output berikut:

m =
     1     2     3     4     5     6     7     8     9    10
     0     0     0     0     0    12    14    16    18    20
     0     0     0     0    15     0    21    24    27    30
     0     0     0     0     0     0    28    32    36    40
     0     0     0     0    25     0    35     0    45    50
     0     0     0     0     0     0    42    48    54    60
     0     0     0     0     0     0    49    56    63    70
     0     0     0     0     0     0     0    64    72    80
     0     0     0     0     0     0     0     0    81    90
     0     0     0     0     0     0     0     0     0   100
Tom Carpenter
sumber
1

Haskell, 103 99 byte

import Data.Lists
f 0=[[0]]
f n=chunksOf n$foldr(\c d->c:replace[c][0]d)[][a*b|a<-[1..n],b<-[1..n]]

Contoh penggunaan: f 4-> [[1,2,3,4],[0,0,6,8],[0,0,9,12],[0,0,0,16]].

Saya baru saja menemukan Data.Listsmodul yang memiliki fungsi bagus pada daftar (seperti replace) dan ekspor ulang Data.List, Data.List.Splitdan Data.List.Extras.

nimi
sumber
1

Ruby, 67 63 61 byte

->n{s,x=1..n,{};s.map{|c|s.map{|r|x[v=c*r]==1?0:(x[v]=1;v)}}}

63 byte

->n{s,x=1..n,{};s.map{|c|s.map{|r|e=x[v=c*r]==1?0:v;x[v]=1;e}}}

67 byte

->n{s,x=1..n,[];s.map{|c|s.map{|r|e=x.include?(v=c*r)?0:v;x<<v;e}}}

Pemakaian:

->n{s,x=1..n,{};s.map{|c|s.map{|r|x[v=c*r]==1?0:(x[v]=1;v)}}}[10]
=> [[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [0, 0, 0, 0, 0, 12, 14, 16, 18, 20], [0, 0, 0, 0, 15, 0, 21, 24, 27, 30], [0, 0, 0, 0, 0, 0, 28, 32, 36, 40], [0, 0, 0, 0, 25, 0, 35, 0, 45, 50], [0, 0, 0, 0, 0, 0, 42, 48, 54, 60], [0, 0, 0, 0, 0, 0, 49, 56, 63, 70], [0, 0, 0, 0, 0, 0, 0, 64, 72, 80], [0, 0, 0, 0, 0, 0, 0, 0, 81, 90], [0, 0, 0, 0, 0, 0, 0, 0, 0, 100]]
Vasu Adari
sumber