Построить матрицу идентичности


44

Задача очень проста. Учитывая целочисленный ввод n, выведите n x nединичную матрицу. Тождественная матрица - это та, которая имеет 1s, охватывающую от верхнего левого угла до нижнего правого. Вы напишите программу или функцию, которая будет возвращать или выводить построенную вами матрицу идентичности. Выходными данными могут быть двумерный массив или числа, разделенные пробелами / символами табуляции и переводами строки.

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

1: [[1]]
2: [[1, 0], [0, 1]]
3: [[1, 0, 0], [0, 1, 0], [0, 0, 1]]
4: [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]
5: [[1, 0, 0, 0, 0], [0, 1, 0, 0, 0], [0, 0, 1, 0, 0], [0, 0, 0, 1, 0], [0, 0, 0, 0, 1]]

1
===
1

2
===
1 0
0 1

3
===
1 0 0
0 1 0
0 0 1

etc.

Это , поэтому выигрывает самый короткий код в байтах.


1
Учитывая целое число n ... - Я предполагаю, что вы имеете в виду натуральное число?
Джонатан Фрех

Ответы:


26

MATL, 2 байта

Xy

Перевод моего октавского ответа.

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

4-байтовая версия без встроенных модулей (спасибо Луису Мендо):

:t!=
:     take input n and a generate row array [1,2,...n]
 t    duplicate
  !   zip
   =  thread compare over the result

7
Должно быть, было трудно перевести этот очень сложный код: D
flawr

11
@flawr Вы понятия не имеете. Это действительно мой шедевр.
спагетто


1
Теперь я понимаю, почему вы спрашивали! :-D
Луис Мендо

5
Без встроенных::t!=
Луис Мендо

20

TI-BASIC, 2 байта

