Eşsiz çarpma spirali


13

Bu, Calvin'in Hobileri'nin son çarpım tablosu meydan okumasından esinlenmiştir .

Bir tamsayıyı Ngirdi olarak alan ve bir N-N benzersiz çarpma spirali yazdırıp döndüren bir işlev veya program yazın . Kod (teorik olarak) 0 ile 1000 arasında N için çalışmalıdır (bunun çıktısını almak zor olabilir). Çıktı, aşağıdaki prosedürle üretilen tabloya eşdeğer olmalıdır:

  1. N-N-N çarpım tablosunu doldurun. Örneğin N = 3 için:

    1 2 3
    2 4 6
    3 6 9
    
  2. Ziyaret ettiğiniz sayılara dikkat ederek sol üst köşeden saat yönünde bir spiral izleyin. Daha önce ziyaret ettiğiniz bir numarayı ziyaret ettiğinizde, yerine 0 girin.

Birkaç örnek daha açık hale getirebilir:

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

Sayılar şu şekilde bulunur:

resim açıklamasını buraya girin

Herhangi bir makul çıktı biçimi kabul edilir, ancak bir N-N matrisi olmalıdır, sadece bir liste olamaz. N kolayca ayırt edilebilen 1 x N sütunları veya N 1 x satırları olduğu için aşağıdaki gibi biçimler kabul edilir:

