Sur les bords de l'hypercube

12

Votre travail consistera à écrire une fonction ou un programme, qui prendra un entier n>0en entrée et produira une liste des bords de l' hypercuben dimensionnel . Dans la théorie des graphes, une arête est définie comme un 2-tuple de sommets (ou coins, si vous préférez), qui sont connectés.

Exemple 1

Un hypercube à 1 dimension est une ligne et comporte deux sommets, que nous appellerons aet b.

entrez la description de l'image ici

Par conséquent, la sortie sera:

[[a, b]]

Exemple 2

L'hypercube (ou tesseract) à 4 dimensions se compose de 32 arêtes et son graphique ressemble à ceci

entrez la description de l'image ici

et la sortie pourrait ressembler à ceci

[[a, b], [a, c], [a, e], [a, i], [b, d], [b, f], [b, j], [c, d], [c, g], [c, k], [d, h], [d, l], [e, f], [e, g], [e, m], [f, h], [f, n], [g, h], [g, o], [h, p], [i, j], [i, k], [i, m], [j, l], [j, n], [k, l], [k, o], [l, p], [m, n], [m, o], [n, p], [o, p]]

Règles

  • Vous pouvez nommer les sommets comme vous le souhaitez, tant que le nom est unique.
  • Les bords ne sont pas orientés, c'est [a, b]-à- dire et [b, a]sont considérés comme le même bord.
  • Votre sortie ne doit pas contenir de bords en double.
  • La sortie peut être dans n'importe quel format sensible.
  • Les failles standard sont interdites.

Notation

Le code le plus court gagne.

murphy
la source
Donc [1,2], [2,3] etc. ça va?
Rɪᴋᴇʀ
@EasterlyIrk Yep.
murphy
Les bords peuvent être sortis dans n'importe quel ordre, non?
Luis Mendo
@DonMuesli À droite.
murphy

Réponses:

4

Gelée, 13 octets

ạ/S’
2ṗœc2ÇÐḟ

Essayez-le ici. Pour l'entrée 3, la sortie est:

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

J'espère que [1, 1, 1]etc. est un «nom» correct.

Explication

La première ligne est un «prédicat» sur une paire d'arêtes: [A, B] ạ/S’est égal à sum(abs(A - B)) - 1, ce qui est zéro (faux-y) ssi Aet Bdiffèrent dans exactement une coordonnée.

La deuxième ligne est le programme principal:

  • Génère toutes les arêtes avec 2ṗ(puissance cartésienne de [1, 2]).
  • Obtenez toutes les paires possibles en utilisant œc2(combinaisons de taille deux sans remplacement).
  • Ne conservez que les éléments satisfaisant le prédicat défini précédemment ( ÐḟÇ).
Lynn
la source
1
ạ/S’et 2ṗœc2ÇÐḟéconomisez quelques octets.
Dennis
c/P=2, 2ṗṗ2ÇÐffonctionne aussi.
Dennis
Schéma de «dénomination» intelligent! Certainement dans les règles.
murphy
9

Python 2, 54 56 62 octets

lambda n:{tuple({k/n,k/n^1<<k%n})for k in range(n<<n)}

Les bords en double sont supprimés en créant un ensemble d'ensembles, sauf que Python exige que les éléments de l'ensemble soient hachables, de sorte qu'ils sont convertis en tuples. Notez que les ensembles {a,b}et {b,a}sont égaux et convertis en le même tuple. xsot a enregistré 2 octets avec n<<n.

Cela peut être réduit à 49 octets si les chaînes d'ensembles sont un format de sortie OK

lambda n:{`{k/n,k/n^1<<k%n}`for k in range(n<<n)}

ce qui donne une sortie comme

set(['set([1, 3])', 'set([2, 3])', 'set([0, 2])', 'set([0, 1])'])

lambda n:[(k/n,k/n^1<<k%n)for k in range(n*2**n)if k/n&1<<k%n]

