«Matrice» d'identité à N dimensions


30

Étant donné un entier positif n, Nsortez la "matrice" d'identité -dimensionnelle, qui est le N^Ntableau 1où toutes les composantes des indices sont égales et 0autrement. N^Nsignifie N par N par N par N ...

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]]]]

Par exemple, si aest l' 4identité de dimension « matrice », alors les seules entrées avec 1seraient a[0][0][0][0], a[1][1][1][1], a[2][2][2][2]et a[3][3][3][3].

C'est du . La réponse la plus courte en octets gagne. Des échappatoires standard s'appliquent.



11
Voici la réponse MATL avec une fonction intégrée qui le fait pour vous ...
caird coinheringaahing

Réponses:



9

Gelée , 8 octets

×=¥þ’¡`Ṡ

Essayez-le en ligne!

Ooh, on dirait que je rejoue @Dennis dans sa propre langue :-)

Il s'agit d'une fonction à 1 argument (car le format de sortie par défaut de Jelly pour les listes imbriquées est un peu ambigu, ce qui signifie qu'il ne répond sans doute pas aux spécifications en tant que programme complet).

Explication

×=¥þ’¡`Ṡ
     ¡    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

Pour comprendre cela, il est utile de regarder les étapes intermédiaires. Pour une entrée de 3, nous obtenons les étapes intermédiaires suivantes:

  1. [1,2,3](entrée, transformée implicitement par le þ)
  2. [[1,0,0],[0,2,0],[0,0,3]](faire un tableau avec [1,2,3], comparer pour obtenir l'égalité [[1,0,0],[0,1,0],[0,0,1]], puis multiplier par l'une des valeurs que nous avons comparées)
  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]]] (encore la même idée)
  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]]](remplacez chaque élément par son signe en utilisant )

Notez que l'entrée commence unidimensionnelle signifie que nous devons boucler (entrée-1) fois pour ajouter (entrée-1) des dimensions, produisant une liste d'entrée-dimensionnelle.

