Иллюстрируйте квадрат бинома


28

Учитывая (любыми средствами) два разных натуральных числа (любого разумного размера), выведите (любыми средствами) квадрат их суммы, как в примерах ниже:

Учитывая 4 и 3, вывод:

12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

Учитывая 1 и 3, вывод:

3 9 9 9
3 9 9 9
3 9 9 9
1 3 3 3

Пробелы могут варьироваться в пределах разумного, но столбцы должны быть выровнены по левому краю, выровнены по правому краю или (псевдо) центрированы.

Завершающий перевод строки хорош, но стандартные лазейки - нет.

Это поэтому включите заголовок, как # LanguageName, 123в вашем ответе, где число - это символы (байты для языков, которые не основаны на тексте). Упаковка кода в большие символы Unicode не допускается.


Бонус: -3, если ваш код выводит только один квадрат, когда одно из чисел равно 0; например, учитывая 0 и 3, вывод:

9 9 9
9 9 9
9 9 9

какое максимальное значение вводимых чисел? Спасибо.
Дон

1
@donbright Нет искусственного ограничения. Единственный предел - это то, что ваш компьютер и язык могут обрабатывать, когда дело доходит до представления, вычислений (с выбранным вами алгоритмом) и результата. Потенциально, современный компьютер, оснащенный принтером, который принимает данные построчно, не будет иметь практически никаких ограничений ... :-)
Adám

Является ли ориентация квадрата заданной или мы можем повернуть его на 90 градусов?
Джон Дворжак

1
Почему же бонус за 0 значений? Каким был бы ожидаемый результат, если бы не один квадрат?
Март Хо

@MarchHo Вот почему бонус такой маленький. Тем не менее, некоторые языки не могут обрабатывать пустые массивы.
Адам

Ответы:


14

J 9 байт - 3 = 6

#~@|.*/#~

