Generar una cuadrícula de sumas.

15

Genere una cuadrícula de 7 por 7, llena de números aleatorios. Sin embargo, en celdas con un número impar de fila y columna (comenzando en 0), debe usar la suma de las celdas circundantes. Aquí hay un pequeño ejemplo con una cuadrícula de 3 por 3 (suma cuadrada en negrita):

2 2  2
2 16 2
2 2  2

Y aquí hay un ejemplo de cuadrícula de 7 por 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

Reglas

  • Los números que no son sumas deben estar siempre entre 1 y 9 inclusive.

  • La cuadrícula se debe generar aleatoriamente. Para cada no suma, cada dígito debe tener la misma posibilidad de aparecer, independientemente de la celda en la que se encuentre.

  • Los números deben estar alineados. Esto significa que el primer o el último dígito de cada número en una columna debe alinearse verticalmente. (Puede suponer que los números del medio siempre serán dos dígitos).

  • Las células circundantes incluyen diagonales. Por lo tanto, cada cuadrado de suma tendrá ocho números que lo rodean, que debes sumar.

  • El código más corto gana, ya que este es el .

Pomo de la puerta
fuente
3
¿ Tiene que ser el primer dígito que se alinea? es decir, ¿puede ser el último?
Volatilidad
@Volatility, supongo que la alineación correcta funcionaría. editado
Pomo de la puerta
¿Qué pasa si un idioma no tiene un generador de números aleatorios?
Heimdall el

Respuestas:

14

APL, 53 49 43 42 40 39 36

Logré replicar J's ;.en APL, y usé el enfoque de Gareth , ahorrando 13 caracteres.

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

Ejecución de muestra:

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

Explicación:

  • ∘.∨⍨9⍴0 1 genera una máscara de bits.
  • ×∘?∘9¨ multiplica cada bit por un valor aleatorio de 1 a 9 inclusive, generando una cuadrícula enmascarada de números aleatorios.
  • 3,⌿3,/usa lo que solo se puede describir como piratería para devolver los cuadros superpuestos de 3 en 3 en la matriz enmascarada. Estos también se aplanan en el proceso.
  • {×5⌷⍵:5⌷⍵⋄+/⍵}¨itera sobre la matriz, asignando cada elemento a . Para cada iteración, toma la quinta (en el medio, recordando que la indexación APL se basa en 1) y devuelve su signo. En este caso, esto es equivalente a probar si el número es mayor que 0. Si esto devuelve 1 (para verdadero), entonces devuelve ese elemento. De lo contrario, devuelva la suma de los elementos en el cuadro aplanado 3 por 3. Utiliza el :⋄operador ternario, que es el equivalente ?:en muchos idiomas.
