Wygeneruj siatkę sum

15

Wygeneruj siatkę 7 na 7, wypełnioną liczbami losowymi. Jednak w komórkach z nieparzystym numerem wiersza i kolumny (zaczynającym się od 0) należy użyć sumy otaczających komórek. Oto mały przykład z siatką 3 na 3 (pogrubiona kwadratowo):

2 2  2
2 16 2
2 2  2

A oto przykład siatki 7 na 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

Zasady

  • Liczby, które nie są sumami, muszą zawsze zawierać się między 1 a 9 włącznie.

  • Siatka musi być generowana losowo. Dla każdej sumy każda cyfra musi mieć równe szanse pojawienia się, niezależnie od tego, w której komórce się znajduje.

  • Liczby muszą być wyrównane. Oznacza to, że pierwsza lub ostatnia cyfra każdej liczby w kolumnie musi być ustawiona pionowo. (Możesz założyć, że środkowe liczby będą zawsze składały się z dwóch cyfr).

  • Otaczające komórki obejmują przekątne. Dlatego każdy kwadrat sumy będzie miał osiem liczb, które należy dodać.

  • Wygrywa najkrótszy kod, ponieważ jest to .

Klamka
źródło
3
Czy to musi być pierwsza cyfra w linii? tzn. czy może to być ostatni?
Zmienność
@ Lotność Przypuszczam, że wyrównanie w prawo działałoby. edytowane
Klamka
Co jeśli język nie ma generatora liczb losowych?
Heimdall,

Odpowiedzi:

14

APL, 53 49 43 42 40 39 36

Udało mi się powielić J ;.w APL i wykorzystałem podejście Garetha , oszczędzając 13 znaków.

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

Przykładowy przebieg:

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

Wyjaśnienie:

  • ∘.∨⍨9⍴0 1 generuje trochę maski.
  • ×∘?∘9¨ mnoży każdy bit przez losową wartość od 1 do 9 włącznie, generując zamaskowaną siatkę liczb losowych.
  • 3,⌿3,/używa czegoś, co można określić tylko jako hackery, aby zwrócić wszystkie nakładające się pola 3 na 3 w zamaskowanej tablicy. Są one również spłaszczane w procesie.
  • {×5⌷⍵:5⌷⍵⋄+/⍵}¨iteruje tablicę, przypisując każdy element do . Dla każdej iteracji zajmuje piąte (środkowe, pamiętając, że indeksowanie APL jest oparte na 1) i zwraca swój znak. W takim przypadku jest to równoważne z testowaniem, czy liczba jest większa niż 0. Jeśli to zwraca 1 (dla wartości true), zwróć ten element. W przeciwnym razie zwróć sumę elementów w spłaszczonym polu 3 na 3. Wykorzystuje :⋄operator trójskładnikowy, który jest odpowiednikiem ?:wielu języków.
