Genera una griglia di somme


15

Genera una griglia 7 per 7, piena di numeri casuali. Tuttavia, nelle celle con un numero di riga e colonna dispari (a partire da 0), è necessario utilizzare la somma delle celle circostanti. Ecco un piccolo esempio con una griglia 3 per 3 (grassetto somma quadrata):

2 2  2
2 16 2
2 2  2

Ed ecco un esempio di griglia 7 per 7:

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

Regole

  • I numeri che non sono somme devono sempre essere compresi tra 1 e 9 inclusi.

  • La griglia deve essere generata casualmente. Per ogni non somma, ogni cifra deve avere le stesse probabilità di apparire, indipendentemente dalla cella in cui si trova.

  • I numeri devono essere allineati. Ciò significa che la prima o l'ultima cifra di ciascun numero in una colonna devono essere allineate verticalmente. (Si può presumere che i numeri medi saranno sempre di due cifre.)

  • Le celle circostanti includono diagonali. Pertanto, ogni quadrato della somma avrà otto numeri che lo circondano, che è necessario aggiungere.

  • Il codice più corto vince, poiché si tratta di .


3
Ha deve essere la prima cifra che allinea? cioè può essere l'ultimo?
Volatilità,

@Volatilità Suppongo che l'allineamento a destra funzionerebbe. a cura di
Maniglia

Cosa succede se una lingua non ha un generatore di numeri casuali?
Heimdall,

Risposte:


14

APL, 53 49 43 42 40 39 36

Sono riuscito a replicare J's ;.in APL e ho usato l'approccio di Gareth , risparmiando 13 caratteri.

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

Esecuzione di esempio:

      {×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

Spiegazione:

  • ∘.∨⍨9⍴0 1 genera una maschera di bit.
  • ×∘?∘9¨ moltiplica ogni bit per un valore casuale compreso tra 1 e 9 inclusi, generando una griglia mascherata di numeri casuali.
  • 3,⌿3,/utilizza ciò che può essere descritto solo come pirateria informatica per restituire tutte le caselle sovrapposte 3 per 3 nell'array mascherato. Anche questi sono appiattiti nel processo.
  • {×5⌷⍵:5⌷⍵⋄+/⍵}¨scorre sull'array, assegnando ogni elemento a . Per ogni iterazione, prende il quinto (al centro, ricordando che l'indicizzazione APL è basata su 1) e restituisce il suo segno. In questo caso ciò equivale a verificare se il numero è maggiore di 0. Se restituisce 1 (per true), restituisce quell'elemento. In caso contrario, restituisce la somma degli elementi nella casella appiattita 3 per 3. Utilizza l' :⋄operatore ternario, che è l'equivalente di ?:in molte lingue.

Uh Oh. Sembra che dovrò trovare più risparmi nei personaggi. : -S
Gareth,

@Gareth bene, guarda cosa abbiamo qui. Sono tornato in testa: P
Volatilità,

