Gere uma grade de somas

15

Gere uma grade 7 por 7, preenchida com números aleatórios. No entanto, nas células com um número ímpar de linhas e colunas (começando em 0), você deve usar a soma das células circundantes. Aqui está um pequeno exemplo com uma grade 3 por 3 (soma quadrada em negrito):

2 2  2
2 16 2
2 2  2

E aqui está um exemplo de grade 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

Regras

  • Os números que não são somas devem sempre estar entre 1 e 9, inclusive.

  • A grade deve ser gerada aleatoriamente. Para cada não soma, cada dígito deve ter uma chance igual de aparecer, independentemente da célula em que está.

  • Os números devem estar alinhados. Isso significa que o primeiro ou o último dígito de cada número em uma coluna deve estar alinhado verticalmente. (Você pode assumir que os números do meio sempre terão dois dígitos.)

  • As células circundantes incluem diagonais. Portanto, cada quadrado de soma terá oito números ao seu redor, que você deve adicionar.

  • O código mais curto vence, pois esse é o .

Maçaneta da porta
fonte
3
Será que ela tem que ser o primeiro dígito que as linhas acima? ou seja, pode ser o último?
Volatilidade
@ Volatility Suponho que o alinhamento à direita funcionaria. editada
Doorknob
E se um idioma não tiver um gerador de números aleatórios?
precisa

Respostas:

14

APL, 53 49 43 42 40 39 36

Consegui replicar J's ;.no APL e usei a abordagem de Gareth , economizando 13 caracteres.

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

Exemplo de execução:

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

Explicação:

  • ∘.∨⍨9⍴0 1 gera uma máscara de bit.
  • ×∘?∘9¨ multiplica cada bit por um valor aleatório de 1 a 9 inclusive, gerando uma grade mascarada de números aleatórios.
  • 3,⌿3,/usa o que só pode ser descrito como hackery para retornar todas as caixas sobrepostas de 3 por 3 na matriz mascarada. Eles também são achatados no processo.
  • {×5⌷⍵:5⌷⍵⋄+/⍵}¨itera sobre a matriz, atribuindo cada elemento a . Para cada iteração, leva o quinto (meio, lembrando que a indexação APL é baseada em 1) e retorna seu sinal. Nesse caso, isso é equivalente a testar se o número é maior que 0. Se isso retornar 1 (para verdadeiro), retorne esse elemento. Caso contrário, retorne a soma dos elementos na caixa achatada 3 por 3. Ele usa o :⋄operador ternário, que é equivalente ?:em muitos idiomas.
