Di tepi hypercube

12

Tugas Anda adalah untuk menulis fungsi atau program, yang akan membawa integer n>0sebagai input dan output daftar tepi nberdimensi hypercube . Dalam teori graph, sebuah edge didefinisikan sebagai 2-tuple dari simpul (atau sudut, jika Anda mau), yang terhubung.

Contoh 1

Hypercube 1 dimensi adalah garis dan fitur dua simpul, yang akan kita panggil adan b.

masukkan deskripsi gambar di sini

Oleh karena itu, hasilnya adalah:

[[a, b]]

Contoh 2

Hypercube 4-dimensi (atau tesseract) terdiri dari 32 sisi dan grafiknya terlihat seperti ini

masukkan deskripsi gambar di sini

dan hasilnya bisa seperti ini

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

Aturan

  • Anda dapat memberi nama simpul dengan cara apa pun yang Anda suka, asalkan namanya unik.
  • Tepi tidak diarahkan, yaitu [a, b]dan [b, a]dianggap sebagai tepi yang sama.
  • Output Anda tidak boleh mengandung duplikat tepi.
  • Outputnya mungkin dalam format yang masuk akal.
  • Celah standar dilarang.

Mencetak gol

Kode terpendek menang.

murphy
sumber
Terkait Terkait
Martin Ender
Jadi [1,2], [2,3] dll tidak apa-apa?
R
@EasterlyIrk Yap.
murphy
Tepi dapat menjadi output dalam urutan apa pun, bukan?
Luis Mendo
@ DonMuesli Benar.
murphy

Jawaban:

4

Jelly, 13 byte

ạ/S’
2ṗœc2ÇÐḟ

Coba di sini. Untuk input 3, outputnya adalah:

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

Saya harap [1, 1, 1]dll adalah "nama" yang oke.

Penjelasan

Baris pertama adalah "predikat" pada sepasang tepi: [A, B] ạ/S’sama dengan sum(abs(A - B)) - 1, yang nol (salah-y) jika Adan Bberbeda dalam satu koordinat.

Baris kedua adalah program utama:

  • Hasilkan semua tepi dengan 2ṗ(kekuatan Cartesian [1, 2]).
  • Dapatkan semua pasangan yang mungkin menggunakan œc2(kombinasi ukuran dua tanpa penggantian).
  • Simpan hanya elemen yang memenuhi predikat yang ditentukan sebelumnya ( ÐḟÇ).
Lynn
sumber
1
ạ/S’dan 2ṗœc2ÇÐḟsimpan beberapa byte.
Dennis
c/P=2, 2ṗṗ2ÇÐfBekerja juga.
Dennis
Skema "penamaan" yang cerdas! Tentunya sesuai aturan.
murphy
9

Python 2, 54 56 62 byte

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

Tepi duplikat dihapus dengan membuat satu set set, kecuali Python membutuhkan elemen set yang hashable, sehingga mereka dikonversi menjadi tupel. Perhatikan bahwa set {a,b}dan {b,a}sama dan dikonversi ke tuple yang sama. xsot menyimpan 2 byte dengan n<<n.

Ini dapat dikurangi menjadi 49 byte jika rangkaian set adalah format output OK

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

yang memberikan output seperti

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]

Pertama, mari kita lihat versi solusi yang lebih lama.

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

Setiap angka dalam interval [0,2^n)sesuai dengan sebuah titik dengan koordinat yang diberikan oleh nstring biner - bitnya. Ke simpul berdekatan jika mereka berbeda dalam satu bit, yaitu jika satu diperoleh dari yang lain dengan xor-ing kekuatan 2.

Fungsi anonim ini menghasilkan semua tepi yang mungkin dengan mengambil setiap titik dan setiap posisi bit untuk flip. Untuk menghindari duplikasi tepi di kedua arah, hanya 1 yang dibalik ke 0.

Dalam solusi yang lebih golf, kdigunakan untuk menyandikan keduanya idan jmelalui k=n*i+j, dari mana (i,j)dapat diekstraksi sebagai (k/n,k%n). Ini menghemat satu lingkaran dalam pemahaman. Kekuatan 2dilakukan 1<<agar memiliki hak operator yang diutamakan.

Pendekatan alternatif untuk menghasilkan setiap pasangan simpul dan memeriksa jika keduanya agak terpisah tampaknya lebih lama (70 byte):

lambda n:[(i,x)for i in range(2**n)for x in range(i)if(i^x)&(i^x)-1<1] 
Tidak
sumber
1
n*2**nhanyan<<n
xsot
Beralih ke Python 3.5, lambda n:{(*{k//n,k//n^1<<k%n},)for k in range(n<<n)}menyimpan satu byte. (Ekspresi berbintang menyimpan tiga, tetapi sintaks pembagian kehilangan dua.) Namun, saya cukup yakin solusi 49-byte yang Anda miliki baik-baik saja.
Lynn
4

Mathematica, 48 24 byte

EdgeList@*HypercubeGraph

Hanya fungsi anonim yang menggunakan bawaan.

LegionMammal978
sumber
Ah, built-in! Karena Anda tidak harus memberi nama simpul sesuai abjad, Anda dapat menghilangkan FromLetterNumber. Saya bahkan berpikir itu EdgeList@*HypercubeGraphadalah jawaban yang valid.
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]]

Ini dimulai sebagai port dari solusi Python 2 @ xnor tetapi saya dapat menyimpan 9 byte dengan menulis ulang kode untuk menggunakan satu loop. Sunting: Menyimpan 5 byte lebih lanjut dengan imemisah-misahkan, sesuai per pembaruan solusi @ xnor, yang sekarang juga menggunakan satu loop.

Neil
sumber
2

MATL , 20 byte

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

Ini berfungsi dengan versi saat ini (14.0.0) dari bahasa / kompiler.

Cobalah online!

Penjelasan

Ini menggunakan ide yang kurang lebih sama dengan jawaban @ 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
sumber
2

Pyth, 13 byte

fq1.aT.c^U2Q2

Output pada input 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]]]

Penjelasan:

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