Вдохновленный ответом APL @ NBZ , обыгравшимся @randomra. Это определяет глагол, который принимает массив чисел. Используется следующим образом:

   (#~@|.*/#~) 4 3
12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

Я также требую 3-байтовый бонус, так как ввод 0 производит субматрицы нулевого размера:

   (#~@|.*/#~) 4 0
16 16 16 16
16 16 16 16
16 16 16 16
16 16 16 16
   (#~@|.*/#~) 0 3
9 9 9
9 9 9
9 9 9

объяснение

У J есть определенное преимущество в этом вызове. Помимо проблем с манипулированием массивами на завтрак, он печатает 2D-матрицы в правильном формате по умолчанию.

       #~  Replicate each number n in input n times
#~@|.      The same for reversed input
     */    Compute their multiplication table

Это заставляет меня чувствовать себя как дома.
Адам

3
Это решение выглядит как неясная вариация table flipperсмайлика ASCII (╯ ° □ °) ╯︵ ┻━┻
Пит ТНТ,

10

Октава, 45 байт - 3 = 42

s=@(m,n)[a=ones(n,1)*n;b=ones(m,1)*m].*[b;a]'

объяснение

Это создает два вектора (предположим m = 4и n = 3):

ones(n, 1)создает массив размером один n x 1, поэтому умножим их на n:

ones(n, 1) * n => [3 3 3]' (where ' is transpose... n x 1 is a column vector)

a = [3 3 3  4 4 4 4]'   %// a is a column vector
b = [4 4 4 4  3 3 3]    %// b is a row vector

Затем векторы умножаются поэлементно, с автоматическим расширением широковещания, так что векторы из 7 элементов создают матрицу из 7х7 элементов:

    [3] .* [4 4 4 4 3 3 3]
    [3]
    [3]
    [4]
    [4]
    [4]
    [4]

Например, умножение первой строки aна bдает:

    [3] .* [4 4 4 4 3 3 3] = [12 12 12 12  9  9  9]

И аналогично для остальных рядов a.

Выход:

>> s(4,3)
ans =

   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12

>> s(3,0)
ans =

   9   9   9
   9   9   9
   9   9   9

Вы можете попробовать это здесь на Ideone


Вы можете удалить s=. У нас есть соглашение, что анонимные функции / лямбды не должны храниться в переменной.
Flawr

6
@ flawr но тогда ответ не будет 42 ...
мензурка

OK.
адам

9

Дьялог АПЛ , 10-3 = 7

Вдохновлен * этим ответом, где аргументы реплицируются, а затем используются в таблице умножения:

⊖∘.×⍨(/⍨⎕)

Вызывает prompt ( ⎕:) и оценивает любое введенное выражение. (По соображениям безопасности, это не работает на TryAPL но он работает на NGN / APL .)
/⍨Репликация свой аргумент сам раз ( /⍨4 33 3 3 4 4 4 4)
∘.×⍨Создает таблицу умножения.
Переворачивает с ног на голову.

Это работает на любой длине ввода (ввод с отступом 6 пробелов, вывод на левом поле):

      ⊖∘.×⍨(/⍨⎕)
⎕:
      ⍬      ⍝ Empty list (the square of nothing)
      ⊖∘.×⍨(/⍨⎕)
⎕:
      0      ⍝ 0​² = 0
      ⊖∘.×⍨(/⍨⎕)
⎕:
      0 1      ⍝ (0+1)​² = 1²
1
      ⊖∘.×⍨(/⍨⎕)
⎕:
      2 3      ⍝ (2+3)​² = 2² + 3²
6 6 9 9 9
6 6 9 9 9
6 6 9 9 9
4 4 6 6 6
4 4 6 6 6
      ⊖∘.×⍨(/⍨⎕)
⎕:
      1 2 3      ⍝ (1+2+3)​² = 1² + 2(1×2) + 2(1×3) + 2² + 2(2×3) + 3²
3 6 6 9 9 9
3 6 6 9 9 9
3 6 6 9 9 9
2 4 4 6 6 6
2 4 4 6 6 6
1 2 2 3 3 3
      ⊖∘.×⍨(/⍨⎕)
⎕:
      ⍳4    ⍝ Integers 1 through 4
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
3 6 6  9  9  9 12 12 12 12
3 6 6  9  9  9 12 12 12 12
3 6 6  9  9  9 12 12 12 12
2 4 4  6  6  6  8  8  8  8
2 4 4  6  6  6  8  8  8  8
1 2 2  3  3  3  4  4  4  4

* Изначально я имел в виду другое решение: каждый прямоугольник создается отдельно путем создания таблицы умножения для каждой комбинации двух аргументов. Затем четыре квадрата соединяются по вертикали и горизонтали. Это выглядит так:

,/⍪⌿⊖∘.(,⍴×)⍨⎕

Подскажите, как указано выше.
,⍴×<Объедините ( ,) аргументы и используйте их для формирования ( ) прямоугольника, заполненного их произведением ( ×).
∘.(... )⍨Создайте таблицу, в которой каждая ячейка соответствует тому, что указано в (... )
Отразить по вертикали.
⍪⌿Объедините ячейки по вертикали.
,/Объединить клетки по горизонтали.


1
Ницца! Та же идея в J с равным счетом:(|.*/])@#~
Zgarb

@Zgarb Обнови свой ответ и поставь сноску, как у меня. J заслуживает этого!
Адам

7

R 31 - 3 = 28

rev(b<-rep(a<-scan(),a))%*%t(b)

Объяснение:

           a<-scan()            # take numeric input and store as vector a
    b<-rep(         ,a)         # repeat each numeric input by itself and store as vector b
rev(                   )        # the reverse of vector b
                        %*%     # matrix multiplication
                           t(b) # the transposed of vector b

Это также работает для более чем двух номеров. Например, вывод для (5,3,2) выглядит так:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]   10   10   10   10   10    6    6    6    4     4
 [2,]   10   10   10   10   10    6    6    6    4     4
 [3,]   15   15   15   15   15    9    9    9    6     6
 [4,]   15   15   15   15   15    9    9    9    6     6
 [5,]   15   15   15   15   15    9    9    9    6     6
 [6,]   25   25   25   25   25   15   15   15   10    10
 [7,]   25   25   25   25   25   15   15   15   10    10
 [8,]   25   25   25   25   25   15   15   15   10    10
 [9,]   25   25   25   25   25   15   15   15   10    10
