Generieren Sie ein Summenraster

15

Erzeugen Sie ein Raster von 7 mal 7, das mit Zufallszahlen gefüllt ist. In Zellen mit einer ungeraden Zeilen- und Spaltennummer (beginnend bei 0) müssen Sie jedoch die Summe der umgebenden Zellen verwenden. Hier ist ein kleines Beispiel mit einem 3 x 3-Raster (Summenquadrat in Fettdruck):

2 2  2
2 16 2
2 2  2

Und hier ist ein Beispiel 7 mal 7 Raster:

6 5  4 3  7 2  5
6 43 3 50 8 43 8
4 7  8 8  9 3  1
4 36 1 43 6 40 5
3 3  6 1  4 7  5
4 35 3 45 9 42 1
2 6  8 6  8 5  3

Regeln

  • Zahlen, die keine Summen sind, müssen immer zwischen 1 und 9 liegen.

  • Das Gitter muss zufällig generiert werden. Für jede Nicht-Summe muss jede Ziffer die gleiche Chance haben, angezeigt zu werden, unabhängig davon, in welcher Zelle sie sich befindet.

  • Zahlen müssen ausgerichtet sein. Dies bedeutet, dass entweder die erste oder die letzte Ziffer jeder Zahl in einer Spalte vertikal ausgerichtet sein muss. (Sie können davon ausgehen, dass die mittleren Zahlen immer zweistellig sind.)

  • Die umgebenden Zellen enthalten Diagonalen. Daher wird jedes Summenquadrat von acht Zahlen umgeben, die Sie hinzufügen müssen.

  • Der kürzeste Code gewinnt, da dies .

Türknauf
quelle
3
Ist es hat die erste Ziffer der Linien bis sein? dh kann es der letzte sein?
Volatility
@Volatility Ich nehme an, dass Right Align funktionieren würde. bearbeitet
Türklinke
Was ist, wenn eine Sprache keinen Zufallszahlengenerator hat?
Heimdall

Antworten:

14

APL, 53 49 43 42 40 39 36

Ich habe es geschafft, Js ;.in APL zu replizieren , und Gareths Ansatz verwendet , um 13 Zeichen zu sparen.

{×5⌷⍵:5⌷⍵⋄+/⍵}¨3,⌿3,/×∘?∘9¨∘.∨⍨9⍴0 1

Probelauf:

      {×5⌷⍵:5⌷⍵⋄+/⍵}¨3,⌿3,/×∘?∘9¨∘.∨⍨9⍴0 1
9  9 6  1 7  5 6
7 55 5 39 9 54 9
9  8 2  1 8  1 9
2 43 8 41 6 42 5
7  3 4  4 8  3 2
2 29 1 26 2 35 8
6  4 2  3 2  3 7

Erläuterung:

  • ∘.∨⍨9⍴0 1 erzeugt eine Bitmaske.
  • ×∘?∘9¨ Multipliziert jedes Bit mit einem Zufallswert von 1 bis einschließlich 9 und erzeugt ein maskiertes Gitter von Zufallszahlen.
  • 3,⌿3,/verwendet, was nur als Hackery bezeichnet werden kann, um alle 3 mal 3 überlappenden Felder im maskierten Array zurückzugeben. Diese werden dabei auch abgeflacht.
  • {×5⌷⍵:5⌷⍵⋄+/⍵}¨iteriert über das Array und weist jedes Element zu . Für jede Iteration wird die fünfte benötigt (in der Mitte wird daran erinnert, dass die APL-Indizierung auf 1 basiert) und das Vorzeichen zurückgegeben. In diesem Fall entspricht dies dem Testen, ob die Zahl größer als 0 ist. Wenn dies 1 (für true) zurückgibt, geben Sie dieses Element zurück. Andernfalls geben Sie die Summe der Elemente im Feld Abgeflacht 3 mal 3 zurück. Es wird der :⋄ternäre Operator verwendet, der ?:in vielen Sprachen dem entspricht .