identity(Ans

Интересный факт: самый короткий путь , чтобы получить список {N,N}является dim(identity(N.

Вот кратчайший путь без встроенного, в 8 байтов:

randM(Ans,Ans)^0

randM(создает случайную матрицу с записями всех целых чисел от -9 до 9 включительно (это звучит странно, потому что это так). Затем мы возьмем эту матрицу к 0-й степени.


1
« Это звучит странно специфично, потому что это « TI-BASIC странно. O_o
дверная ручка

Да, черт возьми. TI-BASIC. +1
bearacuda13

не самый короткий путь , чтобы получить список {N,N}, ммм, {N,N}?
Cyoce

1
@ Кайос Нет; dim(и identity(каждый байт, потому что TI-BASIC является токенизированным.
lirtosiast

19

Юлия, 9 3 байта

eye

Это просто встроенная функция, которая принимает целое число nи возвращает nxn Array{Float64,2}(т.е. двумерный массив). Назовите это как eye(n).

Обратите внимание, что представления этой формы являются приемлемыми в соответствии с этой политикой .


Я вижу что ты тут делал! Хороший!
Исмаэль Мигель

Это также работает в Math.JS
ATaco

16

APL, 5 байт

∘.=⍨⍳

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

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


14

Октава, 10 4 байта

@eye

Возвращает анонимную функцию, которая принимает число nи возвращает единичную матрицу.


@eyeдостаточно.
flawr

@flawr Спасибо, я знал, что есть способ сделать это, но я всегда забываю: P
спагетто

eyeпроизводит матрицу идентичности во многих / некоторых численно ориентированных языках.
flawr

Что делает @?
Cyoce

@Cyoce @- это «оператор дескриптора функции», он работает как a, lambdaа также как ссылка на конкретную функцию, например, @(x)x.^2это функция возведения в квадрат и @sqrtссылка на функцию квадратного корня. Вы можете прочитать больше об этом здесь
Джузеппе

12

R, 4 байта

diag

Когда задана матрица, diagвозвращает диагональ матрицы. Однако, когда задано целое число n, diag(n)возвращается единичная матрица.

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


12

Python 2, 42 байта

lambda n:zip(*[iter(([1]+[0]*n)*n)]*n)[:n]

Анонимная функция, производит вывод, как [(1, 0, 0), (0, 1, 0), (0, 0, 1)],

Во-первых, создает список ([1]+[0]*n)*n, который для n=3выглядит

[1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0]

Используя почтовый индекс / ИТЭР трюк zip(*[iter(_)]*n сделать группы nдает

[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)]

Обратите внимание, что 1каждый раз приходит по одному индексу, давая матрицу идентичности. Но есть дополнительная строка с нулем, которая удаляется с помощью [:n].


1
Черт, что трюк с zip / iter гениален
смотри

10

Желе, 4 байта

R=€R

Не использует встроенный. Попробуйте онлайн!

Как это работает

R=€R    Main link. Input: n

R       Range; yield [1, ..., n].
   R    Range; yield [1, ..., n].
 =€     Compare each.
        This compares each element of the left list with the right list, so it
        yields [1 = [1, ..., n], ..., n = [1, ..., n]], where comparison is
        performed on the integers.

25
Этот код недопустимо длинный.
flawr

5
@flawr В два раза длиннее самого короткого. Это действительно необычная встреча.
Райнер П.

1
@flawr Да, и не короче , чем J . ПРОВАЛ!
Адам

2
В современных версиях Jelly составляет два байта и высмеивает более длинные ответы.
Линн

@Lynn Это все равно вдвое дольше, чем самый короткий.
Адам

10

J, 4 байта

=@i.

Это функция, которая принимает целое число и возвращает матрицу.


Я думаю, что вы можете сделать это в 3:=i.
Сэм Эллиотт

@SamElliott, это не работает. Например, (=i.) 10=>0 0 0 0 0 0 0 0 0 0
Cyoce

9

Haskell, 43 37 байт

f n=[[0^abs(x-y)|y<-[1..n]]|x<-[1..n]]

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

Редактировать: отбросил несколько байтов благодаря Орьяну Йохансену


7
Вы можете обмануть fromEnumкак sum[1|x==y].
xnor

почти уверен, что вы можете удалить место вfromEnum (y==x)
Cyoce

@xnor На один байт короче этого 0^abs(x-y).
Орьян Йохансен

1
@xnor О, вы просто использовали 0^(x-y)^2другой ответ, даже короче.
Орджан Йохансен

@ ØrjanJohansen Да, увидев твой комментарий, было приятно выбрать время :)
xnor

8

Pyth, 7 байт

XRm0Q1Q

Попробуйте онлайн: демонстрация

Создание матрицы нулей и замена диагональных элементов на единицы.


Вы можете сохранить один байт, удалив финалQ
Джим

1
@jim Спасибо, но на самом деле это было бы запрещено. Функция (неявная буква Q в конце) была реализована после публикации заявки.
Якуб

7

JavaScript ES6, 68 62 52 байта

Сохранено 10 байтов благодаря аккуратному трюку от @Neil

x=>[...Array(x)].map((_,y,x)=>x.map((_,z)=>+(y==z)))

Попытка использовать другой подход, чем у @ Cᴏɴᴏʀ O'Bʀɪᴇɴ. Возможно, будет улучшено.


Это было именно то, что я написал, прежде чем прокрутить вниз, чтобы узнать, что вы меня победили.
Нил

Итак, в ответ на ваш вызов, я даю вам (задним числом) очевидную x=>[...Array(x)].map((_,y,x)=>x.map((_,z)=>+(y==z)))экономию в 10 байт.
Нил

@Neil Спасибо большое! Я упомяну, что это ваш трюк в ответе.
ETHproductions

x=>[...Array(x)].map((_,y,x)=>x.map(_=>+!y--))
l4m2

7

Сетчатка , 25

Благодарим @randomra и @Martin за дополнительный гольф.

\B.
 0
+`(.*) 0$
$0¶0 $1

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

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

Сетчатка, 34

.+
$0$*1
\B.
 0
+`(.*) 0$
$0¶0 $1

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


3
... Вау. Retina становится мощным языком не только для регулярных выражений.
ETHproductions

@ETHproductions да, хотя это ответ почти на все подстановки регулярных выражений. Единственная особенность - это использование $*0для замены числа n на n 0s.
Цифровая травма

6

Haskell, 54 байта

(#)=replicate
f n=map(\x->x#0++[1]++(n-x-1)#0)[0..n-1]

fвозвращает единичную матрицу для ввода n. Далеко не оптимально.


Вы можете сохранить несколько байтов, используя понимание списка вместо mapвызова.
Математическая

6

Луа, 77 75 65 байт

x,v=z.rep,io.read()for a=1,v do print(x(0,a-1)..'1'..x(0,v-a))end

Ну, я не уверен, что для этого лучше всего использовать lua с двухпериодной конкатенацией ... Но, эй, есть шанс. Я посмотрю, есть ли какие-либо улучшения, которые будут сделаны.

РЕДАКТИРОВАТЬ:

Я понял что-то случайно, что я нахожу довольно странным, но это работает.

В Lua все знают, что у вас есть возможность назначать функции переменным. Это одна из наиболее полезных функций CodeGolf.

Это значит вместо:

string.sub("50", 1, 1) -- = 5
string.sub("50", 2, 2) -- = 0
string.sub("40", 1, 1) -- = 4
string.sub("40", 2, 2) -- = 0

Ты можешь это сделать:

s = string.sub
s("50", 1, 1) -- = 5
s("50", 2, 2) -- = 0
s("40", 1, 1) -- = 4
s("40", 2, 2) -- = 0

Но подождите, Луа позволяет немного ООП. Так что вы могли бы даже сделать:

z=""
s = z.sub
s("50", 1, 1) -- = 5
s("50", 2, 2) -- = 0
s("40", 1, 1) -- = 4
s("40", 2, 2) -- = 0

Это будет работать так же хорошо и сокращать персонажей.

Теперь здесь начинается странная часть. Вам даже не нужно назначать строку в любой точке. Просто делаю:

s = z.sub
s("50", 1, 1) -- = 5
s("50", 2, 2) -- = 0
s("40", 1, 1) -- = 4
s("40", 2, 2) -- = 0

Буду работать.


Таким образом, вы можете визуально увидеть разницу, взгляните на результаты этого:

Использование string.sub (88 символов)

string.sub("50", 1, 1)string.sub("50", 2, 2)string.sub("40", 1, 1)string.sub("40", 2, 2)

Присвоение string.sub переменной (65 символов)

s=string.sub s("50", 1, 1)s("50", 2, 2)s("40", 1, 1)s("40", 2, 2)

Назначение string.sub с использованием подхода ООП (64 символа)

z=""s=z.sub s("50", 1, 1)s("50", 2, 2)s("40", 1, 1)s("40", 2, 2)

Назначение string.sub с использованием подхода .. nil? (60 символов)

s=z.sub s("50", 1, 1)s("50", 2, 2)s("40", 1, 1)s("40", 2, 2)

Если кто-то знает, почему это работает, мне было бы интересно.


Линия "z.rep" обрывается на шахте. Могу поспорить, что где-то должно быть az = ''? Более короткий вариант z = '' z.rep будет просто ('') .rep. Вы также можете использовать cmdline ... для чтения ввода и уменьшить количество пользователей до 57 следующим образом: z = '0' для i = 1, ... do print (z: rep (i-1) .. 1 ..z: rep (...- i)) end
thenumbernine

Я обнаружил, что кто-то предлагал ("") .rep раньше, но я не смог заставить его работать. Это всегда было бы ошибкой. Может быть, проблема в моем переводчике. Я изо всех сил пытаюсь найти какую-либо документацию по этому вводу командной строки, вы знаете, где это можно найти?
Skyl3r

6

Python 3, 48

Сохранено 1 байт благодаря sp3000.

Я люблю проблемы, которые я могу решить в одной строке. Довольно просто, построить строку из 1 и 0, равную длине переданного int. Выводит в виде 2d массива. Если вы завернете деталь после: in '\n'.join(), она будет довольно распечатана.

lambda x:[[0]*i+[1]+[0]*(x+~i)for i in range(x)]

2
x-i-1 -> x+~i
Sp3000

5

С, 59 или 59, 56 или 56

Две версии одинаковой длины.

3 байта сохранены благодаря предложению от Анатолия: (n+1)->~n

Итерирует iот n*n-1нуля. Печатает 1, если i% (n + 1) равно нулю, иначе 0. Затем печатает новую строку, если i%n= 0 в противном случае пробел.

i;f(n){for(i=n*n;i--;)printf(i%n?"%d ":"%d\n",!(i%~n));}

i;f(n){for(i=n*n;i--;)printf("%d%c",!(i%~n),i%n?32:10);}

1
n+1слишком скучно Используйте ~nвместо этого!
Анатолий

Благодарность! Я должен был это заметить, потому что это произошло со мной, когда я посмотрел на вызов NBZ сегодня.
Уровень Река Сент-

Я не слишком знаком с C. Что делает i;?
Cyoce

@Cyoce i;просто объявляет переменную i. В C вы всегда должны объявлять переменную перед ее использованием, указав тип, чтобы компилятор знал, сколько памяти выделить. С помощью компилятора GCC, если вы не укажете тип, он должен быть int.
Уровень Река St

1
Вы можете снять еще 1 байт со второго, так как вкладки разрешены, вы можете заменить 32 на 9.
Биджан,

5

Мата, 4 байта

I(3)

Выход

[symmetric]
       1   2   3
    +-------------+
  1 |  1          |
  2 |  0   1      |
  3 |  0   0   1  |
    +-------------+

Mata - это матричный язык программирования, доступный в статистическом пакете Stata. I (n) создает единичную матрицу размера n * n


5
Добро пожаловать в Программирование Пазлов и Code Golf Stack Exchange. Это хороший ответ; (б) использование встроенных модулей отлично подходит для игры в гольф. Я заметил, что ваш ответ на самом деле составляет 1 байт:, Iа остальные 3 байта просто вызывают функцию. Это сделало бы ваш ответ одним из самых низких в этой задаче! :-)
wizzwizz4


4

Pyth, 8 байт

mmsqdkQQ

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


1
Я должен сказать, что весьма необычно, что ответ
Pyth в

Хм, это было лучшее, что я смог получить, это выглядит на 100% корректно, но я нашел, qRRQQчто, кажется, работает, кроме вас Trueи Falseвместо, 1и 0, однако, исправление этого afaik требует использования трех байтов, для sMMкоторых не помогает ...
FryAmTheEggman

@FryAmTheEggman Я также нашел qRRQQ. Я пробовал ряд других программ, и ни одна из них не была короче.
lirtosiast

4

Python 3.5 с NumPy - 57 49 30 байт

import numpy
numpy.identity

NumPy.identity принимает целое число n и возвращает единичную матрицу n. Этот ответ допустим с помощью этой политики .


4
На самом деле я считаю, import numpy\nnumpy.identityчто это законный ответ .
FryAmTheEggman

Спасибо за подсказку @MorganThrapp! И @FryAmTheEggman, ты имеешь в виду, что мой ответ может быть просто import numpy\nnumpy.identity()30 байтов?
linkian209

Я так запутался в \ nnumpy lol ... Это также будет верно, @FryAmTheEggman, нет? from numpy import identity, 26 байтов.
Огадай,

Кроме того, смотрите мой ответ что-то похожее
Ogaday

@ Сегодня я не думаю, что это правильно, строка, которую вы дали, не оценивает функцию. Вам нужно будет это сделать from numpy import identidy\nidentity(в этом случае *вместо конкретной встроенной
функции



4

Japt, 14 12 10 байт

Uo £Z®¥X|0

Проверьте это онлайн! Примечание: в этой версии есть несколько дополнительных байтов, чтобы красиво распечатать вывод.

Uo £Z®¥X|0    // Implicit: U = input integer
Uo £          // Create the range [0..U). Map each item X and the full array Z to:
    Z®        //  Take the full array Z, and map each item Z to:
      ¥X|0    //   (X == Z) converted to a number. 1 for equal, 0 for non-equal.
              // Implicit: output result of last expression


3

К 7 байт

t=\:t:!

Возьмем произведение на равенство двух векторов, содержащих [0, n).

В бою:

  t=\:t:!3
(1 0 0
 0 1 0
 0 0 1)
  t=\:t:!5
(1 0 0 0 0
 0 1 0 0 0
 0 0 1 0 0
 0 0 0 1 0
 0 0 0 0 1)

3

Java, 60 байт

n->{int[][]i=new int[n][n];for(;n-->0;)i[n][n]=1;return i;};

Создает 2D-массив и заменяет элементы, в которых строка и столбец равны 1.


Вам не нужно добавлять конечную точку с запятой в счетчик байтов для лямбда-ответов Java.
Кевин Круйссен


3

Mathematica, 14 байтов

IdentityMatrix

Прецедент

IdentityMatrix[4]
(* {{1,0,0,0},{0,1,0,0},{0,0,1,0},{0,0,0,1}} *)

3

Perl, 39 33 байта

/$/,say map$`==$_|0,@%for@%=1..<>

Спасибо Ton Hospel за сохранение 6 байтов

Запуск с -Eperlrun:

$ echo 3 | perl -E'@%=1..<>;$a=$_,say map{$a==$_|0}@%for@%'
100
010
001

Гольф немного больше: /$/,say map$`==$_|0,@%for@%=1..<>или даже лучше, //,say map$'==$_|0,@%for@%=1..<>но вот так вы больше не можете поместить его в одинарные кавычки
Тон Хоспел

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