"Matriz" de identidade N-dimensional

30

Dado um número inteiro positivo n, Nimprima a "matriz" de identidade dimensional, que é a N^Nmatriz com a 1qual todos os componentes dos índices são iguais ou 0não. N^Nsignifica N-por-N-por-N-por-...

1 -> [1]

2 -> [[1,0],[0,1]]

3 -> [[[1,0,0],[0,0,0],[0,0,0]],[[0,0,0],[0,1,0],[0,0,0]],[[0,0,0],[0,0,0],[0,0,1]]]

4 -> [[[[1,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]],[[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,1,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]],[[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]]],[[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]],[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,1]]]]

Por exemplo, se aé o 4dimensional identidade "matriz", em seguida, as únicas entradas com 1seria a[0][0][0][0], a[1][1][1][1], a[2][2][2][2], e a[3][3][3][3].

Isso é . A resposta mais curta em bytes vence. Aplicam-se brechas padrão .

Freira Furada
fonte
1
Relacionado , relacionado .
Leaky Nun
11
Aí vem a resposta do MATL com um built-in fazendo isso por você ...
caird coinheringaahing

Respostas:

9

Geléia , 8 bytes

×=¥þ’¡`Ṡ

Experimente online!

Ooh, parece que eu consigo superar @Dennis no seu próprio idioma novamente :-)

Esta é uma função de um argumento (porque o formato de saída padrão do Jelly para listas aninhadas é um pouco ambíguo, o que significa que provavelmente não atende às especificações como um programa completo).

Explicação

×=¥þ’¡`Ṡ
     ¡    Repeatedly apply the following operation,
    ’     {input-1} times in total:
   þ        For each element of the current value {perhaps made into a range}
      `     and of {the range from 1 to the} {input}:
 =            Compare corresponding elements, giving 0 for equal or 1 for unequal
× ¥           then multiply by one of the elements
       Ṡ  then replace each element with its sign

Para entender isso, é útil examinar as etapas intermediárias. Para uma entrada 3, obtemos as seguintes etapas intermediárias:

  1. [1,2,3](entrada, transformada em um intervalo implicitamente pelo þ)
  2. [[1,0,0],[0,2,0],[0,0,3]](faça uma tabela com [1,2,3], compare para obter igualdade [[1,0,0],[0,1,0],[0,0,1]]e depois multiplique por um dos valores que comparamos)
  3. [[[1,0,0],[0,0,0],[0,0,0]],[[0,0,0],[0,2,0],[0,0,0]],[[0,0,0],[0,0,0],[0,0,3]]] (a mesma ideia novamente)
  4. [[[1,0,0],[0,0,0],[0,0,0]],[[0,0,0],[0,1,0],[0,0,0]],[[0,0,0],[0,0,0],[0,0,1]]](substitua cada elemento pelo seu sinal usando )

Observe o fato de que a entrada começa unidimensional significa que temos que fazer um loop (entrada-1) vezes para adicionar dimensões (entrada-1), produzindo uma lista dimensional de entrada.

Curiosidade: este programa contém cinco rápidas seguidas ¥þ’¡`,. (Um rápido é um modificador para um "link", ou interno, usado para modificar seu comportamento ou combiná-lo com outro link.)


fonte
+ !, só porque você venceu Dennis em Jelly.
Zachary
7

Mathematica, 30 bytes