Flüchtigkeit
quelle
Oh, oh. Es sieht so aus, als müsste ich mehr Charakter sparen. : -S
Gareth
@Gareth na, schau was wir hier haben. Ich bin wieder an der Spitze: P
Volatility
NOOOOOOOOOO !!!!!!! :-(
Gareth
13

J, 63 61 59 55 52 51 49 47 39 37 Zeichen

3 3(4&{+4{*|+/)@,;._3(**1+?)+./~9$0 9

Vielen Dank an Volatility für seine 10-Zeichen-Speicherung.

Erklärung (jeder Schritt hat unterschiedliche Zufallszahlen ...):

Generieren Sie die Maske zur Generierung der Zufallszahlen (Verwendung $:

   9 9$9$0 9
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0
0 9 0 9 0 9 0 9 0

Jetzt haben wir einen Haken . Dies ist eigentlich ein glücklicher Zufall, als ich eine frühere Version runtergeschnitten habe. Es sollte transponiert |:und +.mit dem Original verbunden werden. Es hat Sinn gemacht, da ich zu der Zeit Einsen und Nullen verwendet habe, aber jetzt habe ich Neunen und Nullen. Es kommt einfach so vor, dass es genauso mit der GCD-Bedeutung von funktioniert +.. Glück für mich. :-)

   (+.|:)9 9$9$0 9
0 9 0 9 0 9 0 9 0
9 9 9 9 9 9 9 9 9
0 9 0 9 0 9 0 9 0
9 9 9 9 9 9 9 9 9
0 9 0 9 0 9 0 9 0
9 9 9 9 9 9 9 9 9
0 9 0 9 0 9 0 9 0
9 9 9 9 9 9 9 9 9
0 9 0 9 0 9 0 9 0

Nun, da wir ein Raster von 9s und 0s haben, wollen wir einige Zufallszahlen erzeugen. ?generiert eine Zufallszahl von 0 bis (aber ohne) eine bestimmte Zahl. Bei einer gegebenen Liste wird auf diese Weise eine Zufallszahl für jedes Mitglied der Liste erzeugt. In diesem Fall wird für jede 9 in der Tabelle eine Zahl von 0 bis 8 und für jede 0 eine Gleitkommazahl von 0 bis 1 generiert.

   ?(+.|:)9 9$9$0 9
 0.832573 7 0.926379 7 0.775468 6 0.535925 3  0.828123
        7 0        5 5        4 3        4 5         4
0.0944584 2 0.840913 2 0.990768 1 0.853054 3  0.881741
        3 8        7 0        8 3        3 4         8
 0.641563 4 0.699892 7 0.498026 1 0.438401 6  0.417791
        6 8        7 5        2 3        6 6         3
 0.753671 6 0.487016 4 0.886369 7 0.489956 5  0.902991
        3 4        7 8        1 4        8 0         8
0.0833539 4 0.311055 4 0.200411 6 0.247177 5 0.0464731

Aber wir wollen Zahlen von 1 bis 9, nicht 0 bis 8. Also addieren wir 1.

   (1+?)(+.|:)9 9$9$0 9
 1.4139 4  1.7547 7 1.67065 4 1.52987 1 1.96275
      2 8       2 4       3 9       6 9       9
1.15202 7 1.11341 5  1.0836 1 1.24713 2 1.13858
      9 3       3 2       4 7       3 8       6
1.06383 9 1.67909 4 1.09801 8  1.4805 6  1.0171
      9 5       5 5       9 5       9 4       3
1.22819 1 1.85259 4 1.95632 6 1.33034 3 1.39417
      4 2       5 1       3 7       2 5       6
1.06572 5  1.9942 5 1.78341 5 1.16516 6 1.37087

Das ist sehr schön, aber wir haben die Nullen verloren, die ich haben will, also multiplizieren wir sie mit der Originalmaske, nachdem wir alle Neunen zu Einsen gemacht haben. Ich überprüfe dazu, ob der Wert größer als 1 ist (1&<*1+?).
Es gibt ein paar Dinge, die hier vor sich gehen:

  • Wir haben eine Gabel geschaffen , mit der wir viel Arbeit in sehr wenige Charaktere packen können.
  • Wir haben &die 1 an das <Verb gebunden ( ) .

Alles zusammen (1&<*1+?)erzeugt Zufallszahlen und setzt alle Zahlen auf Null, die durch Nullen im ursprünglichen Gitter erzeugt wurden.

   (1&<*1+?)(+.|:)9 9$9$0 9
0 3 0 2 0 7 0 1 0
9 5 2 7 7 1 4 5 7
0 6 0 8 0 3 0 1 0
4 8 7 5 9 7 7 9 4
0 9 0 6 0 9 0 9 0
6 1 2 1 4 6 8 9 4
0 3 0 8 0 6 0 6 0
2 5 2 2 2 2 3 9 3
0 9 0 3 0 5 0 3 0

Das nächste bisschen ist das (meiner Meinung nach jedenfalls :-) clevere bisschen.
Das ;.Verb " Ausschneiden" hat eine Form, in x u;._3 yder die Eingabe in die mit "Beschrieben" gekennzeichneten Felder aufgeteilt wird xund das Verb dann uauf diese Felder angewendet wird . In diesem Fall haben wir 3 3(4&{++/*0=4&{)@,;._3.

  • Das 3 3beschreibt die Boxen, die wir wollen - 3x3.
  • Das (4&{++/*0=4&{)@,ist ein Verbzug, der beschreibt, was wir mit jeder Box machen wollen.

Um das ;.Verb zu demonstrieren, werde ich <jedes Kästchen zeigen:

   3 3(<);._3(1&<*1+?)(+.|:)9 9$9$0 9
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│0 8 0│8 0 7│0 7 0│7 0 4│0 4 0│4 0 3│0 3 0│
│9 1 3│1 3 2│3 2 3│2 3 8│3 8 5│8 5 5│5 5 9│
│0 6 0│6 0 1│0 1 0│1 0 2│0 2 0│2 0 4│0 4 0│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│9 1 3│1 3 2│3 2 3│2 3 8│3 8 5│8 5 5│5 5 9│
│0 6 0│6 0 1│0 1 0│1 0 2│0 2 0│2 0 4│0 4 0│
│7 1 6│1 6 7│6 7 1│7 1 2│1 2 1│2 1 6│1 6 1│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│0 6 0│6 0 1│0 1 0│1 0 2│0 2 0│2 0 4│0 4 0│
│7 1 6│1 6 7│6 7 1│7 1 2│1 2 1│2 1 6│1 6 1│
│0 7 0│7 0 5│0 5 0│5 0 9│0 9 0│9 0 7│0 7 0│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│7 1 6│1 6 7│6 7 1│7 1 2│1 2 1│2 1 6│1 6 1│
│0 7 0│7 0 5│0 5 0│5 0 9│0 9 0│9 0 7│0 7 0│
│7 9 9│9 9 7│9 7 1│7 1 9│1 9 4│9 4 9│4 9 5│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│0 7 0│7 0 5│0 5 0│5 0 9│0 9 0│9 0 7│0 7 0│
│7 9 9│9 9 7│9 7 1│7 1 9│1 9 4│9 4 9│4 9 5│
│0 3 0│3 0 2│0 2 0│2 0 7│0 7 0│7 0 9│0 9 0│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│7 9 9│9 9 7│9 7 1│7 1 9│1 9 4│9 4 9│4 9 5│
│0 3 0│3 0 2│0 2 0│2 0 7│0 7 0│7 0 9│0 9 0│
│3 1 6│1 6 1│6 1 7│1 7 6│7 6 8│6 8 9│8 9 9│
├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
│0 3 0│3 0 2│0 2 0│2 0 7│0 7 0│7 0 9│0 9 0│
│3 1 6│1 6 1│6 1 7│1 7 6│7 6 8│6 8 9│8 9 9│
│0 9 0│9 0 3│0 3 0│3 0 4│0 4 0│4 0 3│0 3 0│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

Einige Dinge zu beachten:

  • Die Felder überlappen sich - die zweite und dritte Spalte im oberen linken Feld sind die erste und zweite Spalte im Feld rechts davon.
  • Es gibt 7x7 Boxen. Aus diesem Grund hatten wir anfangs ein 9x9-Raster.
  • Jede Stelle, für die wir eine Summe benötigen, hat ein 0in der Mitte der Box.

Jetzt müssen wir nur noch den Wert in der Mitte zurückgeben (wenn er nicht Null ist) oder die Zahlen im 3x3-Feld summieren (wenn die Mitte Null ist).
Dazu benötigen wir einen einfachen Zugang zur Centernummer. ,hilft hier. Es stellt sich die 3x3 - Gitter in eine Liste von 9 Teilen mit der Center - Nummer an der Nummer 4
4&{wird benutzt {den Mittelwert zu ziehen und dann vergleichen Sie es mit 0: 0=4&{. Dies gibt ein 0oder 1für wahr oder falsch zurück, die wir dann mit der Summe multiplizieren +/. Wenn es in der Mitte Null war, haben wir jetzt unsere Summe wie erforderlich. Wenn es nicht Null ist, addieren wir zum Schluss einfach den Mittelwert 4&{+.
Dies gibt das Verb train(4&{++/*0=4&{)@,

   3 3(4&{++/*0=4&{)@,;._3(1&<*1+?)(+.|:)9 9$9$0 9
2  6 9  3 7  9 7
3 47 6 51 5 49 5
3  9 9  6 6  2 8
7 48 6 47 1 37 5
5  4 5  7 7  2 6
5 35 3 49 8 51 9
1  6 6  6 7  4 8
Gareth
quelle
Tut Ihre einzige Codezeile all das, einschließlich der Generierung der Zufallszahlen? Versichere mir. Ich finde es einfach schwer zu glauben.
DavidC
Ja, schwer zu glauben. Das zufällige Bit wird vom ?. Ich werde die Erklärung ändern, um die neueste Version wiederzugeben.
Gareth
@DavidCarraher Die meisten Verben in J bestehen entweder aus 1 oder 2 Zeichen, sodass 47 Zeichen eine Menge Arbeit bedeuten können.
Gareth
Das Schneiden einer 9x9-Box in 7x7 überlappende Quadrate ist definitiv das Schlaue. In weniger als 10 Minuten konnte ich es anwenden, um meine aktuelle GolfScript-Implementierung um 7,5% zu übertreffen.
Peter Taylor
Na ja, es sieht so aus, als wäre es für mich wieder das Zeichenbrett.
Volatility
5

Ruby (135 Zeichen)

a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.each_slice(7){|r|puts"%-3s"*7%r}

Beispielausgabe

2  1  6  9  4  5  1  
9  34 4  37 2  31 3  
7  2  3  1  8  1  7  
5  42 4  40 2  47 9  
3  9  9  4  9  4  7  
3  44 4  41 2  47 4  
6  9  1  5  7  6  8  

Nervenzusammenbruch

Es ist nicht ganz klar, wie das funktioniert. Hier ist eine kurze Übersicht. HINWEIS: Möglicherweise können Sie einige dieser Schritte überspringen und schneller zu kürzeren Versionen wechseln, aber ich denke, es ist lehrreich genug, um zu sehen, wie ich Zeichen abgeschabt habe, insbesondere, indem Muster in Literalen erkannt werden, um zweistellige Zahlen in einstellige Versionen umzuwandeln .

Naive Version

Im Gegensatz zu den anderen Ruby-Lösungen , die auf einem zweidimensionalen Array basieren, können Sie (möglicherweise) eine kürzere Version erhalten, indem Sie mit einem eindimensionalen Array beginnen und mit Versatzwerten arbeiten, da sich die Muster wiederholen.

ary=(0..48).map { rand(9) + 1 }

offsets = [-8,-7,-6,-1,1,6,7,8]

3.times do |i|
  [8,10,12].each do |j|
    ary[j + 14*i] = ary.values_at(*offsets.map { |e| j+14*i + e }).inject(:+)
  end
end

ary.each.with_index do |e,i|
  $> << ("%-3s" % e)
  $> << ?\n if i % 7==6
end

Das Schlüsselprinzip hierbei ist, dass wir an den Indexpositionen 8, 10, 12 arbeiten, die nur um ein Vielfaches von 14 versetzt sind. Die Positionen 8, 10 und 12 sind die Zentren der 3x3-Gitter, die wir summieren. In der Beispielausgabe ist 34 Position 8, 42 Position 8 + 14 * 1 usw. Wir ersetzen Position 8 durch 34 durch Positionen, die von Position 8 versetzt sind, mit [-8,-7,-6,-1,1,6,7,8]anderen Worten - 34 = sum(ary[8-8], ary[8-7], ..., ary[8+8]). Dasselbe Prinzip gilt für alle Werte von [8 + 14*i, 10 + 14*i, 12 + 14*i], da sich das Muster wiederholt.

Es optimieren

Zunächst einige schnelle Optimierungen:

  • Anstelle der "Inline" -Positionen 3.times { ... }wird j + 14*ijedes Mal eine Berechnung durchgeführt [8,10,12,22,24,26,36,38,40].
  • Das offsetsArray wird einmal verwendet. Ersetzen Sie daher die Variable durch das Literal.
  • Ersetzen Sie do ... endmit {...}und schalten Sie den Druck auf um $> << foo. (Es gibt hier einen Trick mit puts nilund () == nil.)
  • Kürzere Variablennamen.

Der Code danach ist 177 Zeichen:

a=(0..48).map{rand(9)+1}
[8,10,12,22,24,26,36,38,40].each{|j|a[j]=a.values_at(*[-8,-7,-6,-1,1,6,7,8].map{|e|j+e}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

Beachten Sie für die nächste Reduzierung, dass injectdas Offsets-Array nicht in Ordnung sein muss. Wir können entweder eine [-8,-7,-6,-1,1,6,7,8]oder eine andere Reihenfolge haben, da die Addition kommutativ ist.

Kombinieren Sie also zuerst die positiven und negativen Punkte, um sie zu erhalten [1,-1,6,-6,7,-7,8,-8].

Jetzt können Sie kürzen

[1,-1,6,-6,7,-7,8,-8].map { |e| j+e }.inject(:+)

zu

[1,6,7,8].flat_map { |e| [j+e, j-e] }

Das führt zu

a=(0..48).map{rand(9)+1}
[8,10,12,22,24,26,36,38,40].each{|j|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

Das sind 176 Zeichen.

Verschieben Sie um 8 und bewegen Sie sich zu Differenzen

Die zweistelligen Literalwerte scheinen verkürzt zu werden. Nehmen Sie also [8,10,12,22,24,26,36,38,40]alles auf und verschieben Sie es nach unten 8, jum es am Anfang der Schleife zu aktualisieren . (Beachten Sie, dass Sie +=8die Offsetwerte von nicht aktualisieren müssen 1,6,7,8.)

a=(0..48).map{rand(9)+1}
[0,2,4,14,16,18,28,30,32].each{|j|j+=8;a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

Das ist 179, das ist größer, aber das j+=8kann tatsächlich entfernt werden.

Erste Änderung

[0,2,4,14,16,18,28,30,32]

zu einer Reihe von Unterschieden:

[2,2,10,2,2,10,2,2]

und addiere diese Werte kumulativ zu einer Initiale j=8. Dies wird schließlich die gleichen Werte abdecken. (Wir könnten wahrscheinlich direkt dorthin springen, anstatt zuerst um 8 zu verschieben.)

Beachten Sie, dass wir auch einen Dummy-Wert von 9999am Ende des Differenzen-Arrays und jam Ende , nicht am Anfang der Schleife , hinzufügen . Die Rechtfertigung ist, dass es furchtbar ähnlich 2,2,10,2,2,10,2,2aussieht, als wären es die gleichen 3 Zahlen, die dreimal wiederholt werden. Wenn Sie j+differenceam Ende der Schleife rechnen, hat der Endwert von 9999keinen Einfluss auf die Ausgabe, da es keinen a[j]Aufruf gibt, bei dem jein bestimmter Wert vorliegt vorbei 10000.

a=(0..48).map{rand(9)+1}
j=8
[2,2,10,2,2,10,2,2,9999].each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

Mit diesem Unterschiedsarray j+=8ist das jetzt j=8natürlich gerade, da wir sonst immer wieder 8zu viele hinzufügen würden . Wir haben auch die Blockvariable von jnach geändert l.

Da das 9999Element keine Auswirkung auf die Ausgabe hat, können wir es ändern 10und das Array verkürzen.

a=(0..48).map{rand(9)+1}
j=8
([2,2,10]*3).each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

Dies sind 170 Zeichen.

Aber jetzt j=8sieht das ein bisschen klobig aus, und Sie können 2 Zeichen speichern, indem Sie um 2 nach [2,2,10]unten verschieben , um ein Zeichen zu erhalten, das 8Sie für die Zuweisung verwenden können. Das muss auch j+=lwerden j+=l+2.

a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+);j+=l+2}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

Dies ist 169 Zeichen. Eine runde Sache, um 7 Charaktere zusammenzudrücken, aber es ist ordentlich.

Letzte Verbesserungen

Der values_atAnruf ist eigentlich redundant und wir können einen Array#[]Anruf einleiten. So

a.values_at(*[1,6,7,8].flat_map{|e|[j+e,j-e]}).inject(:+)

wird

[1,6,7,8].flat_map{|e|[a[j+e],a[j-e]]}.inject(:+)

Sie können auch erkennen , dass flat_map+ j+e/j-e+ injectkann mit einem anfänglichen zu einer direkteren Summe reduziert wird 0in der Anordnung.

So bleiben Ihnen 152 Zeichen:

a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.map.with_index{|e,i|$><<"%-3s"%e<<(?\nif i%7==6)}

Schließlich:

  • map.with_indexwerden kann each_slice.
  • Ändern Sie die Druckmethode.

135 :

a=(0..48).map{rand(9)+1}
([0,0,j=8]*3).each{|l|a[j]=[0,1,6,7,8].inject{|s,e|s+a[j+e]+a[j-e]};j+=l+2}
a.each_slice(7){|r|puts"%-3s"*7%r}
Adam Prescott
quelle
Sie können ersetzen eachmit mapfür ein Byte.
Jordanien
3

Python, 132

Dies entspricht technisch nicht den Regeln, da die letzten Ziffern der einzelnen Nummern anstelle der ersten ausgerichtet sind. Aber ich dachte, ich würde trotzdem teilen:

import numpy
G=numpy.random.randint(1,10,(7,7))
G[1::2,1::2]=sum(G[i:6+i:2,j:6+j:2]for i in[0,1,2]for j in[0,1,2]if i&j!=1)
print G

Beispielausgabe:

[[ 8  9  8  3  8  5  8]
 [ 6 53  4 45  8 53  8]
 [ 8  2  8  1  5  3  8]
 [ 2 40  6 34  1 32  7]
 [ 4  1  9  1  3  3  2]
 [ 4 35  7 35  6 31  1]
 [ 1  7  2  5  2  8  6]]
jakevdp
quelle
3

Mathematica, 108

s=#-1;;#+1&;g=1+8~RandomInteger~{7,7};Column/@
ReplacePart[g,{i_?EvenQ,j_?EvenQ}:>g〚s@i,s@j〛~Total~2-g〚i,j〛]

Ergebnis

Für eine schönere Ausgabe Column/@kann mit TableForm@einem Preis von 2 Zeichen ersetzt werden.

ssch
quelle
Sehr, sehr schlau. Grid[ReplacePart[ g, {i_?EvenQ, j_?EvenQ} :> g[[s@i, s@j]]~Total~2 - g[[i, j]]]\[Transpose]]Gibt eine sauberere Ausgabe und speichert ein paar Zeichen, wenn Sie Transponieren als ein einzelnes Zeichen zählen, was in Mathmatica der Fall ist. Die OneLinerSubmission-Vorlage von Wolfram zählte übrigens 106 Zeichen, davon 105 für die Transponierung mit einem Zeichen.
DavidC
@ DavidCarraher Vielen Dank. Die Zeichenanzahl ist auf unnötige Zeilenumbrüche zurückzuführen und :>ein einziges Symbol, obwohl es sich im Bereich für den privaten Gebrauch von Unicode befindet. Man könnte sogar die Transponierung entfernen, da die Gültigkeitssummierungsregel auch nach der Transposition gilt. Aber es scheint Gridnicht die Einträge ohne weitere Optionen auszurichten (v8)
ssch
Gridzentriert die Zahlen in Spalten. Technisch gesehen würde dies die Herausforderung nicht erfüllen, aber es sieht besser aus, als wenn eine Liste in der angezeigten Tabelle angezeigt wird.
DavidC
Sehr schön. Ich verbringe viel Zeit damit, dasselbe zu erschaffen, nur ich habe Partund verwendet Tuples. Posting bald.
Mr.Wizard
Sie könnten zwei Zeichen mit diesem speichern:p=2|4|6;Column/@ReplacePart[g,{i:p,j:p}:>g[[s@i,s@j]]~Total~2-g[[i,j]]]
Mr.Wizard
3

GolfScript ( 79 78 72 70 68 66 65 60 Zeichen)

56,{13%5<,~9rand)}%9/`{>3<zip`{>3<(*(+(\{+}*or' '}+7,%n}+7,/

NB Dies enthält eine wörtliche Registerkarte, die Markdown möglicherweise beschädigt.

Das Schlaue ist Gareth zu verdanken: Sehen Sie sich seine J-Lösung an.

Online-Demo

Peter Taylor
quelle
3

R: 114 Zeichen

a=array(sample(1:9,49,r=T),c(7,7))
for(i in 2*1:3){for(j in 2*1:3)a[i,j]=sum(a[(i-1):(i+1),(j-1):(j+1)])-a[i,j]}
a

In der ersten Zeile wird ein 7 x 7-Array erstellt, das mit zufällig ausgewählten Zahlen von 1 bis 9 gefüllt ist (gleichmäßige Verteilung mit Ersetzung, daher r=Tsteht das für replace=TRUE). In der zweiten Zeile werden die Summen von 3 mal 3 Gittern berechnet, das Zentrum subtrahiert und durch das Ergebnis ersetzt. In der dritten Zeile wird das resultierende Raster gedruckt (Matrix- und Arrayspalten sind standardmäßig rechtsbündig).

Beispielausgabe:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7]
[1,]    8    5    6    4    3    2    2
[2,]    1   37    6   41    7   38    8
[3,]    5    3    3    3    9    4    3
[4,]    4   31    3   41    3   44    9
[5,]    3    5    5    9    6    7    3
[6,]    3   32    2   40    4   37    5
[7,]    8    2    4    1    9    1    2
Plannapus
quelle
2

J, 67 65 Bytes

Eine naive und ausführliche Lösung in J. Es ist eine unkomplizierte Umsetzung der Aufgabe.

(+/^:_"2((,&.>/@(<:,],>:)"0)&.>m){0 m}a)(m=.{;~1 3 5)}a=.>:?7 7$9

Zuerst erstelle ich ein 7 x 7-Array mit ganzen Zahlen zwischen 1 und 9. In der Tat ist J? verb erzeugt Zahlen bis zu seinem Argument, deshalb müssen wir jedes Element inkrementieren,>: in J

a=.>:?7 7$9 
2 8 7 4 4 5 1
4 5 4 1 6 7 9
3 8 3 6 5 3 3
6 8 6 3 7 7 1
7 7 4 4 5 9 9
2 3 6 5 2 2 9
2 2 6 8 8 1 3

Ich bereite eine Maske vor, die zum Nullsetzen der ungeraden Zeilen / Spalten-Zellen verwendet werden soll, ein Paar ungerader Zeilen / Spalten-Indizes:

m=.{;~1 3 5
┌───┬───┬───┐
│1 1│1 3│1 5│
├───┼───┼───┤
│3 1│3 3│3 5│
├───┼───┼───┤
│5 1│5 3│5 5│
└───┴───┴───┘

Das Katalogverb {kombiniert Elemente aus den Atomen in der Boxliste

┌─────┬─────┐
│1 3 5│1 3 5│
└─────┴─────┘

um einen Katalog zu bilden, die 3x3-Tabelle der obigen Paare

Dann bereite ich eine Tabelle mit Zeilen- / Spaltenindizes vor, die für die Auswahl jedes der 3x3-Subarrays verwendet werden.

s=.(,&.>/@(<:,],>:)"0)&.>m
┌─────────────┬─────────────┬─────────────┐
│┌─────┬─────┐│┌─────┬─────┐│┌─────┬─────┐│
││0 1 2│0 1 2│││0 1 2│2 3 4│││0 1 2│4 5 6││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
├─────────────┼─────────────┼─────────────┤
│┌─────┬─────┐│┌─────┬─────┐│┌─────┬─────┐│
││2 3 4│0 1 2│││2 3 4│2 3 4│││2 3 4│4 5 6││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
├─────────────┼─────────────┼─────────────┤
│┌─────┬─────┐│┌─────┬─────┐│┌─────┬─────┐│
││4 5 6│0 1 2│││4 5 6│2 3 4│││4 5 6│4 5 6││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
└─────────────┴─────────────┴─────────────┘

Für jedes Paar im m-Array erstelle ich ein Paar Drillinge, die um jede Zahl des m-Paares zentriert sind:

        ┌─────┬─────┐
 1 3 -> │0 1 2│2 3 4│
        └─────┴─────┘

Diese Triplettpaare werden vom J From-Verb {verwendet, das mehrere Zeilen und Spalten gleichzeitig auswählen kann. 0 1 2/2 3 4 bedeutet, dass ich die Zeilen 0, 1 und 2 zusammen mit den Spalten 2, 3 und 4 auswähle und so das zweite 3x3-Subarray oben auswähle.

Schließlich kann ich das 7x7-Array und die Masken verwenden, um die Aufgabe zu erfüllen: Zuerst verwende ich m als Maske, um die entsprechenden Elemente auf 0 zu setzen:

0 m}a

Dann nehme ich alle 3x3-Subarrays mit s als Selektor und finde ihre Summen:

+/^:_"2 s{0 m}a

Dann habe ich diese Zahlen wieder in das Startfeld eingefügt.

 (+/^:_"2 s{0 m}a)m}a 
2 8 7 4 4 5 1
4 39 4 39 6 36 9
3 8 3 6 5 3 3
6 44 6 40 7 42 1
7 7 4 4 5 9 9
2 36 6 43 2 46 9
2 2 6 8 8 1 3

Probieren Sie es online!

Galen Ivanov
quelle
1

Rubin, 207

Ich werde zuerst meine Lösung vorstellen (wie immer):

a=Array.new(7){Array.new(7){rand(9)+1}}
s=[-1,0,1]
s=s.product s
s.slice!4
r=[1,3,5]
r.product(r).map{|x|u=0
s.map{|y|u+=a[x[0]+y[0]][x[1]+y[1]]}
a[x[0]][x[1]]=u}
puts a.map{|x|x.map{|y|y.to_s.ljust 3}.join
Türknauf
quelle
1

Ruby, 150 Zeichen

v=(a=0..6).map{a.map{rand(9)+1}}
(o=[1,3,5]).map{|i|o.map{|j|v[i][j]=0
(d=[0,-1,1]).map{|r|d.map{|c|v[i][j]+=v[i+r][j+c]}}}}
puts v.map{|r|"%-3d"*7%r}

Wenn die Rechtfertigung für die Linksbegründung eine Rechtfertigung für die Linksbegründung ist, ljustmüsste diese verwendet werden ... nun, nein. Ich liebe Rubys Formatierungsmöglichkeiten.

Nicht verwenden Array.new(7){...}. (0..6).map{...}ist sowohl kürzer als auch lesbarer und Sie erhalten einen zuweisbaren Bereich kostenlos.

Linie 3 inspiriert von der Doorknob-Lösung .

John Dvorak
quelle
1

GolfScript, 87 Zeichen

49,{.1&\7/1&!|9rand)*}%.7/{[..1>@0\+]zip{{+}*}%);}:^%zip{^~}%]zip{.0=!=}%{'  '+3<}%7/n*

Da sind zu viele Reißverschlüsse drin ... (siehe online )

3  9  9  3  3  9  8  
6  46 2  50 3  39 8  
7  3  7  2  4  7  3  
8  33 9  51 8  49 5  
4  3  9  9  3  9  2  
1  45 9  41 6  33 2  
4  3  6  1  6  1  4  
Howard
quelle
1

J, 58/64/67 Zeichen

0j_1":(7$0,:7$0 1){"0 1 |:>v;v-~7 7{.0,.0,3+/\"1]3+/\v=.1+?7 7$9

Während die Angabe erfordert, dass die Zahlen linksbündig ausgerichtet sind, muss die Dezimalnotation nicht verwendet werden. Ich denke, dies ist eine gültige Ausgabe:

1.0e0 8.0e0 9.0e0 6.0e0 2.0e0 9.0e0 6.0e0
6.0e0 3.9e1 8.0e0 4.0e1 2.0e0 3.8e1 4.0e0
1.0e0 4.0e0 2.0e0 8.0e0 3.0e0 9.0e0 3.0e0
2.0e0 2.4e1 5.0e0 4.1e1 9.0e0 4.7e1 8.0e0
1.0e0 3.0e0 6.0e0 5.0e0 3.0e0 5.0e0 7.0e0
4.0e0 3.0e1 1.0e0 2.3e1 1.0e0 3.1e1 1.0e0
6.0e0 5.0e0 4.0e0 2.0e0 1.0e0 5.0e0 8.0e0

Wenn die Ausrichtung nach rechts anstelle der Ausrichtung nach links akzeptabel ist, haben wir 58 Zeichen

(7$0,:7$0 1){"0 1 |:>v;v-~7 7{.0,.0,3+/\"1]3+/\v=.1+?7 7$9

J's ":(Format) hat drei Formatierungsmodi:

  • rechtsbündig mit n Ziffern oder mit Schrumpffolie (Standardanzeige)
  • linksbündige wissenschaftliche Notation mit n Ziffern und insgesamt m Zeichen
  • Shrinkwrap Boxed Display mit (links / Mitte / rechts) - (oben / Mitte / unten) Ausrichtung (unten, 69 Zeichen)

Das ausführlichste, aber auch vielseitigste und einzige, das die Ausgabe gemäß dem Beispiel erzeugen kann, ist das 8!:2Formatierungs-Foreign, für das ein Formatierungs-String als linkes Argument verwendet wird. Auch 67 Zeichen :

'l3.'8!:2(7$0,:7$0 1){"0 1 |:>v;v-~7 7{.0,.0,3+/\"1]3+/\v=.1+?7 7$9

Hier ist das Box-Format:

 0 0":<"0(7$0,:7$0 1){"0 1 |:>v;v-~7 7{.0,.0,3+/\"1]3+/\v=.1+?7 7$9

 ┌─┬──┬─┬──┬─┬──┬─┐
 │2│6 │5│7 │5│7 │6│
 ├─┼──┼─┼──┼─┼──┼─┤
 │8│40│4│35│9│49│6│
 ├─┼──┼─┼──┼─┼──┼─┤ 
 │6│7 │2│2 │1│9 │6│
 ├─┼──┼─┼──┼─┼──┼─┤
 │8│41│9│35│3│45│7│
 ├─┼──┼─┼──┼─┼──┼─┤
 │3│1 │5│6 │7│8 │4│
 ├─┼──┼─┼──┼─┼──┼─┤
 │7│37│4│45│6│48│8│
 ├─┼──┼─┼──┼─┼──┼─┤
 │8│4 │5│4 │8│1 │6│
 └─┴──┴─┴──┴─┴──┴─┘
John Dvorak
quelle
1

Perl, 117 Zeichen

print$_,++$j%7?$":$/for map{++$i/7&$i%7&1?
eval join"+",@x[map{$i+$_,$i-$_}1,6,7,8]:" $_"}@x=map{1+int rand 9}$i--..48

Dies ist eines dieser Perl-Skripte, bei denen alle bis auf eine for-Schleife zu mapAufrufen zusammengefasst wurden, sodass alles in einer einzigen Anweisung ausgeführt werden kann. Globale Variablen erscheinen auch in dieser. Ich denke, was ich hier sagen will, ist, dass dieses Programm ein bisschen ekelhaft ist.

Warten Sie, es wird schlimmer: Es gibt einen bekannten Fehler im Skript! Es hat jedoch weniger als eine Eins-zu-eine-Million-Chance, ausgelöst zu werden, sodass ich mich noch nicht darum gekümmert habe, es zu beheben.

Brot-Box
quelle
Halten Sie uns nicht auf, was ist der Fehler?
Bonuspunkte für die erste Person, die es entdeckt!
Brotkasten
1

Mathematica , 106/100

Ich habe etwas gefunden, das dem Code von ssch sehr ähnlich ist, bevor ich es gesehen habe. Ich leihe mir seine Idee aus Column. Nur mit ASCII 106 :

s=#-1;;#+1&
a=8~RandomInteger~{7,7}+1
a[[##]]=a[[s@#,s@#2]]~Total~2-a[[##]];&@@@{2,4,6}~Tuples~2
Column/@a

Mit Unicode-Zeichen (wie von ssch verwendet), 100 :

s=#-1;;#+1&
a=8~RandomInteger~{7,7}+1
a〚##〛=a〚s@#,s@#2〛~Total~2-a〚##〛;&@@@{2,4,6}~Tuples~2
Column/@a
Mr.Wizard
quelle
1

Excel VBA, 74 Bytes

VBE-Sofortfunktion, die an ausgegeben wird [B2:H9].

[B2:H9]="=IF(ISODD(ROW()*COLUMN()),SUM(A1:C1,A2,C2,A3:C3),INT(RAND()*8)+1)

Beispielausgabe

Bildbeschreibung hier eingeben

Taylor Scott
quelle
1

Powershell, 149 148 Bytes

-1 Byte dank @AdmBorkBork. Es ist cool!

$i=-1
($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
-join($a|%{if(!(++$i%7)){"
"};'{0,3}'-f$_})

Erläuterung:

$i=-1                       # let $i store -1
($a=                        # let $a is array of random numbers with zero holes
    (,1*8+0,1*3)*3+,1*7|    # the one-dimension array equals
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
    %{                      # for each element
        $_*(1+(Random 9))   # multiply 0 or 1 element to random digit from 1 to 9
    }                       # now $a stores values like (* is a random digit from 1 to 9)
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
)|?{++$i;!$_                # calc index $i and passthru values == 0 only
}|%{                        # for each zero value cell with index $i
    6..8+1|%{               # offsets for the surrounding cells
                            #  .  .  .
                            #  .  x +1
                            # +6 +7 +8  
        $_,-$_              # add the mirror offsets 
                            # -8 -7 -6
                            # -1  x +1
                            # +6 +7 +8  
    }|%{                    # for each offset 
        $a[$i]+=$a[$i+$_]   # add surrounding values to the cell
    }
}
                            # display the $a
-join(
    $a|%{                   # for each value of $a
        if(!(++$i%7)){"`n"} # line break for each 7 cells
        '{0,3}'-f$_         # formatted value of $a with width = 3 char and align right
    }
)                           # join all values to string
mazzy
quelle
1
Sie können ein Byte (eine neue Zeile) loswerden, indem Sie Ihre $aZuweisung in Parens einkapseln und die nächste Zeile nach oben verschieben, um eine große Zeile zu bilden. -($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
AdmBorkBork
Nein, es funktioniert nicht. Das Array muss zuvor vollständig gefüllt sein $a[$i+$_]. Also hier sind zwei Schritte. Ich hatte mehrere Versuche, in einer Pipe zu kapseln. :)
mazzy
1
Es funktioniert nicht, wenn Sie keine Parens um die Aufgabe platzieren. Mit ($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))}), $awird vor der nächsten Pipeline-Instanz vollständig gefüllt. Es sollte funktionieren (zumindest für mich).
AdmBorkBork
0

Mathematica 142 151 172 179

Code

z = (m = RandomInteger[{1, 9}, {7, 7}]; s = SparseArray; o = OddQ; e = EvenQ; i = {1, 1, 1};
(m + ArrayPad[ListCorrelate[{i, i, i}, m] s[{{i_, j_} /; o@i \[And] o@j -> 1}, {5, 5}], 1]
- 2 m s[{{i_, j_} /; e@i \[And] e@j -> 1}, {7, 7}]) // Grid)

Verwendung

z

m8

DavidC
quelle
Du hast 0s; Die Regeln sagen 1-9
Türklinke
Vielen Dank. Ich habe die Daten und Bilder korrigiert. Die Funktionen bleiben unverändert.
DavidC
Außerdem sind die Zahlen nicht wie in der Frage angegeben ausgerichtet.
Türklinke
Die Wortgewandtheit von Mathematica (oder genauer gesagt, das Beharren auf großen Wörtern) wird deutlich.
DavidC
0

Julia 0,6 , 127 (89) Bytes

x=rand(1:9,7,7);[x[i,j]=sum(!(0==k==l)*x[i+k,j+l]for k=-1:1,l=-1:1)for i=2:2:7,j=2:2:7]
Base.showarray(STDOUT,x,1<1;header=1<1)

Probieren Sie es online!

89 Bytes bei Verwendung der nativen Anzeige, die zulässig sein kann, wenn zusätzliche Zeilen gedruckt werden können:

7×7 Array{Int64,2}:
6   6  8   2  3   2  3
7  44  5  33  4  23  5
3   8  1   9  1   3  2
4  41  2  37  5  22  2
7   8  8   8  3   4  2
9  53  6  44  7  36  3
7   7  1   9  2   6  9
mschauer
quelle
0

Java 10, 262 260 248 239 Bytes

v->{int a[][]=new int[7][7],i=49,j,k;for(;i-->0;)a[i/7][i%7]+=Math.random()*9+1;var r="";for(;++i<7;r+="\n")for(j=0;j<7;r+=(k=a[i][j])>9|j++%2<1?k+" ":k+"  ")if(i*j%2>0)for(a[i][j]=k=0;k<9;k++)a[i][j]+=k!=4?a[i+k/3-1][j+k%3-1]:0;return r;}

-12 Bytes dank @ceilingcat .

Erläuterung:

Probieren Sie es hier aus.

v->{                        // Method with empty unused parameter and String return-type
  int a[][]=new int[7][7],  //  Integer-matrix with 7x7 zeroes
      i=49,j,k;             //  Index integers (`i` starting at 49)
  for(;i-->0;)              //  Loop `i` in the range (49, 0]:
    a[i/7][j%7]+=Math.random()*9+1;
                            //   Fill the current cell with a random 1..9 integer
  var r="";                 //  Result-String, starting empty
  for(;++i<7;               //  Loop `i` in the range [0, 7):
      r+="\n")              //    After every iteration: append a new-line to the result
    for(j=0;j<7;            //   Inner loop `j` in the range [0, 7):
        r+=                 //     After every iteration: append the result-String with:
           (k=a[i][j])>9    //      If the current number has 2 digits,
           |j++%2<1?        //      or it's an even column (indices 0/2/4/6)
            k+" "           //       Append the current number appended with one space
           :                //      Else:
            k+"  ")         //       Append the current number appended with two spaces
      if(i*j%2>1)           //    If both indexes `i` and `j` are odd
        for(a[i][j]=k=0;    //     Reset both the current item and index `k` to 0
            k<9;k++)        //     Inner loop `k` in the range [0, 9):
          a[i][j]+=         //      Sum the item at location `i,j` with:
           k!=4?            //       If `k` is not 4 (the current item itself)
            a[i+k/3-1][j+k%3-1]
                            //        Sum it with the numbers surrounding it
           :                //       Else:
            0;              //        Leave it the same by adding 0
  return r;}                //  Return the result-String
Kevin Cruijssen
quelle
@ceilingcat Danke! Und ich konnte mit varstatt Stringund +=Math.random()*9+1;statt ein paar Bytes mehr sparen =(int)(Math.random()*9+1);. Es ist eigentlich ziemlich nützlich für dich, all meine alten Antworten zu besuchen, haha! : D
Kevin Cruijssen