Die einzigartige Multiplikationsspirale

13

Dieser ist inspiriert von Calvins jüngster Herausforderung an der Multiplikationstabelle .

Schreiben Sie eine Funktion oder ein Programm, das eine ganze Zahl Nals Eingabe verwendet und eine N-mal-N-Multiplikationsspirale ausgibt oder zurückgibt. Der Code muss (theoretisch) für N zwischen 0 und 1000 funktionieren (dies auszugeben kann jedoch schwierig sein). Die Ausgabe sollte der nach dem folgenden Verfahren erstellten Tabelle entsprechen:

  1. Füllen Sie eine N-mal-N-Multiplikationstabelle aus. ZB für N = 3:

    1 2 3
    2 4 6
    3 6 9
    
  2. Folgen Sie einer Spirale im Uhrzeigersinn von der oberen linken Ecke und notieren Sie sich die Zahlen, die Sie besuchen. Wenn Sie eine Nummer besuchen, die Sie bereits besucht haben, ersetzen Sie sie durch 0.

Ein paar Beispiele könnten es klarer machen:

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

Die Zahlen sind wie folgt zu finden:

Bildbeschreibung hier eingeben

Jedes vernünftige Ausgabeformat wird akzeptiert, es muss jedoch eine N-mal-N-Matrix sein, es kann nicht nur eine Liste sein. Formate wie die folgenden werden akzeptiert, da es N leicht unterscheidbare 1-mal-N-Spalten oder N-mal-1-Zeilen gibt:

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

Kürzester Code in Bytes gewinnen.

Stewie Griffin
quelle
Ich sehe mit meinem kleinen Auge ein modifiziertes Sieb aus Eratosthenen! Ich bin mir ziemlich sicher, dass Sie hier ein Muster verwenden können, das ich irgendwo gesehen habe.
Addison Crump
2
Warum sollte es eine Ausgabe geben, für die n=0es in den Multiplikationstabellen keine Null gibt? Ich kann verstehen, n=1würde 1 ausgeben, aber warum Null einschließen?
Tom Carpenter
@TomCarpenter, es könnte eine schlechte Entscheidung gewesen sein, aber ich wusste, dass es eine "Was ist mit N = 0?" - Frage geben würde, also machte ich die N = 0 -> 0-Regel. Rückblickend wäre es vielleicht besser gewesen zu sagen, dass N> 0 ist, aber jetzt ist es leider etwas zu spät = /
Stewie Griffin
2
@StewieGriffin Sie sagten, dass die Ausgabe eine N-mal-N-Matrix sein muss, daher sollte die Ausgabe für n=0eine 0-mal-0-Matrix sein, da sonst die Frage inkonsistent wäre.
alephalpha

Antworten:

3

J, 22 Bytes

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

Es wird eine 0-mal-0-Matrix für ausgegeben n=0.

Alephalpha
quelle
8

Mathematica 123 122 117 98 92 73 Bytes

Mit 24 Bytes dank LegionMammal978 und weiteren 19 von alephalpha!


Überraschenderweise haben in dieser Tabelle mehrere Instanzen einer ganzen Zahl ndieselbe relative Reihenfolge in der Spirale wie in der Tabelle selbst! Das erste Auftreten einer Zahl nliegt genau in der Zelle, in der diese Zahl zuerst in der Tabelle erscheint (wenn man die Tabelle zeilenweise ausfüllt). Dies bedeutet, dass der Ansatz die Spiralbeschränkung insgesamt ignorieren kann, da er keinen Einfluss auf das Ergebnis hat. (Siehe Erklärung unten.)

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

Beispiel

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, 12, 14, 16, 18, 20}, {0, 0, 0, 0, 15, 0, 21, 24, 27, 30}, {0, 0, 0, 0, 0, 28, 32, 36, 40}, {0, 0, 0, 0, 25, 0, 35, 0, 45, 50}, {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}}


Grid[%]

tble


Erläuterung

Wir nutzen die Tatsache, dass die Spiralreihenfolge der Positionen einer beliebigen Ziffer n der Reihenfolge der von der Funktion zurückgegebenen Zeilen-Spalten-Positionen entspricht Positions,!

Der Ort des ersten Auftretens jeder Zahl (ob man nach der Spirale oder nach der Tabellenposition ordnet) ist das erste Element, das von zurückgegeben wird Position. Diese Zelle des ersten Vorkommens bleibt unverändert. Die verbleibenden Instanzen der Nummer werden durch 0 ersetzt.

Schauen wir uns an, wie das funktioniert, und untersuchen wir den Fall von n==18. Die Idee ist, mit der Multiplikationstabelle zu beginnen:

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

und suchen Sie die Zeilen-Spaltenpositionen jeder Nummer. Beispielsweise befindet sich 18 in Zeile 2, Spalte 9 (die erste Instanz); Zeile 3, Spalte 6; Zeile 6, Spalte 3; und Zeile 9, Spalte 2. Diese haben die jeweiligen spiralförmigen Ordnungspositionen {44, 58, 68, 82}.