Array[Boole@*Equal,#~Table~#]&
ngenisis
fonte
1
@FryAmTheEggman um parâmetro inteiro como o segundo argumento Tableé uma adição recente. Mathics ainda precisa de uma lista Singleton lá: tio.run/##y00sychMLv7/P83WsagosTLaKT8/...
Martin Ender
1
@FryAmTheEggman Parece que você precisa alterá-lo Array[Boole@*Equal,#~Table~{#}]&para trabalhar em Matemática. Versões mais antigas do Mathematica não suportam um número inteiro como segundo argumento Table, e acho que o Mathics se baseia nisso.
Ngenisis
1
@MartinEnder beliscão, puxão, você me deve uma Coca-Cola :)
ngenisis
6

APL (Dyalog) , 10 bytes

1=≢∘∪¨⍳⍴⍨⎕

Experimente online!

1= [é] 1 igual a

 o número

 do

 elementos únicos

¨ em cada um

 os índices em uma matriz com as dimensões de

⍴⍨ a auto-remodelação ( N cópias de N ) de

 a entrada ( N ) [?]

Adão
fonte
5

Geléia , 9 bytes

ðṗE€ṁ+þ’¡

Experimente online!

Como funciona

Realizar a tarefa diretamente parece difícil (não encontrei uma maneira), mas construir matrizes com os mesmos números e matrizes da mesma forma é bastante fácil.

ðtorna a cadeia diádica e a entrada inteira n serve como argumento esquerdo e direito para a cadeia. É possível usar uma cadeia monádica, mas as regras de análise para díades economizam três bytes aqui (dois após a pesquisa ð).

O átomo de potência cartesiano , com o argumento esquerdo e direito igual a n , constrói a matriz de todos os vetores de comprimento n que consistem em elementos de [1, ..., n] , classificados lexicograficamente.

Quando n = 3 , isso gera

[[1, 1, 1], [1, 1, 2], [1, 1, 3], [1, 2, 1], [1, 2, 2], [1, 2, 3], [1, 3, 1], [1, 3, 2], [1, 3, 3], [2, 1, 1], [2, 1, 2], [2, 1, 3], [2, 2, 1], [2, 2, 2], [2, 2, 3], [2, 3, 1], [2, 3, 2], [2, 3, 3], [3, 1, 1], [3, 1, 2], [3, 1, 3], [3, 2, 1], [3, 2, 2], [3, 2, 3], [3, 3, 1], [3, 3, 2], [3, 3, 3]]

O igual a cada link rápido E€testa os elementos de todos os vetores construídos quanto à igualdade.

Quando n = 3 , obtemos

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

que são os elementos da matriz de identidade tridimensional, em uma matriz plana.

O link rápido diádico +þ’¡é chamado com argumento à esquerda e argumento à direita n . A ¡chamada rápida do átomo de decremento , que gera n-1 , chama o link rápido da tabela de adição n-1 vezes.

Inicialmente, os argumentos de são ambos n . Após cada chamada, o argumento da direita é substituído pelo da esquerda e o da esquerda é substituído pelo valor de retorno da chamada.

A tabela chama rapidamente o átomo de adição+ para cada elemento de seu argumento esquerdo e cada elemento de seu argumento direito, construindo uma tabela / matriz do valor de retorno. Os argumentos inteiros iniciais n são promovidos para os intervalos [1, ... n] .

Quando n = 3 , após a promoção, mas antes da primeira iteração, os dois argumentos são

[1, 2, 3]

Adicionar cada número inteiro nessa matriz a cada número inteiro nessa matriz gera

[[2, 3, 4], [3, 4, 5], [4, 5, 6]]

Na próxima invocação, adicionamos cada uma dessas matrizes aos números inteiros em [1, 2, 3] . A adição vetoriza (adicionar um número inteiro a uma matriz adiciona-o a cada elemento), então obtemos

[[[3, 4, 5], [4, 5, 6], [5, 6, 7]],
 [[4, 5, 6], [5, 6, 7], [6, 7, 8]],
 [[5, 6, 7], [6, 7, 8], [7, 8, 9]]]

Essa matriz tem o mesmo formato da matriz de identidade tridimensional, mas não os elementos corretos.

Por fim, o átomo do molde descarta as entradas inteiras do resultado para a direita e as substitui em ordem pelos elementos do resultado à esquerda.

Dennis
fonte
4

Python , 70 bytes

f=lambda n,l=[]:[f(n,l+[i])for i in(len(l)<n)*range(n)]or+(l==l[:1]*n)

Experimente online!

Uma solução recursiva. Pensando na matriz como uma lista de matrizes de uma dimensão menor, ele itera sobre essa lista para descer pela árvore. Ele lembra os índices escolhidos le, quando os níndices são escolhidos, atribuímos um 1ou, 0dependendo se eles são iguais.


Python 2 , 73 bytes

n=input();r=0
exec'r=eval(`[r]*n`);'*n+('n-=1;r'+'[n]'*n+'=1;')*n
print r

Experimente online!

Uma melhoria no método totalmente humano de criar uma matriz de zeros e depois atribuí- los à diagonal.


Python 2 , 88 bytes

n=input()
t=tuple(range(n))
print eval('['*n+'+(i0'+'==i%d'*n%t+')'+'for i%d in t]'*n%t)

Experimente online!

Algumas bobagens com eval, gerando uma lista aninhada e substituição no formato de string. A sequência a ser avaliada se parece com:

[[[+(i0==i0==i1==i2)for i0 in t]for i1 in t]for i2 in t]
xnor
fonte
4

Python 2 + NumPy , 80 72 70 bytes

Agora empatado com a melhor resposta Python!

from numpy import*
n=input()
a=zeros((n,)*n)
a[[range(n)]*n]=1
print a

Experimente online

Economizou 8 bytes graças a Andras Deak e 2 por officialaimm

mbomb007
fonte
2
Faça uso de indexação sofisticada: em a[[range(n)]*n]=1vez de seu exec.
Andras Deak
(Há realmente fill_diagonal(a,1)para esta finalidade, mas isso é um byte mais)
Andras Deak
1
+1 para a saída bonita. E não vejo o uso da variável i, que deve economizar 2 bytes.
officialaimm
3

Python 2 , 99 93 90 bytes

Agradeço ao Rod por alguma ajuda ainda maior que o fez funcionar e também eliminou 6 bytes! -3 bytes graças ao xnor.

n=input()
r=eval(`eval('['*n+'0'+']*n'*n)`)
for i in range(n):exec'r'+`[i]`*n+'=1'
print r

Experimente online!

totalmente humano
fonte
1
def/returnnunca é melhor do que input/print(no melhor cenário é igual), você também pode soltar o ()em ('[%d]'%i)reduzir para 93 bytes
Rod
1
'[%d]'%ipassa a ser o representante da string de [i].
xnor
2

JavaScript (ES6), 67 bytes

f=(n,d=n-1,i)=>[...Array(n)].map((_,j)=>d?f(n,d-1,j-i?n:j):j-i?0:1)

Explicação: ié usado para controlar se a célula está na diagonal principal ou não. Inicialmente, é indefinido; portanto, na primeira chamada recursiva, sempre passamos a primeira dimensão, enquanto nas chamadas recursivas subsequentes a transmitimos apenas se o índice de dimensão atual for igual a todas as dimensões anteriores, caso contrário, passamos um índice nque indica que todos as células recursivas devem ser zero.

Neil
fonte
2

Brainfuck , 61 bytes

>,[->+>+<<]>[-<<+>>]>-[->+.-<<<<[->+>+<<]>[-<+>]>[->>.<<]>]+.

Ungolfed

Os números após os colchetes angulares indicam a célula em que a cabeça acabou.

>,                   read n to 1
[->+>+<<]            move 1 to 2 and 3
>2[-<<+>>]>3         move 2 to 0 
                     (tape: n 0 0 n 0)
-[                   while cell 3 {
    -                  dec 3
    >4+.-<3            print \x1
    <<<0[->+>+<<]      move 0 to 1 and 2
    >1[-<+>]>2         move 1 to 0
                       (tape: 0 0 n rows_left 0)
    [                  while cell 2 {
        -                dec 2
        >>4.<<           print \x0
    ]>3                }
]                    }
+.                   print \x1

Experimente online!

A entrada é um número binário. Saída é uma matriz armazenada na ordem principal da linha.

Raio
fonte
Já existem alguns formatos de saída diferentes nas respostas, então estou assumindo que o único requisito é "alguma representação matricial padrão". Se precisar estar em um formato específico, modificarei o código de acordo.
22417 Ray
eu acho linha principal, neste caso particular ficaria exatamente como coluna-major
Octopus
@Octopus Na verdade, o programa determina se deve estar na ordem das linhas principais ou das colunas, com base no idioma em que o intérprete Brainfuck está escrito. O meu está escrito em C, então, naturalmente, gera a matriz na ordem das linhas principais. No entanto, se você usasse um intérprete escrito em Fortran ou MATLAB, ele detectaria isso e mudaria automaticamente para a ordem principal da coluna. (Se você usou um intérprete escrito em si Brainfuck, ele resolve a ambiguidade baseado na linguagem de seu editor de texto é escrito em.) :-)
Ray
2