Tout d'abord, regardons une ancienne version de la solution.

lambda n:[(i,i^2**j)for i in range(2**n)for j in range(n)if i&2**j]

Chacun un nombre dans l'intervalle [0,2^n)correspond à un sommet dont les coordonnées sont données par ses nchaînes binaires de bits. Les sommets sont adjacents s'ils diffèrent en un seul bit, c'est-à-dire si l'un est obtenu de l'autre en xorant une puissance de 2.

Cette fonction anonyme génère tous les bords possibles en prenant chaque sommet et chaque position de bit à inverser. Pour éviter de dupliquer une arête dans les deux sens, seuls les 1 sont inversés en 0.

Dans la solution plus golfée, kest utilisé pour coder à la fois iet jvia k=n*i+j, à partir desquels (i,j)peuvent être extraits (k/n,k%n). Cela sauve une boucle dans la compréhension. Les pouvoirs de 2sont faits de manière 1<<à avoir la bonne priorité d'opérateur.

Une approche alternative de générer chaque paire de sommets et de vérifier s'ils sont un peu inversés semble plus longue (70 octets):

lambda n:[(i,x)for i in range(2**n)for x in range(i)if(i^x)&(i^x)-1<1] 
xnor
la source
1
n*2**nest justen<<n
xsot
Le passage à Python 3.5 lambda n:{(*{k//n,k//n^1<<k%n},)for k in range(n<<n)}enregistre un octet. (L'expression suivie en enregistre trois, mais la syntaxe de division en perd deux.) Cependant, je suis sûr que la solution de 49 octets que vous avez est correcte.
Lynn
4

Mathematica, 48 24 octets

EdgeList@*HypercubeGraph

Juste une fonction anonyme qui utilise des fonctions intégrées.

LegionMammal978
la source
Ah, le intégré! Comme vous n'avez pas à nommer les sommets par ordre alphabétique, vous pouvez omettre le FromLetterNumber. Je pense même que EdgeList@*HypercubeGraphc'est une réponse valable.
murphy
3

JavaScript (SpiderMonkey 30+), 69 64 octets

n=>[for(i of Array(n<<n).keys())if(i/n&(j=1<<i%n))[i/n^j,i/n^0]]

Cela a commencé comme un port de la solution Python 2 de @ xnor mais j'ai pu économiser 9 octets en réécrivant le code pour utiliser une seule boucle. Edit: enregistré 5 octets supplémentaires en se divisant idans l'autre sens, conformément à la solution mise à jour de @ xnor, qui utilise désormais également une seule boucle.

Neil
la source
2

MATL , 20 octets

2i^:qt!Z~Zltk=XR2#fh

Cela fonctionne avec la version actuelle (14.0.0) du langage / compilateur.

Essayez-le en ligne!

Explication

Cela utilise plus ou moins la même idée que la réponse de @ xnor .

2i^    % take input n and compute 2^n
:q     % range [0,1,...,2^n-1] (row vector)
t!     % duplicate, transpose into a column vector
Z~     % bitwise XOR with broadcast
Zl     % binary logarithm
tk     % duplicate and round down
=      % true if equal, i.e. for powers of 2
XR     % upper triangular part, above diagonal
2#f    % row and index columns of nonzero values
h      % concatenate vertically
Luis Mendo
la source
2

Pyth, 13 octets

fq1.aT.c^U2Q2

Sortie sur entrée 3 :

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

Explication:

fq1.aT.c^U2Q2
                  Implicit: input = Q
        ^U2Q      All Q entry lists made from [0, 1].
      .c    2     All 2 element combinations of them.
f                 Filter them on
   .aT            The length of the vector
 q1               Equaling 1.
isaacg
la source
1

Python 2: 59 octets

lambda n:[(a,a|1<<l)for a in range(2**n)for l in range(n)if~a&1<<l]
DolphinDream
la source