Volatilidade
fonte
Oh-oh. Parece que vou ter que encontrar mais economia de caracteres. : -S
Gareth
@ Gareth bem, veja o que temos aqui. Estou de volta à liderança: P
Volatilidade
NOOOOOOOOOO !!!!!!! :-(
Gareth
13

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

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

Com agradecimentos a Volatilidade por sua poupança de 10 caracteres.

Explicação (cada etapa terá diferentes números aleatórios ...):

Gere a máscara para gerar os números aleatórios (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

Agora temos um gancho . Este é realmente um acidente feliz de quando eu estava baixando uma versão anterior. Era para transpor |:e OU +.com o original. Fazia sentido desde que eu estava usando uns e zeros na época, mas agora tenho nove e zeros. Acontece que funciona da mesma maneira com o significado de GCD +.. Sorte minha. :-)

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

Então, agora que temos uma grade de 9 e 0, queremos gerar alguns números aleatórios. ?gera um número aleatório de 0 até (mas não incluindo) um determinado número. Dada uma lista, ela gerará um número aleatório dessa maneira para cada membro da lista. Portanto, nesse caso, ele gerará um número de 0 a 8 para cada 9 na tabela e um número de ponto flutuante de 0 a 1 para 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

Mas queremos números de 1 a 9 e não de 0 a 8. Portanto, adicionamos 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

Isso é muito bom, mas perdemos os zeros que eu quero, então vamos multiplicá-lo pela máscara original depois de transformar todos os noves em um. I fazer isso verificando se o valor for maior que 1. Isso nos dá: (1&<*1+?).
Há algumas coisas acontecendo aqui:

  • Criamos um fork que nos permite reunir muito trabalho em muito poucos personagens.
  • Ligamos ( &) o 1 ao <verbo.

Então, tudo combinado (1&<*1+?)é gerar números aleatórios e zerar todos os números que foram gerados por zeros na grade 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

A próxima parte é a (na minha opinião, de qualquer maneira :-) parte inteligente.
O ;.verbo recortar possui um formulário x u;._3 yque corta a entrada nas caixas descritas por xe, em seguida, aplica o verbo ua elas. Neste caso, temos 3 3(4&{++/*0=4&{)@,;._3.

  • o 3 3 está descrevendo as caixas que queremos - 3x3.
  • O (4&{++/*0=4&{)@,é um trem de verbos que descreve o que queremos fazer em cada caixa.

Para demonstrar o ;.verbo que vou usar <para mostrar cada caixa:

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

Algumas coisas a serem observadas:

  • As caixas se sobrepõem - a segunda e a terceira coluna na caixa superior esquerda são a primeira e a segunda na caixa à direita dela.
  • Existem caixas 7x7. É por isso que inicialmente tivemos uma grade 9x9.
  • Cada local em que exigimos uma soma tem um 0no centro da caixa.

Agora só precisamos passar o valor no centro das costas (se não for zero) ou somar os números na caixa 3x3 (se o centro for zero).
Para fazer isso, precisamos de fácil acesso ao número do centro. ,ajuda aqui. Transforma a grade 3x3 em uma lista de 9 itens com o número do centro no número 4.
4&{ usará {para tirar o valor central e, em seguida, compará-lo com 0: 0=4&{. Isso retorna a 0ou 1para verdadeiro ou falso, que depois multiplicamos pela soma +/. Se fosse zero no centro, agora temos nossa soma, conforme necessário. Se não fosse, não temos zero; portanto, para finalizar, basta adicionar o valor central 4&{+.
Isso dá o trem verbal(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
fonte
Sua única linha de código faz tudo isso, inclusive gera os números aleatórios? Tranquilize-me. Apenas achando difícil de acreditar.
DavidC
Sim, por mais difícil que seja acreditar. O bit aleatório é feito pelo ?. Vou mudar a explicação para refletir a versão mais recente.
Gareth
@DavidCarraher A maioria dos verbos em J tem 1 ou 2 caracteres, para que 47 caracteres sejam muito úteis.
Gareth
O corte de uma caixa 9x9 em quadrados sobrepostos 7x7 é definitivamente a parte mais inteligente. Em menos de 10 minutos, consegui aplicá-lo para vencer a minha implementação atual do GolfScript em 7,5%.
Peter Taylor
Bem, parece que está de volta à prancheta para mim.
Volatilidade
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}

Saída de amostra

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  

Demolir

Não é muito óbvio como isso funciona, então aqui está um rápido resumo. NOTA: você provavelmente pode pular algumas dessas etapas e pular para versões mais curtas mais rapidamente, mas acho que é educativo o suficiente para ver as diferentes maneiras em que raspei os caracteres, principalmente identificando padrões em literais para transformar números de 2 dígitos em versões de 1 dígito .

Versão ingênua

Diferente das outras soluções Ruby que dependem de uma matriz bidimensional, você pode (eventualmente) obter uma versão mais curta iniciando com uma matriz unidimensional e trabalhando com valores de deslocamento, uma vez que os padrões se repetem.

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

O princípio chave aqui é que estamos trabalhando nas posições 8, 10, 12 do índice, apenas compensadas por múltiplos de 14. As posições 8, 10 e 12 são os centros das grades 3x3 que estamos resumindo. Na saída de amostra, 34 é a posição 8, 42 é a posição 8 + 14 * 1, etc. Substituímos a posição 8 por 34 por posições deslocadas da posição 8 por [-8,-7,-6,-1,1,6,7,8]- em outras palavras 34 = sum(ary[8-8], ary[8-7], ..., ary[8+8]). Esse mesmo princípio vale para todos os valores de [8 + 14*i, 10 + 14*i, 12 + 14*i], uma vez que o padrão se repete.

Otimizando

Primeiro, algumas otimizações rápidas:

  • Em vez de 3.times { ... }, e calcular j + 14*icada vez, "inline" as posições [8,10,12,22,24,26,36,38,40].
  • A offsetsmatriz é usada uma vez, portanto substitua a variável pelo literal.
  • Substitua do ... endpor {...}e alterne a impressão para $> << foo. (Há um truque aqui envolvendo puts nile () == nil.)
  • Nomes de variáveis ​​mais curtos.

O código depois disso tem 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 a próxima redução, observe que injectnão é necessário que a matriz de compensações esteja em ordem. Podemos ter [-8,-7,-6,-1,1,6,7,8]ou alguma outra ordem, pois a adição é comutativa.

Então, primeiro emparelhe os pontos positivos e negativos de obter [1,-1,6,-6,7,-7,8,-8].

Agora você pode encurtar

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

para

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

Isto resulta em

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 tem 176 caracteres.

Mude para 8 e mude para diferenças

Os valores literais de dois caracteres parecem que podem ser reduzidos, então pegue [8,10,12,22,24,26,36,38,40]e mude tudo 8, atualizando jno início do loop. (Observe que +=8evita a necessidade de atualizar os valores de deslocamento 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)}

Isso é 179, que é maior, mas j+=8pode realmente ser removido.

Primeira mudança

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

para uma variedade de diferenças:

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

e adicione cumulativamente esses valores a uma inicial j=8. Isso acabará por cobrir os mesmos valores. (Nós provavelmente poderíamos pular direto para isso, em vez de mudar para 8 primeiro.)

Note que nós também vamos adicionar um valor fictício de 9999ao final da matriz diferenças, e adicionar jno final , não o início do loop. A justificativa é que 2,2,10,2,2,10,2,2parece muito próximo de ser os mesmos 3 números repetidos 3 vezes e calculandoj+difference no final do loop, o valor final de 9999realmente não afetará a saída, pois não há uma a[j]chamada em que haja jalgum valor. acabou 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)}

Com esse conjunto de diferenças, o j+=8agora é apenas j=8, é claro, pois caso contrário, adicionaríamos repetidamente 8muitos. Também alteramos a variável de bloco de jpara l.

Portanto, como o 9999elemento não tem efeito na saída, podemos alterá-lo para 10e encurtar a 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)}

São 170 caracteres.

Mas agora a j=8aparência é um pouco desajeitada e você pode salvar 2 caracteres deslocando [2,2,10]a tecla 2 para baixo para obter convenientemente um que 8você pode usar para atribuição. Isso também precisa j+=lse tornar 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)}

São 169 caracteres. Uma maneira geral de espremer 7 caracteres, mas é legal.

Ajustes finais

A values_atchamada é realmente redundante e podemos incorporar uma Array#[]chamada. então

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

torna-se

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

Você também pode identificar que flat_map+ j+e/j-e+inject pode ser reduzido a um somatório mais direto com uma inicial 0na matriz.

Isso deixa você com 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_indexpode se tornar each_slice.
  • Mude a abordagem de impressão.

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
fonte
Você pode substituir eachcom mapum byte.
Jordânia
3

Python, 132

Tecnicamente, isso não satisfaz as regras, porque os últimos dígitos de cada número estão alinhados, e não o primeiro. Mas pensei em compartilhar de qualquer maneira:

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

Saída de amostra:

[[ 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
fonte
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 uma saída mais bonita, Column/@pode ser substituída por TableForm@um custo de 2 caracteres.

ssch
fonte
Muito, muito esperto. Grid[ReplacePart[ g, {i_?EvenQ, j_?EvenQ} :> g[[s@i, s@j]]~Total~2 - g[[i, j]]]\[Transpose]]fornece uma saída mais limpa e salva alguns caracteres se você contar Transpose como um único caractere, que é o Mathmatica. Aliás, o modelo OneLinerSubmission da Wolfram contava 106 caracteres, 105 com o caractere Transpose.
DavidC
@DavidCarraher Thanks. A contagem de caracteres deve-se à nova linha desnecessária e a :>ser um símbolo, embora esteja na área de uso privado do unicode. Pode-se até remover a transposição, já que a regra de soma da validade se mantém mesmo após a transposição. Mas parece que Gridnão se alinha as entradas sem outras opções (V8)
SSCH
Gridcentraliza os números nas colunas. Tecnicamente, isso não satisfaria o desafio, mas parece melhor do que ter uma lista aparecendo na tabela exibida.
DavidC 02/09
Muito agradável. Eu passo um tempo considerável criando a mesma coisa, só eu usei Parte Tuples. Postando em breve.
Mr.Wizard
Você pode salvar dois caracteres com isso: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: contém uma guia literal, que Markdown pode muito bem quebrar.

O mais inteligente é devido a Gareth: veja sua solução em J.

Demonstração online

Peter Taylor
fonte
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

A primeira linha cria uma matriz 7 por 7 preenchida com números escolhidos aleatoriamente de 1 a 9 (distribuição uniforme com substituição, portanto, r=Tsignificareplace=TRUE ). Segunda linha, calcule somas de 3 por 3 grades, subtraia o centro e substitua-o pelo resultado. A terceira linha imprime a grade resultante (por padrão, as colunas matriz e matriz estão alinhadas à direita).

Exemplo de saída:

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

J, 67 65 bytes

Uma solução ingênua e detalhada em J. É uma implementação direta da tarefa.

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

Primeiro, crio uma matriz 7 x 7 de números inteiros entre 1 e 9. De fato, os J's? verbo gera números até seu argumento, é por isso que precisamos incrementar cada elemento,>: em 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

Eu preparo uma máscara para ser usada para zerar as células de linha / coluna ímpares, um par de índices de linha / coluna ímpares:

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

O verbo Catálogo {combina itens dos átomos dentro da lista em caixa

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

para formar um catálogo, a tabela 3x3 dos pares acima

Em seguida, preparo uma tabela de índices de linha / coluna a serem usados ​​para a seleção de cada um dos sub-arranjos 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 na matriz m, faço um par de trigêmeos, centralizados em torno de cada número do par m:

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

Esses pares de trigêmeos são usados ​​pelo verbo J From {, que pode selecionar várias linhas e colunas simultaneamente. 0 1 2/2 3 4 significa que seleciono as linhas 0, 1 e 2 juntamente com as colunas 2, 3 e 4, selecionando assim o segundo subarray 3x3 na parte superior.

Finalmente, posso usar a matriz 7x7 e as máscaras para realizar a tarefa: Primeiro, uso m como máscara para definir os elementos correspondentes como 0:

0 m}a

Então pego todas as sub-matrizes 3x3 usando s como seletor e encontro suas somas:

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

Então eu coloquei esses números de volta na 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

Experimente online!

Galen Ivanov
fonte
1

Ruby, 207

Apresentarei minha solução primeiro (como sempre faço):

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
Maçaneta da porta
fonte
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}

se a justificação do requisito de justificativa à esquerda for justamente isso ljustteria que ser usado ... bem, não. Eu amo os recursos de formatação do Ruby.

Não use Array.new(7){...}. (0..6).map{...}é mais curto e mais legível e você obtém um intervalo atribuível gratuitamente.

Linha 3 inspirada na solução da Maçaneta da porta .

John Dvorak
fonte
1

GolfScript, 87 caracteres

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

Existem muitos zíperes lá ... (veja 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
fonte
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

Embora a especificação exija que os números sejam alinhados à esquerda, não há necessidade de usar a notação decimal, então acho que essa é uma saída 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

Se o alinhamento à direita em vez de o alinhamento à esquerda for aceitável, estamos com 58 caracteres

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

J's ":(formato) possui três modos de formatação:

  • alinhado à direita com n dígitos ou com contração (exibição padrão)
  • notação científica alinhada à esquerda com n dígitos e m caracteres no total
  • display em caixa de embalagem retrátil com (esquerda / centro / direita) - alinhamento (superior / médio / inferior) (abaixo, 69 caracteres)

O mais detalhado, mas também o mais versátil, e o único capaz de produzir a saída conforme o exemplo é a 8!:2formatação estrangeira, que usa uma sequência de formatação como argumento à esquerda. Também 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

Aqui está o formato em caixa:

 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
fonte
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 é um daqueles scripts Perl em que todos, exceto um dos loops for, foram recolhidos map chamadas para que tudo possa ser feito em uma única instrução. Variáveis ​​globais também fazem algumas aparências importantes nesta. Acho que o que estou tentando dizer aqui é que este programa é um pouco grosseiro.

Espere, fica pior: há um bug conhecido no script! Porém, ele tem menos de uma chance em um milhão de ser acionado, por isso ainda não resolvi.

caixa de pão
fonte
Não nos segure, qual é o bug?
O bônus aponta para a primeira pessoa que o vê!
embalagem de pão
1

Mathematica , 106/100

Eu vim com algo muito semelhante ao código do ssch, antes de vê-lo. Estou emprestando sua ideia de usar Column. Somente com 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

Com caracteres Unicode (conforme usado pelo 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
Mr.Wizard
fonte
1

Excel VBA, 74 bytes

Função imediata VBE que gera saída para [B2:H9].

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

Saída de amostra

insira a descrição da imagem aqui

Taylor Scott
fonte
1

Powershell, 149 148 bytes

-1 byte graças a @AdmBorkBork. É legal!

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

Explicação:

$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
confuso
fonte
1
Você pode se livrar de um byte (uma nova linha) encapsulando sua $atarefa em parênteses e movendo a próxima linha para formar uma grande linha($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
#
Não. Não funciona. A matriz deve ser totalmente preenchida antes $a[$i+$_]. Então, aqui estão duas etapas. Eu tive várias tentativas de encapsular em um tubo. :)
Mazzy
1
Não funciona se você não colocar parênteses em torno da tarefa. With ($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))}), $aé totalmente preenchido antes da próxima instância do pipeline. Deve funcionar (pelo menos, funciona para mim).
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
fonte
Você tem 0s; as regras dizem 1-9
Maçaneta da porta
Obrigado. Corrigi os dados e fotos. As funções permanecem inalteradas.
DavidC
Além disso, os números não estão alinhados conforme especificado na pergunta.
Maçaneta
A verbosidade do Mathematica (ou, mais precisamente, a insistência em usar palavras grandes) se torna aparente.
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)

Experimente online!

89 bytes usando a exibição nativa, que pode ser admissível se linhas adicionais puderem ser impressas:

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
fonte
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 graças a @ceilingcat .

Explicação:

Experimente aqui.

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
fonte
@ceilingcat Thanks! E eu tenho sido capaz de salvar mais alguns bytes com varem vez de Stringe +=Math.random()*9+1;em vez de =(int)(Math.random()*9+1);. Na verdade, é muito útil você visitar todas as minhas respostas antigas, haha! : D
Kevin Cruijssen 26/11/19