Volatilidad
fuente
UH oh. Parece que voy a tener que encontrar más ahorros de personaje. : -S
Gareth
@Gareth bueno, mira lo que tenemos aquí. Estoy de nuevo a la cabeza: P
Volatilidad
NOOOOOOOOOO !!!!!!! :-(
Gareth
13

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

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

Con gracias a Volatility por su ahorro de 10 personajes.

Explicación (cada paso tendrá diferentes números aleatorios ...):

Genere la máscara para generar los números aleatorios (utiliza $:

   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

Ahora tenemos un gancho . Esto es realmente un feliz accidente de cuando estaba reduciendo una versión anterior. Estaba destinado a ser transpuesta |:y OR +.con el original. Tenía sentido ya que estaba usando unos y ceros en ese momento, pero ahora tengo nueves y ceros. Sucede que funciona de la misma manera con el significado de GCD de +.. Por suerte para mi. :-)

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

Entonces, ahora que tenemos una cuadrícula de 9 y 0 queremos generar algunos números aleatorios. ?genera un número aleatorio desde 0 hasta (pero sin incluir) un número dado. Dada una lista, generará un número aleatorio de esta manera para cada miembro de la lista. Entonces, en este caso, generará un número de 0 a 8 por cada 9 en la tabla y un número de coma flotante de 0 a 1 por cada 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

Pero queremos números del 1 al 9, no del 0 al 8. Así que sumamos 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

Esto es muy bueno, pero hemos perdido los ceros que quiero, así que lo multiplicaremos por la máscara original después de convertir todos los nueves en unos. Hago esto comprobando si el valor es mayor que 1. Esto nos da: (1&<*1+?).
Aquí hay un par de cosas:

  • Hemos creado una bifurcación que nos permite agrupar mucho trabajo en muy pocos caracteres.
  • Hemos unido ( &) el 1 al <verbo.

Entonces, todo combinado (1&<*1+?)genera números aleatorios y pone a cero todos los números que fueron generados por ceros en la cuadrícula original.

   (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

El siguiente bit es el (en mi opinión, de todos modos :-) bit inteligente.
El ;.verbo cortado tiene una forma x u;._3 yque corta la entrada en cuadros descritos por x, y luego les aplica el verbo u. En este caso tenemos 3 3(4&{++/*0=4&{)@,;._3.

  • los 3 3 describe los cuadros que queremos - 3x3.
  • El (4&{++/*0=4&{)@,es un tren de verbos que describe lo que queremos hacer con cada cuadro.

Para demostrar el ;.verbo que usaré <para mostrar cada cuadro:

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

Algunas cosas para notar:

  • Los cuadros se superponen: las columnas segunda y tercera en el cuadro superior izquierdo son la primera y la segunda en el cuadro a la derecha.
  • Hay 7x7 cajas. Es por eso que inicialmente tuvimos una cuadrícula de 9x9.
  • Cada lugar que necesitamos una suma tiene un 0en el centro de la caja.

Ahora solo tenemos que pasar el valor en el centro hacia atrás (si no es cero) o sumar los números en el cuadro 3x3 (si el centro es cero).
Para hacer esto, necesitamos un fácil acceso al número del centro. ,Ayuda aquí. Convierte el cuadrícula de 3x3 en una lista de 9 elementos con el número del centro en el número 4.
4&{utilizará {para sacar el valor central y luego compararlo con 0: 0=4&{. Esto devuelve un 0o 1para verdadero o falso, que luego multiplicamos por la suma +/. Si era cero en el centro, ahora tenemos nuestra suma según sea necesario. Si no fuera así, tenemos cero, así que para terminar simplemente agregamos el valor central 4&{+.
Esto le da al 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
Gareth
fuente
¿Tu única línea de código hace todo eso, incluso generar los números aleatorios? Tranquilizarme. Simplemente me resulta difícil de creer.
DavidC
Sí, por difícil que sea creer. El bit aleatorio lo realiza el ?. Cambiaré la explicación para reflejar la versión más nueva.
Gareth
@DavidCarraher La mayoría de los verbos en J son de 1 o 2 caracteres, por lo que 47 caracteres pueden incluir mucho trabajo.
Gareth
El corte de una caja de 9x9 en cuadrados superpuestos de 7x7 es definitivamente la parte más inteligente. En menos de 10 minutos pude aplicarlo para superar mi implementación actual de GolfScript en un 7,5%.
Peter Taylor
Bueno, parece que ha vuelto a la mesa de dibujo para mí.
Volatilidad
5

Ruby (135 caracteres)

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}

Salida de muestra

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  

Descompostura

No es demasiado obvio cómo funciona esto, así que aquí hay un desglose rápido. NOTA: Probablemente pueda omitir algunos de estos pasos y pasar a versiones más cortas más rápidamente, pero creo que es lo suficientemente educativo como para ver las diferentes formas en que eliminé los caracteres, especialmente al detectar patrones en literales para convertir números de 2 dígitos en versiones de 1 dígito .

Versión ingenua

A diferencia de las otras soluciones de Ruby que dependen de una matriz bidimensional, puede (eventualmente) obtener una versión más corta comenzando con una matriz unidimensional y trabajando con valores de desplazamiento, ya que los patrones se repiten.

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

El principio clave aquí es que estamos trabajando en las posiciones de índice 8, 10, 12, solo compensadas por múltiplos de 14. Las posiciones 8, 10 y 12 son los centros de las cuadrículas de 3x3 que estamos resumiendo. En la salida de muestra, 34 es la posición 8, 42 es la posición 8 + 14 * 1, etc. Reemplazamos la posición 8 con 34 por las posiciones desplazadas de la posición 8 por [-8,-7,-6,-1,1,6,7,8]- en otras palabras 34 = sum(ary[8-8], ary[8-7], ..., ary[8+8]). Este mismo principio es válido para todos los valores de[8 + 14*i, 10 + 14*i, 12 + 14*i] , ya que el patrón se repite.

Optimizándolo

Primero, algunas optimizaciones rápidas:

  • En lugar de 3.times { ... }, y calculando j + 14*icada vez, "en línea" las posiciones [8,10,12,22,24,26,36,38,40].
  • La offsetsmatriz se usa una vez, así que reemplace la variable con el literal.
  • Reemplace do ... endcon {...}y cambie la impresión a $> << foo. (Aquí hay un truco que involucra puts nily () == nil).
  • Nombres de variables más cortos.

El código después de esto es 177 caracteres:

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

Para la próxima reducción, tenga en cuenta que injectno necesita que la matriz de compensaciones esté en orden. Podemos tener [-8,-7,-6,-1,1,6,7,8]u otro orden, ya que la suma es conmutativa.

Así que primero empareje los aspectos positivos y negativos para obtener [1,-1,6,-6,7,-7,8,-8].

Ahora puedes acortar

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

a

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

Esto resulta en

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

que tiene 176 caracteres.

Cambia por 8 y pasa a las diferencias

Parece que los valores literales de dos caracteres se pueden acortar, así que tome [8,10,12,22,24,26,36,38,40]y cambie todo hacia abajo 8, actualizando jal comienzo del ciclo. (Tenga en cuenta que +=8evita tener que actualizar los valores de desplazamiento de 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)}

Esto es 179, que es más grande, pero en j+=8realidad se puede eliminar.

Primer cambio

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

a una serie de diferencias:

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

y acumulativamente agregue estos valores a una inicial j=8. Esto eventualmente cubrirá los mismos valores. (Probablemente podríamos pasar directamente a esto en lugar de cambiar por 8 primero).

Tenga en cuenta que vamos a añadir un valor ficticio de 9999la final de la matriz diferencias, y añadimos a jla final , no el inicio del bucle. La justificación es que se 2,2,10,2,2,10,2,2ve muy cerca de ser los mismos 3 números repetidos 3 veces, y al calcular j+differenceal final del ciclo, el valor final de 9999no afectará realmente la salida, ya que no hay una a[j]llamada donde jhay algún valor terminado 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 esta matriz de diferencias, j+=8ahora es justa j=8, por supuesto, ya que de lo contrario agregaríamos 8demasiadas veces . También hemos cambiado la variable de bloque de jal .

Entonces, dado que el 9999elemento no tiene ningún efecto en la salida, podemos cambiarlo 10y acortar la matriz.

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

Esto es 170 caracteres.

Pero ahora se j=8ve un poco torpe, y puede guardar 2 caracteres al cambiar [2,2,10]hacia abajo por 2 para obtener convenientemente un 8que pueda usar para la asignación. Esto también necesita j+=lser 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)}

Esto es 169 caracteres. Una forma redonda de exprimir 7 caracteres, pero es genial.

Ajustes finales

La values_atllamada es en realidad algo redundante, y podemos hacer una Array#[]llamada en línea . Entonces

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

se convierte

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

También puede detectar que flat_map+ j+e/j-e+ injectse puede reducir a una suma más directa con una inicial 0en la matriz.

Esto te deja con 152 caracteres:

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

Finalmente:

  • map.with_indexpuede llegar a ser each_slice.
  • Cambiar el enfoque de impresión.

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
fuente
Se puede reemplazar eachcon mapun byte.
Jordan
3

Python, 132

Esto técnicamente no satisface las reglas, porque los últimos dígitos de cada número están alineados en lugar del primero. Pero pensé en compartir de todos modos:

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

Salida de muestra:

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

resultado

Para una salida más bonita Column/@se puede reemplazar con TableForm@un costo de 2 caracteres.

ssch
fuente
Muy, muy listo. Grid[ReplacePart[ g, {i_?EvenQ, j_?EvenQ} :> g[[s@i, s@j]]~Total~2 - g[[i, j]]]\[Transpose]]da una salida más limpia y guarda un par de caracteres si cuenta Transponer como un solo carácter, que está en Mathmatica. Por cierto, la plantilla OneLinerSubmission de Wolfram contó 106 caracteres, 105 con el carácter Transposición.
DavidC
@DavidCarraher Gracias. El recuento de caracteres se debe a una nueva línea innecesaria y a :>ser un símbolo, aunque está en el área de uso privado de Unicode. Incluso se podría eliminar la transposición, ya que la regla de suma de validez se mantiene incluso después de la transposición. Pero parece Gridque no alinea las entradas sin más opciones (v8)
ssch
Gridcentra los números dentro de columnas. Técnicamente, eso no satisfaría el desafío, pero se ve mejor que tener una lista en la tabla mostrada.
DavidC
Muy agradable. Solo paso un tiempo considerable creando lo mismo, solo que usé Party Tuples. Publicando pronto.
Mr.Wizard
Podrías guardar dos personajes con esto: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 caracteres)

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

Nota: contiene una pestaña literal que Markdown puede romper.

La parte inteligente se debe a Gareth: vea su solución J.

Demostración en línea

Peter Taylor
fuente
3

R: 114 caracteres

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 primera línea crea una matriz de 7 por 7 llena de números elegidos al azar del 1 al 9 (distribución uniforme con reemplazo, por r=Tlo tanto, lo que significa replace=TRUE). Segunda línea, calcule sumas de 3 por 3 cuadrículas, reste el centro y reemplácelo con el resultado. La tercera línea imprime la cuadrícula resultante (por defecto, las columnas de matriz y matriz están alineadas a la derecha).

Salida de ejemplo:

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

J, 67 65 bytes

Una solución ingenua y detallada en J. Es una implementación sencilla de la tarea.

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

Primero creo una matriz de 7 x 7 de enteros entre 1 y 9. ¿De hecho J's? el verbo genera números hasta su argumento, es por eso que necesitamos incrementar cada elemento,>: en 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 máscara para usar para poner a cero las celdas impares de fila / columna, un par de índices de fila / columna impares:

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

El verbo Catálogo {combina elementos de los átomos dentro de la lista en recuadro

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

para formar un catálogo, la tabla 3x3 de los pares de arriba

Luego preparo una tabla de índices de fila / columna para usar en la selección de cada una de las submatrices de 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││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
└─────────────┴─────────────┴─────────────┘

Para cada par en la matriz m hago un par de tripletes, centrados alrededor de cada número del par m:

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

Estos pares de tripletes son utilizados por el verbo J From {, que puede seleccionar múltiples filas y columnas simultáneamente. 0 1 2/2 3 4 significa que selecciono las filas 0, 1 y 2 junto con las columnas 2, 3 y 4, seleccionando así el segundo subconjunto 3x3 en la parte superior.

Finalmente, puedo usar la matriz 7x7 y las máscaras para lograr la tarea: Primero uso m como máscara para establecer los elementos correspondientes en 0:

0 m}a

Luego tomo todas las submatrices 3x3 usando s como selector y encuentro sus sumas:

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

Luego puse estos números nuevamente en la matriz inicial.

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

Pruébalo en línea!

Galen Ivanov
fuente
1

Rubí, 207

Presentaré mi solución primero (como siempre lo hago):

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
Pomo de la puerta
fuente
1

Ruby, 150 caracteres.

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}

si el requisito de justificación de la izquierda es solo eso ljusttendría que ser usado ... bueno, no. Me encantan las capacidades de formateo de Ruby.

No utilice Array.new(7){...}. (0..6).map{...}es más corto y más legible y obtienes un rango asignable de forma gratuita.

Línea # 3 inspirada en la solución de Doorknob .

John Dvorak
fuente
1

GolfScript, 87 caracteres

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

Hay demasiadas cremalleras allí ... (ver en línea )

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

J, 58/64/67 caracteres

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

Si bien la especificación requiere que los números estén alineados a la izquierda, no es necesario usar la notación decimal, por lo que supongo que esta es una salida válida:

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

Si la alineación derecha en lugar de la alineación izquierda es aceptable, estamos en 58 caracteres

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

J ":(formato) tiene tres modos de formato:

  • alineado a la derecha con n dígitos o con retractilado (pantalla predeterminada)
  • notación científica alineada a la izquierda con n dígitos ym caracteres en total
  • pantalla en caja retráctil con (izquierda / centro / derecha) - (arriba / centro / abajo) alineación (abajo, 69 caracteres)

El más detallado pero también más versátil y el único capaz de producir la salida según el ejemplo es el 8!:2formato extranjero, que toma una cadena de formato como argumento izquierdo. También 67 caracteres :

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

Aquí está el formato en caja:

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

Perl, 117 caracteres

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

Este es uno de esos scripts de Perl donde todos menos uno de los bucles for se han colapsado en mapllamadas para que todo se pueda hacer en una sola declaración. Las variables globales también hacen algunas apariciones importantes en este caso. Supongo que lo que estoy tratando de decir aquí es que este programa es un poco asqueroso.

Espera, empeora: ¡Hay un error conocido en el script! Sin embargo, tiene menos de una probabilidad en un millón de ser disparado, por lo que aún no he podido solucionarlo.

caja de pan
fuente
No nos esperes, ¿cuál es el error?
¡Los puntos de bonificación a la primera persona que lo ve!
breadbox
1

Mathematica , 106/100

Se me ocurrió algo muy similar al código de ssch, antes de verlo. Estoy tomando prestada su idea de usar 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 caracteres Unicode (como los utilizados por 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
Señor mago
fuente
1

Excel VBA, 74 bytes

VBE función inmediata que da salida a [B2:H9].

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

Salida de muestra

ingrese la descripción de la imagen aquí

Taylor Scott
fuente
1

Powershell, 149 148 bytes

-1 byte gracias a @AdmBorkBork. ¡Es genial!

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

Explicación:

$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
fuente
1
Puede deshacerse de un byte (una nueva línea) encapsulando su $aasignación en parens y moviendo la siguiente línea hacia arriba para formar una línea grande($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
AdmBorkBork
No. No funciona La matriz debe estar completamente poblada antes $a[$i+$_]. Así que aquí hay dos pasos. Tuve varios intentos de encapsular en una tubería. :)
mazzy
1
No funciona si no coloca a los padres alrededor de la tarea. Con ($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))}), $ase llena completamente antes de la siguiente instancia de canalización. Debería funcionar (al menos, lo hace para mí).
AdmBorkBork
0

Mathematica 142 151 172 179

Código

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

DavidC
fuente
Tienes 0s; las reglas dicen 1-9
Pomo de la puerta
Gracias. Corrija los datos y las fotos. Las funciones permanecen sin cambios.
DavidC
Además, los números no están alineados como se especifica en la pregunta.
Pomo
La palabrería de Mathematica (o, más exactamente, la insistencia en usar palabras grandes) se hace evidente.
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)

Pruébalo en línea!

89 bytes con pantalla nativa, que podría ser admisible si se pueden imprimir líneas adicionales:

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
fuente
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 gracias a @ceilingcat .

Explicación:

Pruébalo aquí.

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
fuente
@ceilingcat Gracias! Y he podido guardar algunos bytes más en varlugar deString y en +=Math.random()*9+1;lugar de =(int)(Math.random()*9+1);. En realidad, es bastante útil para ti visitar todas mis viejas respuestas, ¡jaja! : D
Kevin Cruijssen