R , 64 49 bytes

-15 bytes graças a Jarko Dubbeldam

x=array(0,rep(n<-scan(),n));x[seq(1,n^n,l=n)]=1;x

Lê de stdin e retorna uma matriz, imprimindo como matrizes. seqgera uma sequência uniformemente espaçada de 1para n^ncom comprimento l=n, que faz o truque bastante para indexar para onde os 1s vão.

Experimente online!

versão antiga:

n=scan();x=rep(0,n^n);x=array(x,rep(n,n));x[matrix(1:n,n,n)]=1;x

nde stdin; retorna uma matriz, imprimindo os resultados como matrizes. Eu lutei com isso por um tempo até ler os documentos para [, que indicam que uma matriz pode ser usada para indexar uma matriz, em que cada linha da matriz representa o conjunto de índices. Arrumado!

Experimente online!

Giuseppe
fonte
array(0, rep(n,n)funciona, então você não precisa fazer rep. Você também pode levar nadiante array(0, rep(n<-scan(),n)).
JAD
Além disso, x[seq(1,n^n,l=n)]=1é 1 byte mais curto.
JAD
@JarkoDubbeldam thank you! Agradável.
Giuseppe
1

Python 3 + numpy, 81 77 bytes

from numpy import*
f=lambda n:all([a==range(n)for a in indices((n,)*n)],0)+0

Não estou inteiramente certo de que os ajustes acima todas as diretrizes: ele retorna um ndarray com as propriedades dadas. Eu sei que funções anônimas geralmente são boas, mas um shell interativo realmente imprime

>>> f(2)
array([[1, 0],
       [0, 1]])

Se o cotão da matriz invalida o print()item acima, eu tenho que adicionar um para algo como 7 bytes adicionais.

Experimente online!

Andras Deak
fonte
1

Pitão, 14 bytes

ucGQtQms!t{d^U

Suíte de teste

Explicação:, ^Uque é implicitamente ^UQQ, onde Qestá a entrada, calcula todas as listas possíveis de elementos Q do intervalo 0 ... n-1. ms!t{dmapeia aqueles com todos os elementos iguais a 1 e o restante a 0. Isso fornece a saída achatada

ucGQtQ executa o seguinte, Q - 1 vezes: Pique a entrada em listas de tamanho Q.

isaacg
fonte
1

C # (.NET Core) , 166 bytes

n=>{var c=new int[n];int i=0,d;for(;i<n;c[i++]=n);var m=System.Array.CreateInstance(typeof(int),c);for(i=0;i<n;i++){for(d=0;d<n;c[d++]=i);m.SetValue(1,c);};return m;}

Experimente online!

No começo eu pensei que não poderia ser feito com uma expressão lambda em C # ... ^ __ ^ U

Charlie
fonte
1

Lisp comum, 147 133 bytes

(defun i(n)(flet((m(x)(fill(make-list n)x)))(let((a(make-array(m n):initial-element 0)))(dotimes(i n)(incf(apply #'aref a(m i))))a)))

Experimente online!

O cocô super longo e usual. 12 bytes reduzidos graças a @ceilingcat!

Explicação:

(defun i (n)
  (flet ((m (x) (fill (make-list n) x)))            ; function to build a list of n values x
    (let ((a (make-array (m n) :initial-element 0))); build the array with all 0
      (dotimes (i n)                                ; for i from 0 to n-1
        (incf (apply #'aref a (m i))))              ; add 1 to a[i]..[i] 
      a)))                                          ; return the array
Renzo
fonte
@ceilingcat, ops, houve um erro estúpido na versão golfed. Corrigido, obrigado!
Renzo
0

SOGL V0.12 , 22 bytes

.^κ.H/ 0* 1.H≤Οčr.H{.n

Experimente aqui!
Deixa a saída na pilha , visível no console. Se fosse permitido que os números na saída fossem seqüências de caracteres, o valor rpoderia ser removido.
Assim como um teste divertido de como o SOGL se sai em desafios, ele não foi feito completamente para: p

input: x
.^                      push  x^x
  κ                     subtract x    (x^x)-x
   .H/                  divide by x   ((x^x) - x)/x
       0*               get that many zeroes
          1             push "1"
           .H           push x-1
             ≤          pull the first item from the stack to the top
              Ο         encase (x-1 times the zeroes, separated, started and ended with 1s)
               č        chop to a char-array
                r       convert each character to a number
                 .H{    repeat x-1 times:
                    .n    in the top array, for each group of x contents, encase that in an array
dzaima
fonte
0

Clojure, 92 bytes

#(reduce(fn[v i](assoc-in v(repeat % i)1))(nth(iterate(fn[v](vec(repeat % v)))0)%)(range %))

É bom que assoc-in funcione também com vetores, não apenas com mapas de hash.

NikoNyrh
fonte