[[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   

Bayt kazanmak için en kısa kod.


Küçük gözümle değiştirilmiş bir eratosten eleği gözetiyorum! Eminim burada bir yerde gördüğüm bir desen var.
Addison Crump

2
Neden n=0çarpım tablolarında sıfır olmadığı için bir çıktı olsun ? Ben n=1çıktı 1 anlayabiliyorum , ama neden sıfır içerir?
Tom Carpenter

@TomCarpenter, kötü bir karar olabilirdi, ama "N = 0?" Sorusu olacağını biliyordum, bu yüzden N = 0 -> 0 kuralını yaptım. Geriye dönüp bakıldığında, N> 0 olduğunu söylemek daha iyi olabilirdi, ama şimdi biraz çok geç korkuyorum = /
Stewie Griffin

2
@StewieGriffin Çıktının N-N-matrisi olması gerektiğini söylediniz, bu nedenle çıktı 0-0 matrisi n=0olmalı veya soru tutarsız olacaktır.
alephalpha

Yanıtlar:


3

J, 22 bayt

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

İçin 0'a 0 matrisi çıkarır n=0.


8

Mathematica 123 122 117 98 92 73 bayt

24 bayt sayesinde LegionMammal978 ve 19 tane daha alephalpha sayesinde kurtarıldı!


Şaşırtıcı bir şekilde, bu tabloda, herhangi bir tam sayının birden çok örneği n, tabloda kendisiyle aynı göreli sıralamaya sahip olacaktır! Bir sayının ilk görünümü, no sayının tabloda ilk göründüğü hücrede yatar (tabloya satır satır dolduğunda). Bu, yaklaşımın sarmal kısıtlamayı tamamen göz ardı edebileceği anlamına gelir, çünkü sonuç üzerinde bir etkisi yoktur. (Aşağıdaki açıklamaya bakın.)

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

Misal

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, 25, 0, 35, 0, 45, 50}, {0, 0, 0, 0, 0, 0, 42, 48, 54, 60}, {0, 0, 0, 0, 0, 0, 0, 49, 56, 63, 70}, {0, 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


açıklama

Herhangi bir basamağın konumlarının spiral sırasının, n, fonksiyon tarafından döndürülen sıra-col konumlarının sırası ile aynı olduğu gerçeğinden yararlanıyoruz Positions!

Her sayının ilk oluşumunun yeri (ister sarmal ister tablo pozisyonuna göre bir emir olsun), döndürülen ilk öğe olacaktır Position. Bu ilk oluşum hücresi olduğu gibi bırakılacak. Sayının kalan örnekleri 0 ile değiştirilir.

Durumunu inceleyerek bunun nasıl çalıştığına bakalım n==18. Fikir çarpım tablosuyla başlamaktır:

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

ve her bir sayının satır-sütun konumlarını bulun. Örneğin, 18 Satır 2, Sütun 9'da (ilk örnek) bulunur; Satır 3, Sütun 6; Sıra 6, Sütun 3; ve Satır 9, Sütun 2. Bunlar, ilgili spiral düzen pozisyonlarına sahiptir {44, 58, 68, 82}.

Position[t, 18]

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

Aşağıdaki tabloda gösterildiği gibi.

Tablo 2

18'in son 3 örneğinin 0 ile değiştirilmesi gerekir. (Kolayca tespit edilebilmeleri için büyük bir kalın mavi sıfır kullanacağız.)

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

Tablo 3


Yazmamanın bir nedeni var mı Function?
LegionMammal978

1
İç içe geçmiş saf işlevlerle ilgili sorun yaşıyordum, ancak bu yineleme bunu gerektirmiyor. Teşekkürler.
DavidC

Yeni satır hariç 117 bayt sayıyorum.
LegionMammal978


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

2

Python, 99 95 90 89 87 81 bayt

Golf kodu:

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

Ungolfed:

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

Çıktı:

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]

girdi byte tıraş için thanx @valuah
CSᵠ

2

MATLAB, 96 88 87 86 79 bayt

Bu, örnek çıktıları izleyen 79 bayt koddur (özellikle n = 0 için)

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

Bu 75 bayttır, sorunun çıkarımına göre boş bir dizi üretecek olan n = 0 dışında aynı davranışa sahiptir (N'den N dizisine = 0'dan 0'a = boş dizi).

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

Bu Octave ile de çalışır . Burada çevrimiçi deneyebilirsiniz . Kod zaten 'multspiral.m' adlı bir dosya olarak eklenmiştir. Oktav istemine yazın multspiralve enter tuşuna basın. Daha sonra tablonun boyutunu girmelisiniz (örn. 4). Daha sonra çıktı yazdırılır.


O nasıl çalışır?

İlk olarak bu, gerektiğinde bir giriş numarası alır (örn. 6, 4 vb.)

n=input('');

Sonra biz davaları ele alıyoruz n=0ve n=1- bunlar dizileri oluşturmak için kullandığım kurala uymayan iki kişilik oldukları için - özel muamele görüyorlar - aslında bu anlaşılmaz n=0durum olmasa bile 5 bayt daha kısa olabilir .

m=+(n>0);

Sonra tüm değerleri için n>2, matris doğru boyuta gelinceye kadar biraz döngü yapıyoruz.

for i=2:n;

Aslında nve n+1herkes için sadece üç basit fark vardır n>=2. Bunlar:

  1. Sayıları içeren diziye en sağda yeni bir sütun eklenir n(1:n). Bu aşağıdakilerle kolayca hesaplanır:

     a=i*(1:i);
    
  2. Bu yeni sütuna eklenecek tüm öğeler var olan matristen (sıfıra ayarlı) kaldırılmalıdır, çünkü her zaman yeni sütundan daha sonra spiralde gelirler. Bu, geçerli matristeki yeni sütundaki tüm öğeleri sıfır olacak şekilde ayarlamak için bir yuvalanmış döngü kullanılarak kaldırılır.

    for j=a;
        m(m==j)=0;
    end;
    
  3. En çok, yeni sütunda bulunanlar dışındaki her öğenin sıfır olacağı yeni bir satır alt kısmı vardır. Yeni sütun eklendiğinde, kasıtlı olarak oluşturulan sınır dışı endeksler nedeniyle 0 ile otomatik olarak doldurulur. MATLAB'ın güçlü özelliklerinden biri, herhangi bir özel işlem yapmadan dizileri büyütebilmesidir, bu nedenle yeni satırı ve sütunu basitçe ekleyebiliriz ile:

    m(1:i,i)=a;
    

Sonunda for döngüsünün sonuna sahibiz - ki bu bir kez ulaştığında, matris çıktımızı miçerir. Çıktı formatınızla esnek olduğunuz için matris, mnoktalı virgül olmadan yeni bir satır olarak gösteriliyor

end;
m

Örnek olarak, programı çalıştırırsak, 10 sayısını girin, aşağıdaki çıktıyı alırız:

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

1

Haskell, 103 99 bayt

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]]

Kullanım örneği: f 4-> [[1,2,3,4],[0,0,6,8],[0,0,9,12],[0,0,0,16]].

Ben sadece Data.Listslisteleri (gibi replace) ve yeniden ihracat Data.List, güzel fonksiyonları olan modülü keşfettim Data.List.Splitve Data.List.Extras.


1

Yakut, 67 63 61 bayt

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

63 bayt

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

67 bayt

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

Kullanımı:

->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]]
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.