Fun fait: ce programme contient cinq Quicks dans une rangée, ¥þ’¡`. (Un rapide est un modificateur d'un "lien", ou intégré, utilisé pour modifier son comportement ou le combiner avec un autre lien.)


+ !, juste parce que vous avez battu Dennis dans Jelly.
Zacharý

7

Mathematica, 30 octets

Array[Boole@*Equal,#~Table~#]&

1
@FryAmTheEggman un paramètre entier comme deuxième argument de Tableest un ajout récent. Les mathématiques ont encore besoin d'une liste de singleton là: tio.run/##y00sychMLv7/P83WsagosTLaKT8/…
Martin Ender

1
@FryAmTheEggman On dirait que vous devez le changer Array[Boole@*Equal,#~Table~{#}]&pour travailler sur les mathématiques. Les versions plus anciennes de Mathematica ne prennent pas en charge un entier comme deuxième argument Table, et je suppose que les mathématiques sont basées sur cela.
ngenisis

1
@MartinEnder Pinch, poke, tu me dois un coca :)
ngenisis

6

APL (Dyalog) , 10 octets

1=≢∘∪¨⍳⍴⍨⎕

Essayez-le en ligne!

1= [est] 1 égal à

 le nombre

 de

 éléments uniques

¨ Dans chacun de

 les indices dans un tableau avec les dimensions de

⍴⍨ l'auto-remodelage ( N exemplaires de N ) de

 l'entrée ( N ) [?]


5

Gelée , 9 octets

ðṗE€ṁ+þ’¡

Essayez-le en ligne!

Comment ça marche

La réalisation directe de la tâche semble difficile (je n'ai pas trouvé de moyen), mais la construction de tableaux de mêmes nombres et de tableaux de même forme est assez facile.

ðrend la chaîne dyadique, et l'entrée entière n sert à la fois d'argument gauche et droit pour la chaîne. Il est possible d'utiliser une chaîne monadique à la place, mais les règles d'analyse pour les chaînes dyadiques économisent ici trois octets (deux après avoir accoutumé pour ð).

L' atome de puissance cartésien , avec un argument gauche et droit égal à n , construit le tableau de tous les vecteurs de longueur n qui sont constitués d'éléments de [1, ..., n] , triés lexicographiquement.

Lorsque n = 3 , cela donne

[[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]]

L' égale chaque lien rapideE€ teste l' des éléments de tous les vecteurs construits.

Lorsque n = 3 , nous obtenons

[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]

qui sont les éléments de la matrice d'identité tridimensionnelle, dans un réseau plat.

Le lien rapide dyadique +þ’¡est appelé avec l'argument gauche et l'argument droit n . Le rapide ¡appelle l'atome de décrémentation , ce qui donne n-1 , puis appelle n-1 le lien rapide de la table d' ajout .

Initialement, les arguments de sont tous les deux n . Après chaque appel, l'argument de droite est remplacé par celui de gauche et celui de gauche est remplacé par la valeur de retour de l'appel.

Le tableau appelle rapidement l' atome d' ajout+ pour chaque élément de son argument de gauche et chaque élément de son argument de droite, construisant une table / matrice de la valeur de retour. Les arguments entiers initiaux n sont promus dans les plages [1, ... n] .

Lorsque n = 3 , après la promotion mais avant la première itération, les deux arguments sont

[1, 2, 3]

L'ajout de chaque entier de ce tableau à chaque entier de ce tableau donne

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

Dans l'invocation suivante, nous ajoutons chacun de ces tableaux aux entiers de [1, 2, 3] . L'addition vectorise (l'ajout d'un entier à un tableau l'ajoute à chaque élément), donc on obtient

[[[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]]]

Ce tableau a la même forme que la matrice d'identité tridimensionnelle, mais pas les éléments corrects.

Enfin, l' atome de moule supprime les entrées entières du résultat à droite et les remplace dans l'ordre par les éléments du résultat à gauche.


4

Python , 70 octets

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

Essayez-le en ligne!

Une solution récursive. En considérant la matrice comme une liste de matrices une dimension plus petite, elle parcourt cette liste pour descendre dans l'arbre. Il se souvient des indices sélectionnés l, et lorsque les nindices ont été sélectionnés, nous attribuons un 1ou 0selon qu'ils sont tous identiques.


Python 2 , 73 octets

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

Essayez-le en ligne!

Une amélioration par rapport à la méthode totalement humaine consistant à créer une matrice de zéros puis à les affecter à la diagonale.


Python 2 , 88 octets

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

Essayez-le en ligne!

Quelques absurdités avec eval, génération d'une liste imbriquée et substitution de format de chaîne. La chaîne à évaluer ressemble à:

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

4

Python 2 + NumPy , 80 72 70 octets

Maintenant à égalité avec la meilleure réponse Python!

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

Essayez-le en ligne

Enregistré 8 octets grâce à Andras Deak, et 2 par officialaimm


2
Utilisez l'indexation de fantaisie: a[[range(n)]*n]=1au lieu de votre exécutable.
Andras Deak

(Il y a en fait fill_diagonal(a,1)à cet effet, mais c'est un octet de plus)
Andras Deak

1
+1 pour la jolie sortie. Et, je ne vois pas l'utilisation de la variable i, qui devrait économiser 2 octets.
officialaimm

3

Python 2 , 99 93 90 octets

Merci à Rod pour certains aide encore plus qui a obtenu ce travail et aussi rasé 6 octets off! -3 octets grâce à xnor.

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

Essayez-le en ligne!


1
def/returnest jamais mieux que input/print(dans le meilleur scénario , il est égal), vous pouvez également déposer l' ()en ('[%d]'%i)réduisant à 93 octets
Rod

1
'[%d]'%ise trouve être le représentant de chaîne de [i].
xnor

2

JavaScript (ES6), 67 octets

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

Explication: ipermet de savoir si la cellule est sur la diagonale principale ou non. Initialement, il n'est pas défini, donc lors du premier appel récursif, nous passons toujours la première dimension, tandis que lors des appels récursifs suivants, nous ne la transmettons que si l'indice de dimension actuel est égal à toutes les dimensions précédentes, sinon nous passons un index nqui indique que tout les cellules récursives doivent être nulles.


2

Brainfuck , 61 octets

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

Non golfé

Les chiffres après les crochets indiquent la cellule sur laquelle se trouve la tête.

>,                   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

Essayez-le en ligne!

L'entrée est un nombre binaire. La sortie est une matrice stockée dans l'ordre des lignes principales.


Il y a déjà quelques formats de sortie différents dans les réponses, donc je suppose que la seule exigence est "une représentation matricielle standard". S'il doit être dans un format particulier, je modifierai le code en conséquence.
Ray

je suppose que la ligne principale dans ce cas particulier ressemblerait exactement à la colonne principale
Octopus

@Octopus En fait, le programme détermine s'il doit être dans l'ordre des lignes ou des colonnes selon la langue dans laquelle l'interpréteur Brainfuck est écrit. Le mien est écrit en C, donc il sort naturellement la matrice dans l'ordre des lignes. Cependant, si vous utilisiez un interpréteur écrit en Fortran ou MATLAB, il le détecterait et passerait automatiquement en ordre majeur de colonne. (Si vous avez utilisé un interpréteur écrit dans Brainfuck lui-même, cela résout l'ambiguïté en fonction de la langue dans laquelle votre éditeur de texte est écrit.) :-)
Ray

2

R , 64 49 octets

-15 octets grâce à Jarko Dubbeldam

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

Lit à partir de stdin et renvoie un tableau, imprimant sous forme de matrices. seqgénère une séquence régulièrement espacée de 1à n^navec la longueurl=n , ce qui fait très bien l'affaire pour indexer où vont les 1.

Essayez-le en ligne!

ancienne version:

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

Lit à npartir de stdin; renvoie un tableau, imprimant les résultats sous forme de matrices. J'ai lutté avec cela pendant un certain temps jusqu'à ce que je lise les documents pour [, qui indiquent qu'une matrice peut être utilisée pour indexer un tableau, où chaque ligne de la matrice représente l'ensemble des indices. Soigné!

Essayez-le en ligne!


array(0, rep(n,n)fonctionne, vous n'avez donc pas à faire rep. Vous pouvez ensuite également passer à ntravers array(0, rep(n<-scan(),n)).
JAD

En outre, x[seq(1,n^n,l=n)]=1est 1 octet plus court.
JAD

@JarkoDubbeldam merci! Joli.
Giuseppe


1

Python 3 + numpy, 81 77 octets

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

Je ne suis pas entièrement sûr que ce qui précède convient à toutes les directives: il renvoie un ndarray avec les propriétés données. Je sais que les fonctions anonymes sont généralement bien, mais un shell interactif s'imprimera

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

Si le fluff du tableau rend ce qui précède invalide, je dois ajouter un print()pour quelque chose comme 7 octets supplémentaires.

Essayez-le en ligne!


1

Pyth, 14 octets

ucGQtQms!t{d^U

Suite de tests

Explication:, ^Uqui est implicitement ^UQQ, où se Qtrouve l'entrée, calcule toutes les listes d'éléments Q possibles de la plage 0 ... n-1.ms!t{dmappe ceux dont tous les éléments sont égaux à 1 et les autres à 0. Cela donne la sortie aplatie

ucGQtQ exécute les opérations suivantes, Q - 1 fois: Coupez l'entrée dans des listes de taille Q.


1

C # (.NET Core) , 166 octets

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

Essayez-le en ligne!

Au début, je pensais que cela ne pouvait pas être fait avec une expression lambda en C # ... ^ __ ^ U


1

Lisp commun, 147133 octets

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

Essayez-le en ligne!

Le lisp super-long habituel. Réduction de 12 octets grâce à @ceilingcat!

Explication:

(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

@ceilingcat, ops, il y avait une erreur stupide dans la version golfée. Corrigé, merci!
Renzo

0

SOGL V0.12 , 22 octets

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

Essayez-le ici!
Laisse la sortie sur la pile , visible dans la console. Si les nombres dans la sortie étaient autorisés à être des chaînes, alors le rpourrait être supprimé.
Tout comme un test amusant de la façon dont SOGL fait dans les défis, il n'a pas été fait pour: 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

0

Clojure, 92 octets

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

Bien que l' assoc-in fonctionne également avec des vecteurs, pas seulement avec des cartes de hachage.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.