Zmienność
źródło
O o. Wygląda na to, że będę musiał znaleźć więcej oszczędności dla postaci. : -S
Gareth
@Gareth, zobacz, co tu mamy. Wróciłem na prowadzenie: P
Volatility
NIEEEEEEEEEEEE !!!!!!! :-(
Gareth,
13

J, 63 61 59 55 52 51 49 47 39 37 znaków

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

Dzięki Zmienności za uratowanie 10 postaci.

Objaśnienie (każdy krok będzie miał różne liczby losowe ...):

Wygeneruj maskę do generowania liczb losowych (używa $:

   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

Teraz mamy haczyk . To jest właściwie szczęśliwy wypadek, kiedy traciłem wcześniejszą wersję. Miał być transponowany |:i OR +.z oryginałem. To miało sens, ponieważ używałem wówczas zer i jedynek, ale teraz mam dziewiątki i zera. Tak się składa, że ​​działa w ten sam sposób, co GCD +.. Szczęśliwie dla mnie. :-)

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

Teraz, kiedy mamy siatkę 9 i 0, chcemy wygenerować losowe liczby. ?generuje liczbę losową od 0 do (ale nie wliczając) podanej liczby. Dana lista wygeneruje w ten sposób jedną liczbę losową dla każdego członka listy. Tak więc w tym przypadku wygeneruje liczbę od 0 do 8 dla każdego 9 w tabeli i liczbę zmiennoprzecinkową od 0 do 1 dla każdego 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

Ale chcemy liczb od 1 do 9, a nie od 0 do 8. Więc dodajemy 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

To bardzo miłe, ale straciliśmy zera, które chcę, więc pomnożymy je przez oryginalną maskę po przekształceniu wszystkich dziewiątek w jedynki. Robię to poprzez sprawdzenie, czy wartość jest większa niż 1. To daje nam: (1&<*1+?).
Tutaj dzieje się kilka rzeczy:

  • Stworzyliśmy widelec, który pozwala nam spakować dużo pracy w bardzo niewiele postaci.
  • Związaliśmy ( &) 1 z <czasownikiem.

Tak więc wszystko razem (1&<*1+?)generuje liczby losowe i zeruje wszystkie liczby, które były generowane przez zera w oryginalnej siatce.

   (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

Następny kawałek to (moim zdaniem zresztą :-) sprytny kawałek.
Cut ;.czasownik ma formę, x u;._3 yktóra tnie dane wejściowe na pola opisane przez x, a następnie stosuje udo nich czasownik . W tym przypadku mamy 3 3(4&{++/*0=4&{)@,;._3.

  • 3 3Opisuje pola, które chcemy - 3x3.
  • (4&{++/*0=4&{)@,Jest pociąg czasownik, który opisuje to, co chcemy zrobić, aby każdym polu.

Aby zademonstrować ;.czasownik, użyję <do wyświetlenia każdego pola:

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

Niektóre rzeczy do zauważenia:

  • Pola pokrywają się - druga i trzecia kolumna w lewym górnym polu to pierwsza i druga kolumna po prawej stronie.
  • Istnieje 7x7 pudełek. Dlatego początkowo mieliśmy siatkę 9x9.
  • Każde miejsce, którego potrzebujemy, ma 0na środku pole.

Teraz musimy albo przekazać wartość na środku z powrotem (jeśli jest niezerowa), albo zsumować liczby w polu 3x3 (jeśli środek jest zerowy).
Aby to zrobić, potrzebujemy łatwego dostępu do centralnego numeru. ,pomaga tutaj. Okazuje siatkę 3x3 do listy 9 pozycji z numerem centrum pod numerem 4.
4&{użyje {wyciągnąć wartość środkową, a następnie porównać je z 0: 0=4&{. Zwraca 0lub 1za prawdziwe lub fałszywe, które następnie pomnożyć przez sumę +/. Jeśli w centrum było zero, mamy teraz wymaganą sumę. Jeśli tak nie było, mamy zero, więc na zakończenie dodajemy wartość środkową 4&{+.
To daje czasownikowi pociąg(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
źródło
Czy Twój jeden wiersz kodu to wszystko, w tym generowanie liczb losowych? Uspokój mnie. Trudno w to uwierzyć.
DavidC
Tak, choć trudno w to uwierzyć. Bit losowy jest wykonywany przez ?. Zmienię wyjaśnienie, aby odzwierciedlić najnowszą wersję.
Gareth,
@DavidCarraher Większość czasowników w J ma 1 lub 2 znaki, więc 47 znaków może spakować dużo pracy.
Gareth,
Cięcie pudełka 9x9 na zachodzące na siebie kwadraty 7x7 to zdecydowanie sprytny kawałek. W mniej niż 10 minut udało mi się go zastosować, aby pobić moją obecną implementację GolfScript o 7,5%.
Peter Taylor
No cóż, wygląda na to, że wróciło do deski kreślarskiej.
Zmienność
5

Ruby (135 znaków)

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}

Próbka wyjściowa

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  

Awaria

To nie jest zbyt oczywiste, jak to działa, więc oto szybki podział. UWAGA: Prawdopodobnie możesz pominąć niektóre z tych kroków i szybciej przejść do krótszych wersji, ale myślę, że jest to wystarczająco edukacyjne, aby zobaczyć różne sposoby golenia znaków, szczególnie poprzez wykrywanie wzorców w literałach, aby zamieniać 2-cyfrowe liczby na 1-cyfrowe wersje .

Wersja naiwna

W przeciwieństwie do innych rozwiązań Ruby, które opierają się na dwuwymiarowej tablicy, możesz (ostatecznie) uzyskać krótszą wersję, zaczynając od tablicy jednowymiarowej i pracując z wartościami przesunięcia, ponieważ wzorce się powtarzają.

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

Kluczową zasadą jest to, że pracujemy na pozycjach indeksu 8, 10, 12, po prostu przesuniętych o wielokrotności 14. Pozycje 8, 10 i 12 są środkami sumowanych siatek 3x3. Na wyjściu próbki 34 to pozycja 8, 42 to pozycja 8 + 14 * 1 itd. Zastępujemy pozycję 8 34 pozycjami przesuniętymi od pozycji 8 o [-8,-7,-6,-1,1,6,7,8]- innymi słowy 34 = sum(ary[8-8], ary[8-7], ..., ary[8+8]). Ta sama zasada obowiązuje dla wszystkich wartości [8 + 14*i, 10 + 14*i, 12 + 14*i], ponieważ wzorzec się powtarza.

Optymalizacja

Po pierwsze, kilka szybkich optymalizacji:

  • Zamiast za każdym razem „ 3.times { ... }obliczać j + 14*i” pozycje [8,10,12,22,24,26,36,38,40].
  • offsetsTablica jest użyta tylko raz, aby zastąpić zmienną dosłownym.
  • Wymień do ... endsię {...}i przełączyć okolice drukowanie $> << foo. (Jest tu sztuczka z udziałem puts nili () == nil.)
  • Krótsze nazwy zmiennych.

Kod po tym ma 177 znaków:

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

Przy następnej redukcji zwróć uwagę, że injecttablica przesunięć nie musi być w porządku. Możemy mieć [-8,-7,-6,-1,1,6,7,8]albo inne zamówienie, ponieważ dodawanie jest przemienne.

Więc najpierw połącz pozytywne i negatywne [1,-1,6,-6,7,-7,8,-8].

Teraz możesz skrócić

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

do

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

To skutkuje

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

który ma 176 znaków.

Przesuń o 8 i przejdź do różnic

Dwuznakowe wartości literalne wydają się być możliwe do skrócenia, więc weź [8,10,12,22,24,26,36,38,40]i przenieś wszystko w dół 8, aktualizując jna początku pętli. (Należy pamiętać, że +=8unika się konieczności aktualizacji wartości przesunięcia 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)}

Jest to 179, co jest większe, ale j+=8faktycznie można je usunąć.

Pierwsza zmiana

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

do szeregu różnic:

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

i kumulatywnie dodaj te wartości do wartości początkowej j=8. To ostatecznie obejmie te same wartości. (Prawdopodobnie moglibyśmy przejść bezpośrednio do tego, zamiast przejść najpierw o 8).

Zauważ, że dodamy również wartość fikcyjną 9999na końcu tablicy różnic i dodamy jna końcu , a nie na początku pętli. Uzasadnieniem jest to, 2,2,10,2,2,10,2,2że okropnie zbliża się do bycia tymi samymi 3 liczbami powtarzanymi 3 razy, a obliczając j+differencena końcu pętli, ostateczna wartość 9999nie wpłynie na wynik, ponieważ nie ma a[j]wywołania, w którym jjest jakaś wartość ponad 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)}

Z tą tablicą różnic j+=8jest teraz po prostu j=8oczywiście, ponieważ w przeciwnym razie wielokrotnie dodawaliśmy 8zbyt wiele. Zmieniliśmy również zmienną blokową z jna l.

Ponieważ 9999element nie ma wpływu na wynik, możemy go zmienić 10i skrócić tablicę.

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

To jest 170 znaków.

Ale teraz j=8wygląda to trochę niezgrabnie i możesz uratować 2 postacie, przesuwając w [2,2,10]dół o 2, aby wygodnie uzyskać postać, 8której możesz użyć do przypisania. To też musi j+=lsię stać 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)}

To jest 169 znaków. Okrągły sposób wyciskania 7 znaków, ale jest fajny.

Ostatnie poprawki

values_atPołączenie jest rzeczywiście rodzaju zbędne i możemy inline takie Array#[]połączenie. Więc

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

staje się

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

Możesz również zauważyć, że flat_map+ j+e/j-e+ injectmożna zredukować do bardziej bezpośredniego sumowania z inicjałem 0w tablicy.

To daje ci 152 znaki:

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

Wreszcie:

  • map.with_indexmoże zostać each_slice.
  • Zmień podejście do drukowania.

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
źródło
Można wymienić eachz mapjednej bajt.
Jordan
3

Python, 132

To technicznie nie spełnia zasad, ponieważ ostatnie cyfry każdego numeru są wyrównane, a nie pierwsze. Ale pomyślałem, że i tak podzielę się:

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

Przykładowe dane wyjściowe:

[[ 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
źródło
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〛]

wynik

Dla ładniejszego wyjścia Column/@można go zastąpić TableForm@kosztem 2 znaków.

ssch
źródło
Bardzo, bardzo sprytny. Grid[ReplacePart[ g, {i_?EvenQ, j_?EvenQ} :> g[[s@i, s@j]]~Total~2 - g[[i, j]]]\[Transpose]]daje czystszy wynik i zapisuje kilka znaków, jeśli liczysz Transpozycja jako pojedynczy znak, który jest w Mathmatica. Btw, szablon OneLinerSubmission Wolfram liczy 106 znaków, 105 z transpozycją jednego znaku.
DavidC
@DavidCarraher Thanks. Liczba znaków wynika z niepotrzebnego znaku nowej linii i :>jest jednym symbolem, chociaż znajduje się w obszarze prywatnego użytku Unicode. Można nawet usunąć transpozycję, ponieważ zasada sumowania ważności obowiązuje nawet po transpozycji. Ale wydaje się, Gridże nie wyrównuje wpisów bez dalszych opcji (v8)
ssch
Gridwyśrodkowuje liczby w kolumnach. Technicznie nie spełniłoby to wyzwania, ale wygląda lepiej niż wyświetlenie listy w wyświetlanej tabeli.
DavidC
Bardzo dobrze. Po prostu spędzam dużo czasu, tworząc to samo, tyle że używałem Parti Tuples. Publikowanie wkrótce.
Mr.Wizard
Dzięki temu możesz uratować dwie postacie: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 znaków)

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

Uwaga: Zawiera dosłowną zakładkę, którą Markdown może złamać.

Sprytny kawałek należy do Garetha: zobacz jego rozwiązanie J.

Demo online

Peter Taylor
źródło
3

R: 114 znaków

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

W pierwszym wierszu utwórz tablicę 7 na 7 wypełnioną losowo wybranymi liczbami od 1 do 9 (równomierny rozkład z zastępowaniem, stąd r=Tskrót replace=TRUE). Drugi wiersz, oblicz sumy 3 na 3 siatki, odejmij środek i zastąp go wynikiem. Trzeci wiersz wypisuje wynikową siatkę (domyślnie kolumny macierzy i macierzy są wyrównane do prawej).

Przykładowe dane wyjściowe:

     [,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
źródło
2

J, 67 65 bajtów

Naiwne i pełne odpowiedzi rozwiązanie w J. To prosta realizacja zadania.

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

Najpierw tworzę tablicę liczb całkowitych 7 x 7 między 1 a 9. W rzeczywistości J? czasownik generuje liczby aż do argumentu, dlatego musimy zwiększać każdy element,>: w 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

Przygotowuję maskę do zerowania komórek nieparzystych wierszy / kolumn, pary indeksów nieparzystych wierszy / kolumn:

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

Czasownik z katalogu {łączy elementy z atomów znajdujących się na liście w ramkach

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

aby utworzyć katalog, tabelę 3x3 powyższych par

Następnie przygotowuję tabelę wskaźników wierszy / kolumn, które zostaną użyte do wyboru każdej z podtablic 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││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
└─────────────┴─────────────┴─────────────┘

Dla każdej pary w macierzy m tworzę parę trojaczków, wyśrodkowanych wokół każdej liczby m pary:

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

Te pary trojaczków są używane przez czasownik J From {, który może zaznaczyć wiele wierszy i kolumn jednocześnie. 0 1 2/2 3 4 oznacza, że ​​wybieram wiersze 0, 1 i 2 razem z kolumnami 2, 3 i 4, wybierając w ten sposób drugą podtablicę 3x3 u góry.

Na koniec mogę użyć tablicy 7x7 i masek do wykonania zadania: Najpierw używam m jako maski, aby ustawić odpowiednie elementy na 0:

0 m}a

Następnie biorę wszystkie pod-tablice 3x3 za pomocą s jako selektora i znajduję ich sumy:

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

Następnie ponownie umieszczam te liczby w tablicy początkowej.

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

Wypróbuj online!

Galen Iwanow
źródło
1

Ruby, 207

Najpierw przedstawię moje rozwiązanie (jak zawsze):

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
Klamka
źródło
1

Ruby, 150 znaków

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}

jeśli uzasadnienie lewego uzasadnienia jest właśnie takie, które ljustmusiałoby zostać zastosowane ... no nie. Uwielbiam możliwości formatowania Ruby.

Nie używać Array.new(7){...}. (0..6).map{...}jest zarówno krótszy, jak i bardziej czytelny, a Ty możesz przypisać zakres za darmo.

Linia nr 3 inspirowana rozwiązaniem Doorknob .

John Dvorak
źródło
1

GolfScript, 87 znaków

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

Tam jest za dużo zamków ... (patrz 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
źródło
1

J, 58/64/67 znaków

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

Chociaż specyfikacja wymaga wyrównania liczb do lewej, nie ma wymogu używania zapisu dziesiętnego, więc myślę, że jest to poprawny wynik:

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

Jeśli dopuszczalne jest wyrównanie do prawej zamiast wyrównania do lewej, mamy 58 znaków

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

J ":(format) ma trzy tryby formatowania:

  • wyrównane do prawej za pomocą n cyfr lub z zawijaniem (domyślny wyświetlacz)
  • wyrównany do lewej notacja naukowa z n cyframi i ogółem m znaków
  • wyświetlacz w pudełku z kurczeniem z wyrównaniem (lewy / środkowy / prawy) - (górny / środkowy / dolny) (poniżej 69 znaków)

Najbardziej gadatliwym, ale także najbardziej wszechstronnym i jedynym, który jest w stanie wygenerować wynik, jak w przykładzie, jest 8!:2formatowanie obce, które przyjmuje łańcuch formatujący jako lewy argument. Również 67 znaków :

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

Oto format pudełkowy:

 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
źródło
1

Perl, 117 znaków

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

Jest to jeden z tych skryptów Perla, w których wszystkie oprócz jednej pętli for zostały zwinięte w mapwywołania, dzięki czemu wszystko można zrobić w jednym poleceniu. Zmienne globalne również pojawiają się w tym dokumencie. Myślę, że próbuję tu powiedzieć, że ten program jest trochę obrzydliwy.

Czekaj, robi się coraz gorzej: w skrypcie jest znany błąd! Ma jednak mniej niż 1 na milion szansy na wyzwolenie, więc jeszcze nie udało mi się go naprawić.

chlebak
źródło
Nie przejmuj się nami, jaki jest błąd?
Bonus wskazuje pierwszą osobę, która to zauważy!
breadbox
1

Matematyka , 106/100

Zanim go zobaczyłem, wymyśliłem coś bardzo podobnego do kodu ssch. Pożyczam jego pomysł użycia Column. Tylko z 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

Ze znakami Unicode (używanymi przez 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
źródło
1

Excel VBA, 74 bajty

Natychmiastowa funkcja VBE, która wysyła do [B2:H9].

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

Przykładowe dane wyjściowe

wprowadź opis zdjęcia tutaj

Taylor Scott
źródło
1

PowerShell, 149 148 bajtów

-1 bajt dzięki @AdmBorkBork. To jest spoko!

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

Wyjaśnienie:

$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
źródło
1
Możesz pozbyć się bajtu (nowego wiersza), zamykając swoje $azadanie w pareny i przesuwając następny wiersz w górę, aby utworzyć jedną dużą linię -($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
AdmBorkBork
Nie. To nie działa. Tablica musi być wcześniej całkowicie wypełniona $a[$i+$_]. Oto dwa kroki. Miałem kilka prób kapsułkowania w jednej rurze. :)
mazzy
1
Nie działa, jeśli nie umieścisz parenów wokół zadania. Dzięki ($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))}), $ajest całkowicie wypełniona przed następnym przykład rurociągu. Powinien działać (przynajmniej dla mnie).
AdmBorkBork,
0

Mathematica 142 151 172 179

Kod

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)

Stosowanie

z

m8

DavidC
źródło
Masz 0s; zasady mówią 1-9
Klamka
Dzięki. Poprawiłem dane i zdjęcia. Funkcje pozostają niezmienione.
DavidC
Ponadto liczby nie są wyrównane, jak określono w pytaniu.
Klamka
Słownictwo Mathematiki (a ściślej naleganie na użycie dużych słów) staje się oczywiste.
DavidC
0

Julia 0,6 , 127 (89) bajtów

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)

Wypróbuj online!

89 bajtów przy użyciu natywnego wyświetlania, co może być dopuszczalne, jeśli można wydrukować dodatkowe wiersze:

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
źródło
0

Java 10, 262 260 248 239 bajtów

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 bajtów dzięki @ceilingcat .

Wyjaśnienie:

Wypróbuj tutaj.

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
źródło
@ceilingcat Thanks! Udało mi się zaoszczędzić jeszcze kilka bajtów varzamiast Stringi +=Math.random()*9+1;zamiast =(int)(Math.random()*9+1);. To naprawdę przydatne, aby odwiedzić wszystkie moje stare odpowiedzi, haha! : D
Kevin Cruijssen