Создать сетку сумм


15

Создайте сетку 7 на 7, заполненную случайными числами. Однако в ячейках с нечетным номером строки и столбца (начиная с 0) необходимо использовать сумму окружающих ячеек. Вот небольшой пример с сеткой 3 на 3 (сумма-квадрат выделена жирным шрифтом):

2 2  2
2 16 2
2 2  2

А вот пример сетки 7 на 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

правила

  • Числа, которые не являются суммами, всегда должны быть между 1 и 9 включительно.

  • Сетка должна быть сгенерирована случайным образом. Для каждой не суммы каждая цифра должна иметь одинаковую вероятность появления, независимо от того, в какой ячейке она находится.

  • Числа должны быть выровнены. Это означает, что либо первая, либо последняя цифра каждого числа в столбце должна располагаться вертикально. (Вы можете предположить, что средние числа всегда будут состоять из двух цифр.)

  • Окружающие клетки включают диагонали. Следовательно, каждый квадрат суммы будет иметь восемь чисел, окружающих его, которые вы должны добавить.

  • Самый короткий код выигрывает, так как это .


3
Есть ли у быть первой цифрой , которая выстраивается? то есть это может быть последним?
Волатильность

@ Volatlity Я полагаю, правильное выравнивание будет работать. Отредактировано
дверная ручка

Что если в языке нет генератора случайных чисел?
Heimdall

Ответы:


14

APL, 53 49 43 42 40 39 36

Мне удалось воспроизвести J ;.в APL и использовать подход Гарета , сохранив 13 символов.

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

Образец прогона:

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

Объяснение:

  • ∘.∨⍨9⍴0 1 генерирует немного маски
  • ×∘?∘9¨ умножает каждый бит на случайное значение от 1 до 9 включительно, создавая замаскированную сетку случайных чисел.
  • 3,⌿3,/использует то, что можно описать только как хакерство, чтобы вернуть все 3 на 3 перекрывающихся поля в замаскированном массиве. Они также сглаживаются в процессе.
  • {×5⌷⍵:5⌷⍵⋄+/⍵}¨перебирает массив, присваивая каждый элемент . Для каждой итерации берется пятая (средняя, ​​помня, что индексирование APL основано на 1) и возвращает знак. В этом случае это эквивалентно тестированию, если число больше 0. Если это возвращает 1 (для истины), то вернуть этот элемент. В противном случае верните сумму элементов в сглаженном квадрате 3 на 3. Он использует :⋄троичный оператор, который является эквивалентом ?:во многих языках.

Ой-ой. Похоже, мне придется найти больше сбережений персонажей. : -S
Гарет

@ Хорошо, посмотри, что у нас здесь. Я вернулся в лидеры: P
волатильность