[10,]   25   25   25   25   25   15   15   15   10    10

Вы, вероятно, должны будете обернуть это в catили writeдля того, чтобы это было правильным ответом.
Дэвид Аренбург

@ ДавидАренбург Я не понимаю, почему? Там написано "Вывод (любыми средствами)". Мне потребовалось только одно средство для вывода, что ставит меня в соответствие с требованиями.
freekvd

Да, может быть, вы правы. Не уверен, что они имеют в виду.
Дэвид Аренбург

@DavidArenburg Да, все в порядке. Это проблема с данными / текстом, а не проблема ввода / вывода.
Адам

5

Haskell, 153 125 байт - 3 = 122

(#)=replicate
d=length.show
y%x=unlines$(>>= \n->(1+d(x*x+y*y)-d n)#' '++show n)<$>x#(y#(x*y)++x#(x*x))++y#(y#(y*y)++x#(x*y))

Половина кода предназначена для форматирования вывода. Это работает для произвольных больших целых чисел. Пример вывода:

> putStrLn $ 4 % 3
12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

> putStrLn $ 6 % 0
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36

Иногда между числами есть дополнительный пробел, потому что я вычисляю необходимое пространство , например, x*x+y*yвместоmax (x*x) (y*y)

> putStrLn $ 2 % 3
  6  6  9  9  9
  6  6  9  9  9
  6  6  9  9  9
  4  4  6  6  6
  4  4  6  6  6

Но это не более одного пробела.


4

Mathematica 56-3 = 53

Обновление : я добавил второй метод, точно такого же размера кода, который использует именованную функцию. Он использует Arrayскорее, чем, Tableно следует той же логике. (Увидеть ниже.)

Способ 1

Это составляет таблицу продуктов, факторы которой зависят от строки, значения столбца. Пара чисел вводится как список целых чисел. Анонимные функции, такие как следующие, наиболее полезны, если они используются в программе только один раз. В противном случае имеет смысл использовать именованную функцию.

Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&

Каждый фактор является оператором If-then:

  • If[r>#2,#,#2] означает «Если номер строки больше, чем второй вход, используйте первый вход в качестве коэффициента, в противном случае используйте второй вход.
  • If[c>#,#2,#] означает «Если номер столбца больше, чем первый вход, используйте второй вход в качестве коэффициента, в противном случае используйте первый вход.

Пример 1

 Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&@@{5,3}

EX1


Пример 2

Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&@@{0,3}

ех2


Метод 2 (также 56-3 = 53)

Это работает аналогично методу 1. Но при вызове требуется меньше кода. И ячейки являются адресуемыми, в отличие от ячеек в таблице. Этот метод лучше использовать, если функция будет использоваться более одного раза.

a_~f~b_:=Grid@Array[If[#>a,a,b]If[#2>a,b,a]&,{a+b,a+b}]

Приведенные выше примеры производятся следующим образом:

Пример 1:

f[4,3]

Пример 2:

f[0,3]

1
Это гениально. С помощью этого метода я могу уменьшить свое собственное решение на 4 символа.
Адам

Спасибо. Я только что понял, что такой же подход работает с именованной функцией. См. Метод 2 выше.
DavidC

4

Октава, 34 - 3 = 31

@(a)rot90(b=repelems(a,[1,2;a]))*b

Примеры:

octave:1> f = @(a)rot90(b=repelems(a,[1,2;a]))*b;
octave:2> f([4,3])
ans =

   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12

octave:3> f([0,3])
ans =

   9   9   9
   9   9   9
   9   9   9

Ух, я понятия не имел, что repelemsсуществует. Потрясающе!
стакан

4

CJam, 27 байтов - 3 = 24

q:L~_]ze~_ff{*sL,2*Se[}W%N*

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

Проверьте это здесь.

объяснение

q:L    e# Read the input and store it in L.
~_     e# Evaluate the input, pushing [A B] onto the stack and duplicate it.
]z     e# Wrap both in an array and transpose it to get [[A A] [B B]].
e~     e# Run-length decode, getting A copies of A and B copies of B.
_ff{   e# Double map over each pair of entries in this new array...
  *s   e#   Multiply the two values.
  L,2* e#   Push twice the length of the input string.
  Se[  e#   Pad the result to this width with spaces (from the left).
}
W%     e# Reverse the resulting matrix to get the correct orientation.
N*     e# Join the rows with linefeed characters.

Хорошо, но что вызывает столько пустого пространства и что нужно для его уменьшения?
Адам

1
@NBZ Самый короткий способ, который я нашел до сих пор, чтобы вычислить надежную верхнюю границу ширины ячейки, состоит в том, чтобы использовать вдвое большую длину входной строки (потому что большее число в квадрате не будет иметь в два раза больше цифр, чем число сам). Конечно, я мог бы вычислить фактическую сумму, необходимую на основе полученных чисел, но это было бы немного дольше.
Мартин Эндер

4

Функция C (с использованием glibc), 122 байта - 3 = 119

В основном простая реализация с 2 циклами. Я ожидаю, что есть некоторые возможности для игры в гольф, которые я упустил здесь:

f(n,m,x,y){for(x=0;x<n+m;x+=puts(""))for(y=0;y<n+m;y++)printf(" %*d",snprintf(0,0,"%d",n>m?n*n:m*m),(x<m?m:n)*(y<n?n:m));}

Входные данные передаются в первых двух параметрах функции, остальные два являются пустышками. Столбцы выровнены по правому краю.

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

В полной программе:

f(n,m,x,y){for(x=0;x<n+m;x+=puts(""))for(y=0;y<n+m;y++)printf(" %*d",snprintf(0,0,"%d",n>m?n*n:m*m),(x<m?m:n)*(y<n?n:m));}

int main (int argc, char **argv) {
    if (argc == 3) {
        f(atoi(argv[1]),atoi(argv[2]));
    }
}

Компилировать как gcc sqrbin.c -o sqrbin(или make sqrbin). Предупреждения можно смело игнорировать.

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

$ ./sqrbin 4 3
 12 12 12 12  9  9  9
 12 12 12 12  9  9  9
 12 12 12 12  9  9  9
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
$ ./sqrbin 4 0
 16 16 16 16
 16 16 16 16
 16 16 16 16
 16 16 16 16
$ 

Исходя из моего опыта, возвращаемое значение puts()зависит от машины. Это 10 на моем, например. Кроме того, вот совет: вы можете обычно сжимать два цикла в один, если вы условно увеличиваете счетчик во внешнем цикле. Мое решение демонстрирует, как это можно сделать.
xsot

@xsot Да, puts()код возврата гарантированно будет только + ve для успеха. Однако мое тестирование с использованием glibc, похоже, показывает, что возвращаемое значение - это число записанных байтов. Что касается консолидации цикла - да, я знаю об этом методе и попробовал это здесь, пока без сокращения в этом случае.
Цифровая травма

2

Рубин, (133 - 3) = 130 байтов

s=1
a=ARGV.map{|e|s*=(e=e.to_i);[e]*e}.flatten
s=s.to_s.size
a.reverse.each{|i|a.each{|j|print (i*j).to_s.rjust(s).ljust(s+3)};puts}

для 4,3

12   12   12   12    9    9    9   
12   12   12   12    9    9    9   
12   12   12   12    9    9    9   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12

для 1,3

3   9   9   9   
3   9   9   9   
3   9   9   9   
1   3   3   3

за 0,3

9   9   9   
9   9   9   
9   9   9

2
Добро пожаловать в PPCG! Я не думаю, что ваш отступ достаточен для больших чисел. Подумайте о наличии 1и большом числе, как 9999. Чем sполучится 4, так что вы дополняете до ширины, s+3 = 7но 9999^2нужно 8 цифр. Вы можете использовать 2*sвместо этого.
Мартин Эндер

2
Несмотря на это, вот несколько советов по игре в гольф: я не понимаю, зачем вам это нужно, rjustпрежде чем делать ljust. Вы можете сократить printдо $><<(и избавиться от места после него). ARGVимеет псевдоним $*. Вы можете избежать этого flatten, построив свой массив с помощью чего-то вроде этого: codegolf.stackexchange.com/a/19493/8478 . Кроме того, ответы только для функций определенно разрешены здесь (даже безымянные функции), так что функция может принимать целые числа в качестве входных данных, и вам не придется ничего делать .to_i.
Мартин Эндер

@ MartinBüttner, спасибо за советы.
Суровая Гупта

2

Python 2, 176 байт - 3 = 173

def g(m,n):
 y,x,z,l,f='y','x','z','l','%'+str(len(str(max(m*m,n*n))))+'s'
 d={y:m*n,x:n*n,z:m*m,l:'\n'}
 for i in map(lambda x:d[x],(y*m+x*n+l)*n+(z*m+y*n+l)*m): print f % i,

Это использует строковые функции Python для создания сетки символов, затем заменяет символы целыми числами и печатает форматированный вывод.


Интересный метод.
Адам

1

Матлаб, 58 - 3 = 55

Использование анонимной функции:

@(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)

Пример:

>> @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
ans = 
    @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
>> ans(4,3)
ans =
    12    12    12    12     9     9     9
    12    12    12    12     9     9     9
    12    12    12    12     9     9     9
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12

>> @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
ans = 
    @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
>> ans(0,3)
ans =
     9     9     9
     9     9     9
     9     9     9

(Старое решение) 59 - 3 = 56

Использование анонимной функции:

@(a,b)[b*a*ones(b,a) b^2*ones(b);a^2*ones(a) a*b*ones(a,b)]

1

C, (125 - 3) байта

i,j,a;main(b,s){for(sscanf(gets(s),"%d %d",&a,&b);j<a+b;)printf(++i>a+b?i=!++j,"\n":"%*d",strlen(s)*2,(i<a?a:b)*(j<b?b:a));}

Ввод принимается как два целых числа через пробел в одной строке. Каждая ячейка дополняется пробелами до двойной длины входной строки.


У меня возникли проблемы при получении этого для компиляции с GCC (4.8.4) ...
Don

1
Я проверил это на golf.shinh.org/check.rb, который использует пакет Debian gcc-4.6.1-2. Какие ошибки компиляции вы получаете?
xsot

извините, я попробовал еще раз, так как все в одной строке, и это сработало, ... но когда я бегу, у меня появляется ошибка. я ввел строку 2 3 и нажал клавишу возврата, и там написано «Ошибка сегментации (ядро сброшено)»
Дон

Извините, но я не знаю, почему это не сработает для вас. По крайней мере, вы все еще можете попробовать код на сайте, на который я
ссылался

1

Пиф, 39 - 3 = 36

Pyth не имеет встроенного матричного форматирования, что значительно увеличивает размер, так как приходится вручную дополнять выходные числа. Вот что я придумал.

JAQL*b]jdm.[`d\ l`eS^R2Jsm*d]*bdJj+yHyG

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


1

Блоки , 51 байт 52 62 82 87 (не конкурирующие)

::`+`1|U;{`*`1}|A;`+`1,0+`1={`1^2}|;0+`,`1+`={`^2}|

Ungolfed:

::
  ` + `1                    | Expand;
  {` * `1}                  | SetAll;
  ` + `1, 0 + `1 = {`1 ^ 2} | Set;
  0 + `, `1 + `  = {` ^ 2}  | Set

Попытайся

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.