Noooooooooo !!!!!!! :-(
Gareth,

13

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

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

Grazie a Volatility per il suo salvataggio di 10 personaggi.

Spiegazione (ogni passaggio avrà numeri casuali diversi ...):

Genera la maschera per generare i numeri casuali (usa $:

   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

Ora abbiamo un gancio . Questo è in realtà un felice incidente da quando stavo ridimensionando una versione precedente. Doveva essere trasposto |:e OR +.con l'originale. Aveva senso da quando stavo usando uno e zero in quel momento, ma ora ho nove e zero. Accade solo che funzioni allo stesso modo con il significato di GCD di +.. Fortuna a me. :-)

   (+.|:)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

Quindi, ora che abbiamo una griglia di 9 e 0 vogliamo generare alcuni numeri casuali. ?genera un numero casuale da 0 a (ma non incluso) un determinato numero. Dato un elenco, genererà un numero casuale in questo modo per ciascun membro dell'elenco. Quindi in questo caso genererà un numero compreso tra 0 e 8 per ogni 9 nella tabella e un numero in virgola mobile compreso tra 0 e 1 per ogni 0.

   ?(+.|:)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

Ma vogliamo numeri da 1 a 9 e non da 0 a 8. Quindi aggiungiamo 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

Questo è molto bello ma abbiamo perso gli zero che voglio, quindi lo moltiplicheremo per la maschera originale dopo aver trasformato tutti i nove in uno. Faccio questo controllando se il valore è maggiore di 1. Questo ci dà: (1&<*1+?).
Qui ci sono un paio di cose:

  • Abbiamo creato un fork che ci consente di raggruppare molto lavoro in pochissimi personaggi.
  • Abbiamo legato ( &) l'1 al <verbo.

Quindi tutto combinato (1&<*1+?)sta generando numeri casuali e azzerando tutti i numeri che sono stati generati da zero nella griglia originale.

   (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

Il prossimo passo è il (secondo me, comunque :-) un po 'intelligente.
Il ;.verbo tagliato ha una forma x u;._3 yche taglia l'input nelle caselle descritte da x, e quindi applica il verbo uad esse. In questo caso abbiamo 3 3(4&{++/*0=4&{)@,;._3.

  • La 3 3descrive le caselle che vogliamo - 3x3.
  • Il (4&{++/*0=4&{)@,è un treno, verbo che descrive ciò che vogliamo fare per ogni casella.

Per dimostrare il ;.verbo che userò <per mostrare ogni casella:

   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│
└─────┴─────┴─────┴─────┴─────┴─────┴─────┘

Alcune cose da notare:

  • Le caselle si sovrappongono: la seconda e la terza colonna nella casella in alto a sinistra sono la prima e la seconda nella casella a destra di essa.
  • Ci sono scatole 7x7. Ecco perché inizialmente avevamo una griglia 9x9.
  • Ogni posto in cui richiediamo una somma ha una 0al centro della scatola.

Ora dobbiamo solo passare il valore al centro indietro (se è diverso da zero) o sommare i numeri nella casella 3x3 (se il centro è zero).
Per fare ciò abbiamo bisogno di un facile accesso al numero centrale. ,aiuta qui. Risulta griglia 3x3 in una lista di 9 oggetti con il numero del centro al numero 4.
4&{utilizzerà {per estrarre il valore centrale e poi confrontarlo con 0: 0=4&{. Questo restituisce un 0o 1per vero o falso, che moltiplichiamo per la somma +/. Se al centro era zero, ora abbiamo la nostra somma come richiesto. In caso contrario, abbiamo zero, quindi per finire aggiungiamo semplicemente il valore centrale 4&{+.
Questo dà il verbo 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

La tua unica riga di codice fa tutto ciò, incluso generare numeri casuali? Rassicurami. Trovo difficile da credere.
DavidC,

Sì, per quanto possa essere difficile da credere. Il bit casuale viene eseguito dal ?. Cambierò la spiegazione per riflettere la versione più recente.
Gareth,

@DavidCarraher La maggior parte dei verbi in J sono composti da 1 o 2 caratteri, quindi 47 caratteri possono contenere un sacco di lavoro.
Gareth,

Il taglio di una scatola 9x9 in quadrati sovrapposti 7x7 è sicuramente la parte intelligente. In meno di 10 minuti sono stato in grado di applicarlo per battere la mia attuale implementazione GolfScript del 7,5%.
Peter Taylor,

Vabbè, sembra che sia tornato al tavolo da disegno per me.
Volatilità

5

Ruby (135 caratteri)

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}

Uscita campione

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  

Abbattersi

Non è troppo ovvio come funzioni, quindi ecco una rapida ripartizione. NOTA: Probabilmente puoi saltare alcuni di questi passaggi e passare a versioni più brevi più rapidamente, ma penso che sia abbastanza educativo vedere diversi modi in cui ho rasato i caratteri, in particolare individuando modelli in letterali per trasformare i numeri a 2 cifre in versioni a 1 cifra .

Versione ingenua

A differenza delle altre soluzioni Ruby che si basano su un array bidimensionale, è possibile (eventualmente) ottenere una versione più breve iniziando con un array monodimensionale e lavorando con valori di offset, poiché i motivi si ripetono.

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

Il principio chiave qui è che stiamo lavorando alle posizioni di indice 8, 10, 12, appena compensate da multipli di 14. Le posizioni 8, 10 e 12 sono i centri delle griglie 3x3 che stiamo riassumendo. Nell'output del campione, 34 è la posizione 8, 42 è la posizione 8 + 14 * 1, ecc. Sostituiamo la posizione 8 con 34 con posizioni sfalsate dalla posizione 8 con [-8,-7,-6,-1,1,6,7,8]- in altre parole 34 = sum(ary[8-8], ary[8-7], ..., ary[8+8]). Lo stesso principio vale per tutti i valori di [8 + 14*i, 10 + 14*i, 12 + 14*i], poiché il modello si ripete.

Ottimizzandolo

Innanzitutto, alcune rapide ottimizzazioni:

  • Invece 3.times { ... }e calcolando j + 14*iogni volta, "inline" le posizioni [8,10,12,22,24,26,36,38,40].
  • L' offsetsarray viene utilizzato una volta, quindi sostituisci la variabile con il valore letterale.
  • Sostituire do ... endcon {...}e passare alla stampa in $> << foo. (C'è un trucco qui che coinvolge puts nile () == nil.)
  • Nomi delle variabili più brevi.

Il codice dopo questo è di 177 caratteri:

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)}

Per la prossima riduzione, si noti che injectnon è necessario che l'array di offset sia in ordine. Possiamo avere [-8,-7,-6,-1,1,6,7,8]o qualche altro ordine, poiché l'aggiunta è commutativa.

Quindi prima abbina gli aspetti positivi e quelli negativi da ottenere [1,-1,6,-6,7,-7,8,-8].

Ora puoi accorciare

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

per

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

Questo risulta in

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)}

che è di 176 caratteri.

Spostati di 8 e passa alle differenze

I valori letterali a due caratteri sembrano essere accorciabili, quindi prendi [8,10,12,22,24,26,36,38,40]e sposta tutto verso il basso 8, aggiornando jall'inizio del ciclo. (Notare che non è +=8necessario aggiornare i valori di offset di 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)}

Questo è 179, che è più grande, ma j+=8può effettivamente essere rimosso.

Primo cambiamento

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

a una serie di differenze:

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

e aggiungere cumulativamente questi valori a un'iniziale j=8. Questo finirà per coprire gli stessi valori. (Probabilmente potremmo saltare direttamente a questo invece di spostarci prima di 8).

Si noti che noi anche aggiungere un valore fittizio di 9999alla fine dell'array differenze, e aggiungiamo jalla fine , non la partenza del ciclo. La giustificazione è che 2,2,10,2,2,10,2,2sembra terribilmente vicino ad essere gli stessi 3 numeri ripetuti 3 volte e calcolando j+differencealla fine del ciclo, il valore finale di 9999non influenzerà effettivamente l'output, dal momento che non c'è una a[j]chiamata dove jc'è un certo valore finita 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)}

Con questo array di differenze, j+=8ora è solo j=8, ovviamente, poiché altrimenti ne aggiungeremmo ripetutamente 8troppe. Abbiamo anche cambiato la variabile di blocco da ja l.

Quindi, poiché l' 9999elemento non ha alcun effetto sull'output, possiamo cambiarlo 10e accorciare l'array.

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)}

Questo è di 170 caratteri.

Ma ora j=8sembra un po 'goffo, e puoi salvare 2 caratteri spostando in [2,2,10]basso di 2 per ottenere convenientemente un 8che puoi usare per il compito. Anche questo deve j+=ldiventare 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)}

Questo è di 169 caratteri. Un modo completo per spremere 7 personaggi, ma è pulito.

Modifiche finali

La values_atchiamata è in realtà una sorta di ridondante e possiamo incorporare una Array#[]chiamata. Così

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

diventa

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

Puoi anche individuare che flat_map+ j+e/j-e+ injectpuò essere ridotto a una somma più diretta con un'iniziale 0nell'array.

Questo ti lascia con 152 caratteri:

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)}

Infine:

  • map.with_indexpuò diventare each_slice.
  • Cambia l'approccio di stampa.

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}

È possibile sostituire eachcon mapper un byte.
Giordania,

3

Python, 132

Ciò non soddisfa tecnicamente le regole, poiché le ultime cifre di ciascun numero sono allineate anziché la prima. Ma ho pensato di condividere comunque:

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

Uscita campione:

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

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

risultato

Per un output più bello Column/@può essere sostituito con TableForm@un costo di 2 caratteri.


Molto, molto intelligente. Grid[ReplacePart[ g, {i_?EvenQ, j_?EvenQ} :> g[[s@i, s@j]]~Total~2 - g[[i, j]]]\[Transpose]]fornisce un output più pulito e salva un paio di caratteri se si considera Transpose come un singolo carattere, che è in Mathmatica. A proposito, il modello OneLinerSubmission di Wolfram ha contato 106 caratteri, 105 con il carattere Transpose.
DavidC,

@DavidCarraher Grazie. Il conteggio dei caratteri è dovuto a una nuova riga non necessaria ed :>è un simbolo, sebbene sia nell'area di uso privato di Unicode. Si potrebbe persino rimuovere il recepimento, poiché la regola di sommatoria di validità vale anche dopo il recepimento. Ma sembra Gridnon allineare le voci senza ulteriori opzioni (v8)
ssch

Gridcentra i numeri all'interno delle colonne. Tecnicamente, ciò non soddisferebbe la sfida, ma sembra migliore che avere un elenco visualizzato nella tabella visualizzata.
DavidC

Molto bella. Trascorro molto tempo a creare la stessa cosa, solo io ho usato Parte Tuples. Invio presto.
Mr.Wizard,

Potresti salvare due personaggi con questo: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 caratteri)

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

NB Questo contiene una scheda letterale, che Markdown potrebbe rompere.

La parte intelligente è dovuta a Gareth: vedi la sua soluzione J.

Demo online


3

R: 114 caratteri

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

La prima riga crea un array 7 per 7 riempito con numeri scelti casualmente da 1 a 9 (distribuzione uniforme con sostituzione, quindi r=Tche sta perreplace=TRUE ). Seconda riga, calcola somme di 3 per 3 griglie, sottrai il centro e sostituiscilo con il risultato. La terza riga stampa la griglia risultante (per impostazione predefinita, le colonne matrice e matrice sono allineate a destra).

Esempio di output:

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

2

J, 67 65 byte

Una soluzione ingenua e dettagliata in J. È un'implementazione diretta del compito.

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

Per prima cosa creo un array 7 x 7 di numeri interi compresi tra 1 e 9. In effetti, J's? il verbo genera numeri fino al suo argomento, ecco perché dobbiamo incrementare ogni elemento,>: 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

Preparo una maschera da utilizzare per l'azzeramento delle celle dispari / colonne, una coppia di indici dispari / colonne:

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

Il verbo del catalogo {combina elementi dagli atomi all'interno dell'elenco in scatola

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

per formare un catalogo, la tabella 3x3 delle coppie sopra

Quindi preparo una tabella di indici riga / colonna da utilizzare per la selezione di ciascuno dei subarray 3x3.

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││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
└─────────────┴─────────────┴─────────────┘

Per ogni coppia nella matrice m faccio una coppia di terzine, centrate attorno a ciascun numero della coppia m:

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

Queste coppie di terzine sono utilizzate dal verbo J From {, che può selezionare più righe e colonne contemporaneamente. 0 1 2/2 3 4 significa che seleziono le righe 0, 1 e 2 insieme alle colonne 2, 3 e 4, selezionando quindi il secondo sottoarray 3x3 in alto.

Infine, posso usare l'array 7x7 e le maschere per raggiungere il compito: in primo luogo uso m come maschera per impostare gli elementi corrispondenti su 0:

0 m}a

Quindi prendo tutti i subarrays 3x3 usando s come selettore e trovo le loro somme:

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

Quindi ho reinserito questi numeri nella matrice iniziale.

 (+/^:_"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

Provalo online!



1

Ruby, 207

Presenterò prima la mia soluzione (come faccio sempre):

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

1

Rubino, 150 caratteri

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}

se la giustificazione del requisito di giustificazione a sinistra è proprio questa ljust dovrebbe essere utilizzata ... beh, no. Adoro le capacità di formattazione di Ruby.

Non usare Array.new(7){...}. (0..6).map{...}è più breve e più leggibile e ottieni un intervallo assegnabile gratuitamente.

Linea n. 3 ispirata alla soluzione di Doorknob .


1

GolfScript, 87 caratteri

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

Ci sono troppe cerniere lì dentro ... (vedi 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  

1

J, 58/64/67 caratteri

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

Mentre la specifica richiede che i numeri siano allineati a sinistra, non è necessario utilizzare la notazione decimale, quindi suppongo che questo sia un output valido:

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

Se l'allineamento a destra anziché quello a sinistra è accettabile, siamo a 58 caratteri

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

J ":(formato) ha tre modalità di formattazione:

  • allineato a destra con n cifre o con termoretraibile (visualizzazione predefinita)
  • notazione scientifica allineata a sinistra con n cifre e m caratteri totali
  • display in scatola termoretraibile con allineamento (sinistro / centrale / destro) - (alto / medio / basso) (sotto, 69 caratteri)

Il più prolisso ma anche il più versatile e l'unico in grado di produrre l'output secondo l'esempio è la 8!:2formattazione esterna, che accetta una stringa di formattazione come argomento sinistro. Anche 67 caratteri :

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

Ecco il formato in scatola:

 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│
 └─┴──┴─┴──┴─┴──┴─┘

1

Perl, 117 caratteri

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

Questo è uno di quegli script Perl in cui tutti i loop for tranne uno sono stati compressi in mapchiamate in modo che tutto possa essere fatto in una singola istruzione. Le variabili globali fanno anche alcune apparizioni importanti in questo. Immagino che quello che sto cercando di dire qui sia, questo programma è un po 'disgustoso.

Aspetta, peggiora: c'è un bug noto nella sceneggiatura! Tuttavia, ha meno di una possibilità su un milione di essere attivato, quindi non sono ancora riuscito a risolverlo.


Non trattenerci, qual è il bug?

Punti bonus per la prima persona che lo individua!
breadbox

1

Mathematica , 106/100

Ho trovato qualcosa di molto simile al codice di ssch, prima di vederlo. Sto prendendo in prestito la sua idea di utilizzo Column. Solo con 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

Con caratteri Unicode (usati da ssch), 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

1

Excel VBA, 74 byte

VBE funzione immediata che genera [B2:H9].

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

Uscita campione

inserisci qui la descrizione dell'immagine


1

Powershell, 149 148 byte

-1 byte grazie a @AdmBorkBork. È fantastico!

$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$_})

Spiegazione:

$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

1
Puoi sbarazzarti di un byte (una nuova riga) incapsulando il tuo $acompito in parentesi e spostando la riga successiva per creare una grande linea -($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
AdmBorkBork

No. Non funziona. L'array deve essere completamente popolato prima $a[$i+$_]. Quindi, ecco due passaggi. Ho avuto diversi tentativi di incapsulare in una pipa. :)
mazzy

1
Non funziona se non si posizionano le parentesi attorno al compito. Con ($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))}), $aè completamente popolato prima della prossima istanza della pipeline. Dovrebbe funzionare (almeno, lo fa per me).
AdmBorkBork,

0

Mathematica 142 151 172 179

Codice

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)

uso

z

m8


Hai 0s; le regole dicono 1-9
Maniglia della porta

Grazie. Ho corretto i dati e le foto. Le funzioni rimangono invariate.
DavidC

Inoltre, i numeri non sono allineati come specificato nella domanda.
Maniglia della porta

La verbosità di Mathematica (o, più precisamente, l'insistenza sull'uso di parole grosse) diventa evidente.
DavidC

0

Julia 0,6 , 127 (89) byte

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)

Provalo online!

89 byte utilizzando la visualizzazione nativa, che potrebbe essere ammissibile se è possibile stampare righe aggiuntive:

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

0

Java 10, 262 260 248 239 byte

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 byte grazie a @ceilingcat .

Spiegazione:

Provalo qui.

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

@ceilingcat Grazie! E sono stato in grado di salvare qualche byte in più con varinvece di Stringe +=Math.random()*9+1;invece di =(int)(Math.random()*9+1);. In realtà è abbastanza utile per te visitare tutte le mie vecchie risposte, ahah! : D
Kevin Cruijssen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.