NOOOOOOOOOO !!!!!!! :-(
Гарет

13

J, 63 61 59 55 52 51 49 47 39 37 символов

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

Благодаря Волатильности за его сохранение 10 символов.

Пояснение (каждый шаг будет иметь разные случайные числа ...):

Генерация маски для генерации случайных чисел (использует $:

   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

Теперь у нас есть крюк . Это на самом деле счастливый случай, когда я сократил более раннюю версию. Он должен был быть транспонирован |:и ИЛИ +.с оригиналом. Это имело смысл, так как я использовал единицы и нули в то время, но теперь у меня есть девятки и нули. Так уж сложилось, что он работает так же, как и в смысле GCD +.. К счастью для меня. :-)

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

Итак, теперь, когда у нас есть сетка из 9 и 0, мы хотим сгенерировать несколько случайных чисел. ?генерирует случайное число от 0 до (но не включая) заданного числа. Получив список, он сгенерирует одно случайное число таким образом для каждого члена списка. Так что в этом случае он сгенерирует число от 0 до 8 для каждых 9 в таблице и число с плавающей запятой от 0 до 1 для каждого 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

Но нам нужны числа от 1 до 9, а не от 0 до 8. Поэтому мы добавляем 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

Это очень хорошо, но мы потеряли нули, которые я хочу, поэтому мы умножим их на исходную маску, превратив все девятки в единицы. Я делаю это, проверяя , если значение больше 1. Это дает нам: (1&<*1+?).
Здесь происходит несколько вещей:

  • Мы создали форк, который позволяет нам упаковать большую работу в очень мало персонажей.
  • Мы связали ( &) 1 с <глаголом.

Таким образом, все вместе (1&<*1+?)генерирует случайные числа и обнуляет все числа, которые были сгенерированы нулями в исходной сетке.

   (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

Следующий бит - это (на мой взгляд, в любом случае :-) умный бит.
Вырезанный ;.глагол имеет форму, x u;._3 yкоторая разрезает входные данные в поля, описанные с помощью x, и затем применяет глагол uк ним. В этом случае мы имеем 3 3(4&{++/*0=4&{)@,;._3.

  • 3 3Описывает коробки , которые мы хотим - 3x3.
  • Это (4&{++/*0=4&{)@,поезд глаголов, который описывает, что мы хотим сделать с каждой коробкой.

Чтобы продемонстрировать ;.глагол, я буду использовать, <чтобы показать каждую коробку:

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

Некоторые вещи, на которые стоит обратить внимание:

  • Коробки перекрываются - второй и третий столбцы в верхнем левом блоке являются первым и вторым в блоке справа от него.
  • Есть коробки 7х7. Вот почему у нас изначально была сетка 9x9.
  • Каждое место, которое нам требуется, имеет сумму 0в центре бокса.

Теперь нам просто нужно либо передать значение в центре назад (если оно не равно нулю), либо сложить числа в поле 3х3 (если центр равен нулю).
Для этого нам нужен легкий доступ к номеру центра. ,помогает здесь Это превращает 3х3 в список 9 пунктов с номером центра под номером 4.
4&{будет использовать , {чтобы вытащить значение центра , а затем сравнить его с 0: 0=4&{. Это возвращает 0или 1для истины или ложи, которые мы затем умножаем на сумму +/. Если в центре было ноль, то теперь у нас есть требуемая сумма. Если это не так, у нас есть ноль, поэтому, чтобы закончить, мы просто добавляем значение центра 4&{+.
Это дает поезд глагола(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

Ваша строка кода делает все это, в том числе генерирует случайные числа? Успокой меня. Просто в это трудно поверить.
DavidC

Да, как бы трудно ни было верить. Случайный бит делается с помощью ?. Я изменю объяснение, чтобы отразить новейшую версию.
Гарет

@DavidCarraher Большинство глаголов в J - это 1 или 2 символа, поэтому 47 символов могут вместить много работы.
Гарет

Разрезание коробки 9x9 на перекрывающиеся квадраты 7x7, безусловно, является умным кусочком. Менее чем за 10 минут я смог применить его, чтобы превзойти мою текущую реализацию GolfScript на 7,5%.
Питер Тейлор

Ну да ладно, похоже, что я снова за чертежной доской.
Волатильность

5

Рубин (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}

Образец вывода

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  

Сломать

Не слишком очевидно, как это работает, так что вот краткий анализ. НОТА: Вероятно, вы можете пропустить некоторые из этих шагов и перейти к более коротким версиям, но я думаю, что это достаточно познавательно, чтобы увидеть различные способы, которыми я сбрил символы, особенно, обнаруживая шаблоны в литералах, чтобы превратить двузначные числа в однозначные версии. ,

Наивная версия

В отличие от других решений Ruby, которые полагаются на двумерный массив, вы можете (в конечном итоге) получить более короткую версию, начав с одномерного массива и работая со значениями смещения, поскольку шаблоны повторяются.

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

Ключевой принцип здесь заключается в том, что мы работаем с индексными позициями 8, 10, 12, просто смещенными на множители 14. Позиции 8, 10 и 12 являются центрами сеток 3x3, которые мы суммируем. В примере вывода 34 - это позиция 8, 42 - это позиция 8 + 14 * 1 и т. Д. Мы заменяем позицию 8 на 34 позициями, смещенными от позиции 8 на [-8,-7,-6,-1,1,6,7,8]- другими словами 34 = sum(ary[8-8], ary[8-7], ..., ary[8+8]). Этот же принцип действует для всех значений [8 + 14*i, 10 + 14*i, 12 + 14*i], поскольку шаблон повторяется.

Оптимизация это

Сначала несколько быстрых оптимизаций:

  • Вместо того 3.times { ... }, чтобы и рассчитывать j + 14*iкаждый раз, «встроенные» позиции [8,10,12,22,24,26,36,38,40].
  • offsetsМассив используется один раз, поэтому замените переменную с буквальным.
  • Замените do ... endна {...}и переключите печать на $> << foo. (Здесь есть трюк с участием puts nilи() == nil .)
  • Более короткие имена переменных.

Код после этого 177 символов:

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

Для следующего сокращения обратите внимание, что injectмассив смещений не должен быть в порядке. Мы можем иметь [-8,-7,-6,-1,1,6,7,8]или другой порядок, так как сложение коммутативно.

Итак, сначала объедините плюсы и минусы, чтобы получить [1,-1,6,-6,7,-7,8,-8].

Теперь вы можете сократить

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

в

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

Это приводит к

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

что 176 символов.

Сдвиг на 8 и переход к различиям

Кажется, что двухсимвольные литеральные значения могут быть сокращены, поэтому возьмите [8,10,12,22,24,26,36,38,40]и сдвиньте все вниз 8, обновляя jв начале цикла. (Обратите внимание, что не +=8нужно обновлять значения смещения 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)}

Это 179, что больше, но на j+=8самом деле может быть удалено.

Первая смена

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

к множеству различий:

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

и кумулятивно добавить эти значения к исходному j=8. Это в конечном итоге охватит те же значения. (Возможно, мы могли бы сразу перейти к этому, вместо того, чтобы сначала перейти на 8).

Обратите внимание, что мы также добавим фиктивное значение 9999в конец массива различий и добавим jв конце , а не в начало цикла. Обоснование состоит в том, что 2,2,10,2,2,10,2,2выглядит очень похоже на то, что те же 3 числа повторяются 3 раза, и, вычисляя j+differenceв конце цикла, окончательное значение 9999фактически не повлияет на вывод, так как нет a[j]вызова, где jесть какое-то значение более 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)}

С этим массивом различий, j+=8теперь это просто j=8, конечно, поскольку в противном случае мы бы неоднократно добавляли 8слишком много. Мы также изменили переменную блока с jна l.

Таким образом, поскольку 9999элемент не влияет на вывод, мы можем изменить его 10и сократить массив.

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

Это 170 символов.

Но теперь j=8выглядит немного неуклюже, и вы можете сохранить 2 символа, сдвинув их [2,2,10]вниз на 2, чтобы удобно получить то, что 8вы можете использовать для назначения. Это тоже должно j+=lстать 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)}

Это 169 символов. Вокруг способ сжать 7 символов, но это аккуратно.

Финальные настройки

values_atВызов на самом деле своего рода излишними, и мы можем встраивать в Array#[]вызов. Так

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

становится

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

Кроме того, можно заметить , что flat_map+ j+e/j-e+ injectможет быть сведено к более прямому суммированию с начальным 0в массиве.

Это оставляет вас с 152 символами:

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

В заключение:

  • map.with_indexможет стать each_slice.
  • Измените подход к печати.

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}

Вы можете заменить eachс mapодного байта.
Иордания

3

Python, 132

Технически это не удовлетворяет правилам, потому что последние цифры каждого номера выровнены, а не первые. Но я думал, что поделюсь в любом случае:

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

Пример вывода:

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

3

Математика, 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〛]

результат

Для более красивого вывода Column/@можно заменить TableForm@на 2 символа.


Очень, очень умный. Grid[ReplacePart[ g, {i_?EvenQ, j_?EvenQ} :> g[[s@i, s@j]]~Total~2 - g[[i, j]]]\[Transpose]]дает более чистый вывод и сохраняет пару символов, если вы считаете Transpose как один символ, который есть в Mathmatica. Кстати, шаблон Wolfram's OneLinerSubmission насчитывал 106 символов, 105 с одним символом Transpose.
DavidC

@DavidCarraher Спасибо. Количество символов связано с ненужным переводом строки и :>является одним символом, хотя он находится в частной области юникода. Можно даже удалить транспонирование, поскольку правило суммирования справедливости сохраняется даже после транспонирования. Но, похоже Grid, не выравнивает записи без дополнительных опций (v8)
ssch

Gridцентрирует числа в столбцах. Технически это не решило бы проблему, но выглядит лучше, чем отображение списка в отображаемой таблице.
DavidC

Очень хорошо. Я просто провожу много времени, создавая то же самое, только я использовал Partи Tuples. Скоро
Мистер Волшебник,

Вы можете сохранить два символа с этим: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 символов)

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

NB Это содержит буквенную вкладку, которую Markdown может сломать.

Умный бит принадлежит Гарету: посмотрите его решение J.

Онлайн демо


3

R: 114 символов

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

Первая строка создает массив 7 на 7, заполненный случайно выбранными числами от 1 до 9 (равномерное распределение с заменой, следовательно, r=T расшифровка replace=TRUE). Во второй строке вычислите суммы 3 на 3, вычтите центр и замените его результатом. В третьей строке выведите итоговую сетку (по умолчанию столбцы матрицы и массива выровнены по правому краю).

Пример вывода:

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

2

J, 67 65 байт

Наивное и многословное решение в J. Это прямая реализация задачи.

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

Сначала я создаю массив целых чисел 7 x 7 между 1 и 9. На самом деле J? глагол генерирует числа с точностью до аргумента, поэтому нам нужно увеличивать каждый элемент,>: в 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

Я готовлю маску, которая будет использоваться для обнуления нечетных ячеек строки / столбца, пары нечетных индексов строки / столбца:

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

Глагол Catalog {объединяет элементы из атомов внутри упакованного списка

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

для формирования каталога, таблица 3х3 из пар выше

Затем я готовлю таблицу индексов строк / столбцов, которые будут использоваться для выбора каждого из подмассивов 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││
│└─────┴─────┘│└─────┴─────┘│└─────┴─────┘│
└─────────────┴─────────────┴─────────────┘

Для каждой пары в массиве m я делаю пару триплетов, центрированных вокруг каждого числа пары m:

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

Эти пары триплетов используются глаголом J From {, который может выбрать несколько строк и столбцов одновременно. 0 1 2/2 3 4 означает, что я выбираю строки 0, 1 и 2 вместе со столбцами 2, 3 и 4, таким образом выбирая второй подрешетку 3x3 сверху.

Наконец, я могу использовать массив 7x7 и маски для выполнения задачи: сначала я использую m в качестве маски, чтобы установить соответствующие элементы в 0:

0 m}a

Затем я беру все подмассивы 3x3, используя s в качестве селектора, и нахожу их суммы:

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

Затем я помещаю эти числа обратно в исходный массив.

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

Попробуйте онлайн!



1

Рубин, 207

Сначала я представлю свое решение (как я всегда делаю):

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

1

Рубин, 150 знаков

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}

если левое оправдание требует оправдания, ljustто оно должно быть использовано ... ну, нет. Я люблю возможности форматирования Руби.

Не используйте Array.new(7){...}. (0..6).map{...}и короче и более читабельным и вы получаете назначаемый диапазон бесплатно.

Линия № 3, вдохновленная решением Doorknob .


1

GolfScript, 87 символов

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

Там слишком много молний ... (см. Онлайн )

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

1

J, 58/64/67 знаков

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

Хотя спецификация требует, чтобы числа были выровнены по левому краю, нет необходимости использовать десятичную нотацию, поэтому я предполагаю, что это правильный вывод:

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

Если допустимо выравнивание по правому краю вместо выравнивания по левому краю, то мы получим 58 символов

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

J's ":(формат) имеет три режима форматирования:

  • выравнивание по правому краю с помощью n цифр или с использованием термоусадочной пленки (отображение по умолчанию)
  • выровненная по левому краю научная запись с n цифрами и m символами всего
  • упакованный в термоусадочную пленку дисплей с (левым / центральным / правым) - (верхний / средний / нижний) выравниванием (ниже, 69 символов)

Наиболее многословным, но также и наиболее универсальным, и единственным, способным произвести выходные данные в соответствии с примером, является 8!:2внешнее форматирование, которое принимает строку форматирования в качестве левого аргумента. Также 67 персонажей :

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

Вот формат в штучной упаковке:

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

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

1

Perl, 117 символов

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

Это один из тех сценариев Perl, где все циклы for, кроме одного, были объединены в map вызовы, так что все может быть сделано в одном выражении. Глобальные переменные также имеют некоторые важные появления в этом. Я думаю, что я пытаюсь сказать здесь, эта программа немного грубая.

Подождите, становится хуже: в скрипте есть известная ошибка! Однако вероятность его срабатывания составляет менее одного на миллион, так что я пока не удосужился его исправить.


Не держитесь за нас, что за ошибка?

Бонус указывает первому, кто его заметит!
хлебница

1

Mathematica , 106/100

Я придумал что-то очень похожее на код ssch, прежде чем увидел это. Я заимствую его идею использования Column. Только с 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

С символами Unicode (как используется ssch), 100 :

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

1

Excel VBA, 74 байта

VBE немедленная функция, которая выводит на [B2:H9].

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

Пример вывода

введите описание изображения здесь


1

Powershell, 149 148 байт

-1 байт благодаря @AdmBorkBork. Это круто!

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

Объяснение:

$i=-1                       # let $i store -1
($a=                        # let $a is array of random numbers with zero holes
    (,1*8+0,1*3)*3+,1*7|    # the one-dimension array equals
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
                            # 1 0 1 0 1 0 1
                            # 1 1 1 1 1 1 1
    %{                      # for each element
        $_*(1+(Random 9))   # multiply 0 or 1 element to random digit from 1 to 9
    }                       # now $a stores values like (* is a random digit from 1 to 9)
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
                            # * 0 * 0 * 0 *
                            # * * * * * * *
)|?{++$i;!$_                # calc index $i and passthru values == 0 only
}|%{                        # for each zero value cell with index $i
    6..8+1|%{               # offsets for the surrounding cells
                            #  .  .  .
                            #  .  x +1
                            # +6 +7 +8  
        $_,-$_              # add the mirror offsets 
                            # -8 -7 -6
                            # -1  x +1
                            # +6 +7 +8  
    }|%{                    # for each offset 
        $a[$i]+=$a[$i+$_]   # add surrounding values to the cell
    }
}
                            # display the $a
-join(
    $a|%{                   # for each value of $a
        if(!(++$i%7)){"`n"} # line break for each 7 cells
        '{0,3}'-f$_         # formatted value of $a with width = 3 char and align right
    }
)                           # join all values to string

1
Вы можете избавиться от байта (новой строки), инкапсулировав свое $aназначение в скобках и переместив следующую строку вверх, чтобы сделать одну большую строку -($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))})|?{++$i;!$_}|%{6..8+1|%{$_,-$_}|%{$a[$i]+=$a[$i+$_]}}
AdmBorkBork

Нет, это не работает Массив должен быть полностью заполнен раньше $a[$i+$_]. Итак, вот два шага. У меня было несколько попыток инкапсулировать в одну трубу. :)
Маззи

1
Это не сработает, если вы не ставите скобки вокруг задания. С ($a=(,1*8+0,1*3)*3+,1*7|%{$_*(1+(Random 9))}), $aполностью заполняется перед следующим экземпляром конвейера. Это должно работать (по крайней мере, для меня).
AdmBorkBork

0

Mathematica 142 151 172 179

Код

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)

использование

z

m8


У вас есть 0с; правила говорят 1-9
дверная ручка

Благодарю. Я исправил данные и фотографии. Функции остаются без изменений.
DavidC

Кроме того, цифры не выровнены, как указано в вопросе.
Дверная ручка

Многословность Mathematica (или, точнее, настойчивость в использовании громких слов) становится очевидной.
DavidC

0

Юлия 0,6 , 127 (89) байт

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)

Попробуйте онлайн!

89 байтов с использованием собственного отображения, что может быть допустимо, если можно напечатать дополнительные строки:

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

0

Java 10, 262 260 248 239 байт

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 байт благодаря @ceilingcat .

Объяснение:

Попробуй это здесь.

v->{                        // Method with empty unused parameter and String return-type
  int a[][]=new int[7][7],  //  Integer-matrix with 7x7 zeroes
      i=49,j,k;             //  Index integers (`i` starting at 49)
  for(;i-->0;)              //  Loop `i` in the range (49, 0]:
    a[i/7][j%7]+=Math.random()*9+1;
                            //   Fill the current cell with a random 1..9 integer
  var r="";                 //  Result-String, starting empty
  for(;++i<7;               //  Loop `i` in the range [0, 7):
      r+="\n")              //    After every iteration: append a new-line to the result
    for(j=0;j<7;            //   Inner loop `j` in the range [0, 7):
        r+=                 //     After every iteration: append the result-String with:
           (k=a[i][j])>9    //      If the current number has 2 digits,
           |j++%2<1?        //      or it's an even column (indices 0/2/4/6)
            k+" "           //       Append the current number appended with one space
           :                //      Else:
            k+"  ")         //       Append the current number appended with two spaces
      if(i*j%2>1)           //    If both indexes `i` and `j` are odd
        for(a[i][j]=k=0;    //     Reset both the current item and index `k` to 0
            k<9;k++)        //     Inner loop `k` in the range [0, 9):
          a[i][j]+=         //      Sum the item at location `i,j` with:
           k!=4?            //       If `k` is not 4 (the current item itself)
            a[i+k/3-1][j+k%3-1]
                            //        Sum it with the numbers surrounding it
           :                //       Else:
            0;              //        Leave it the same by adding 0
  return r;}                //  Return the result-String

@ceilingcat Спасибо! И я смог сохранить еще несколько байтов с varвместо Stringи +=Math.random()*9+1;вместо =(int)(Math.random()*9+1);. На самом деле это довольно полезно для вас, чтобы посетить все мои старые ответы, ха-ха! : D
Кевин Круйссен
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.