Position[t, 18]

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

wie die folgende Tabelle zeigt.

Tabelle 2

Die letzten 3 Fälle von 18 müssen durch 0 ersetzt werden. (Wir verwenden große, fett gedruckte blaue Nullen, damit sie leicht erkannt werden können.)

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

Tisch 3

DavidC
quelle
Gibt es einen Grund, nicht zu schreiben Function?
LegionMammal978
1
Ich hatte Probleme mit verschachtelten reinen Funktionen, aber diese Iteration erfordert das nicht. Vielen Dank.
DavidC
Ich zähle 117 Bytes ohne die Newline.
LegionMammal978
Außerdem noch ein paar Golfplätze
LegionMammal978
Noch ein paar Golfplätze:ReplacePart[t=1##&~Array~{#,#},Join@@(Rest[t~Position~#]&/@Union@@t)->0]&
Alephalpha
2

Python, 99 95 90 89 87 81 Bytes

Golf Code:

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

Ausgabe:

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ᵠ
quelle
Danke @valuah für die Eingabe Byte Shave
CSᵠ
2

MATLAB, 96 88 87 86 79 Bytes

Dies ist der 79-Byte-Code, der den Beispielausgaben folgt (speziell für n = 0).

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

Dieser ist 75 Bytes, hat das gleiche Verhalten mit Ausnahme von n = 0, wodurch ein leeres Array gemäß der Implikation der Frage erzeugt wird (N mal N Array = 0 mal 0 = leeres Array).

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

Dies funktioniert auch mit Octave . Sie können es hier online ausprobieren . Der Code wurde bereits als Datei mit dem Namen "multspiral.m" hinzugefügt. Geben Sie an der Octave-Eingabeaufforderung Folgendes einmultspiral und drücken Sie die Eingabetaste. Sie sollten dann die Größe der Tabelle eingeben (z. B. 4). Die Ausgabe wird dann gedruckt.


Wie funktioniert es?

Erstens nimmt dies eine Eingabe-Nummer nach Bedarf (zB 6, 4, etc.)

n=input('');

Dann behandeln wir Fälle für n=0und n=1- diese werden speziell behandelt, da es sich um zwei Fälle handelt, die nicht der Regel entsprechen, die ich für die Generierung der Arrays verwende - in der Tat könnte dies 5 Byte kürzer sein, wenn nicht der obskure n=0Fall.

m=+(n>0);

Dann machen n>2wir für alle Werte von eine Schleife, bis die Matrix auf die richtige Größe angewachsen ist.

for i=2:n;

Es gibt eigentlich nur drei einfache Unterschiede zwischen nund n+1für allen>=2 . Diese sind:

  1. Eine neue Spalte wird ganz rechts in das Array eingefügt, das die Zahlen enthält n(1:n). Dies lässt sich leicht berechnen mit:

     a=i*(1:i);
    
  2. Alle Elemente, die in dieser neuen Spalte hinzugefügt werden, müssen aus der vorhandenen Matrix entfernt werden (auf Null gesetzt), da sie immer später in die Spirale kommen als die neue Spalte. Dies wird entfernt, indem eine eingebettete for-Schleife verwendet wird, um alle Elemente in der aktuellen Matrix, die sich in der neuen Spalte befinden, auf Null zu setzen.

    for j=a;
        m(m==j)=0;
    end;
    
  3. Es gibt eine neue unterste Zeile, für die jedes Element mit Ausnahme des Elements in der neuen Spalte Null ist. Wenn die neue Spalte hinzugefügt wird, werden die absichtlich erstellten Out-of-Bound-Indizes automatisch mit 0 aufgefüllt. Eine der Stärken von MATLAB ist, dass Arrays ohne spezielle Behandlung vergrößert werden können, sodass wir die neue Zeile und Spalte einfach hinzufügen können mit:

    m(1:i,i)=a;
    

Endlich haben wir das Ende der for-Schleife - die Matrix menthält unsere Ausgabe, sobald sie erreicht ist . Da Sie mit Ihrem Ausgabeformat flexibel sind, wird die Matrix einfach mals neue Zeile ohne Semikolon angezeigt

end;
m

Wenn wir beispielsweise das Programm ausführen und die Zahl 10 eingeben, erhalten wir die folgende Ausgabe:

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
quelle
1

Haskell, 103 99 Bytes

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

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

Ich habe gerade das Data.ListsModul entdeckt, das nette Funktionen für Listen (wie replace) und Reexporte hat Data.List, Data.List.Splitund Data.List.Extras.

nimi
quelle
1

Ruby, 67 63 61 Bytes

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

63 Bytes

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

67 Bytes

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

Verwendung:

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