Ai bordi dell'ipercubo


12

Il tuo compito sarà quello di scrivere una funzione o un programma, che prenderà un intero n>0come input e produrrà un elenco dei bordi dell'ipercubon tridimensionale . Nella teoria dei grafi un bordo è definito come una 2 tupla di vertici (o angoli, se preferite), che sono collegati.

Esempio 1

Un ipercubo monodimensionale è una linea e presenta due vertici, che chiameremo ae b.

inserisci qui la descrizione dell'immagine

Pertanto, l'output sarà:

[[a, b]]

Esempio 2

L'ipercubo a 4 dimensioni (o tesseratto) è costituito da 32 bordi e il suo grafico è simile al seguente

inserisci qui la descrizione dell'immagine

e l'output potrebbe apparire così

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

Regole

  • Puoi nominare i vertici come preferisci, purché il nome sia univoco.
  • I bordi sono non orientati, ossia [a, b]e [b, a]sono considerati dello stesso bordo.
  • L'output non deve contenere bordi duplicati.
  • L'output può essere in qualsiasi formato ragionevole.
  • Sono vietate le scappatoie standard.

punteggio

Il codice più corto vince.



Quindi [1,2], [2,3] ecc. Va bene?
R

@EasterlyIrk Yep.
Murphy

I bordi possono essere emessi in qualsiasi ordine, giusto?
Luis Mendo,

@DonMuesli Right.
Murphy

Risposte:


4

Gelatina, 13 byte

ạ/S’
2ṗœc2ÇÐḟ

Provalo qui. Per l'input 3, l'output è:

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

Spero [1, 1, 1]ecc. È un "nome" ok.

Spiegazione

La prima riga è un "predicato" su una coppia di bordi: [A, B] ạ/S’è uguale a sum(abs(A - B)) - 1, che è zero (false-y) iff Ae Bdifferisce esattamente in una coordinata.

La seconda riga è il programma principale:

  • Genera tutti i bordi con 2ṗ(Potenza cartesiana di [1, 2]).
  • Ottieni tutte le coppie possibili usando œc2(combinazioni di taglia due senza sostituzione).
  • Mantenere solo gli elementi che soddisfano il predicato definito in precedenza ( ÐḟÇ).

1
ạ/S’e 2ṗœc2ÇÐḟsalva un paio di byte.
Dennis,

c/P=2, 2ṗṗ2ÇÐffunziona anche.
Dennis,

Schema intelligente di "denominazione"! Certamente all'interno delle regole.
Murphy

9

Python 2, 54 56 62 byte

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

I bordi duplicati vengono rimossi creando un set di set, tranne per il fatto che Python richiede che gli elementi set siano hash, quindi vengono convertiti in tuple. Notare che gli insiemi {a,b}e {b,a}sono uguali e si convertono nella stessa tupla. xsot ha salvato 2 byte con n<<n.

Questo può essere ridotto a 49 byte se le stringhe di set sono in un formato di output OK

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

che dà un output simile

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]

Innanzitutto, diamo un'occhiata a una versione precedente della soluzione.

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

Ciascuno di un numero nell'intervallo [0,2^n)corrisponde a un vertice con coordinate fornite dalle sue nstringhe binarie a bit. I vertici sono adiacenti se differiscono in un singolo bit, cioè se uno è ottenuto dall'altro xorando una potenza di 2.

Questa funzione anonima genera tutti i fronti possibili prendendo in rotazione tutti i vertici e tutte le posizioni dei bit. Per evitare di duplicare un bordo in entrambe le direzioni, solo 1 viene ruotato su 0.

Nella soluzione più golfata, kviene utilizzato per codificare sia ie jvia k=n*i+j, da cui (i,j)può essere estratto come (k/n,k%n). Questo salva un ciclo nella comprensione. I poteri di 2sono fatti in modo 1<<da avere la giusta precedenza da parte dell'operatore.

Un approccio alternativo per generare ogni coppia di vertici e verificare se sono leggermente capovolti sembra più lungo (70 byte):

lambda n:[(i,x)for i in range(2**n)for x in range(i)if(i^x)&(i^x)-1<1] 

1
n*2**nè solon<<n
xsot

Passando a Python 3.5, lambda n:{(*{k//n,k//n^1<<k%n},)for k in range(n<<n)}salva un byte. (L'espressione a stella ne salva tre, ma la sintassi della divisione ne perde due.) Tuttavia, sono abbastanza sicuro che la soluzione a 49 byte che hai sia a posto.
Lynn

4

Mathematica, 48 24 byte

EdgeList@*HypercubeGraph

Solo una funzione anonima che utilizza i built-in.


Ah, il built-in! Poiché non è necessario nominare i vertici in ordine alfabetico, è possibile omettere il FromLetterNumber. Penso anche che EdgeList@*HypercubeGraphsia una risposta valida.
Murphy

3

JavaScript (SpiderMonkey 30+), 69 64 byte

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

Questo è iniziato come una porta della soluzione Python 2 di @ xnor, ma sono stato in grado di salvare 9 byte riscrivendo il codice per utilizzare un singolo ciclo. Modifica: salvato altri 5 byte suddividendoli iviceversa, come per la soluzione aggiornata di @ xnor, che ora utilizza anche un singolo ciclo.


2

MATL , 20 byte

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

Funziona con la versione corrente (14.0.0) del linguaggio / compilatore.

Provalo online!

Spiegazione

Questo utilizza più o meno la stessa idea della risposta di @ 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

2

Pyth, 13 byte

fq1.aT.c^U2Q2

Uscita sull'ingresso 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]]]

Spiegazione:

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.

1

Python 2: 59 byte

lambda n:[(a,a|1<<l)for a in range(2**n)for l in range(n)if~a&1<<l]
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.