Temukan diameter grafik kata

12

pengantar

Teka-teki kata yang populer adalah mengubah satu kata menjadi kata lain melalui serangkaian langkah yang hanya mengganti satu huruf dan yang selalu menghasilkan kata yang valid. Misalnya, BAG dapat dikonversi ke DOG melalui jalur lima langkah:

BAG -> BAT -> CAT -> COT -> COG -> DOG

Jalur yang lebih pendek juga ada dalam kasus ini; sebagai contoh:

BAG -> BOG -> DOG

Jika seseorang menggambar grafik yang simpulnya dilabeli dengan kata-kata, dengan tepi antara pasangan kata yang berbeda dengan satu huruf, maka jalur terpendek dari "BAG" ke "DOG" akan terdiri dari dua tepi.

Tantangan

Anda harus menulis sebuah program yang menerima sebagai masukan "kamus" kata-kata yang semuanya memiliki panjang yang sama, mewakili semua kata yang diijinkan yang dapat muncul sebagai langkah-langkah di sepanjang jalur. Ini harus menghasilkan setidaknya satu "jalan terpendek terpanjang", yaitu jalur antara dua kata yaitu:

  • tidak lebih dari jalan lain di antara kedua kata itu;

  • setidaknya selama jalur terpendek yang mungkin antara pasangan kata lain dalam daftar.

Dalam konteks grafik yang dijelaskan di atas, panjang jalur tersebut adalah diameter grafik.

Dalam kasus degenerasi di mana tidak ada kata-kata input dapat diubah menjadi yang lain, output setidaknya satu jalur dengan panjang nol, yaitu, satu kata.

Contohnya

  • Input ["bag", "bat", "cat", "cot", "dot", "dog"] harus menghasilkan jalur yang melintasi semua enam kata dalam urutan itu (atau urutan terbalik), karena jalur terpendek dari " tas "ke" anjing "dalam kamus ini adalah yang paling lama dicapai, lima langkah.

  • Input ["bag", "bat", "bot", "cat", "cot", "dot", "dog"] harus menghasilkan path "bag, kelelawar, bot, titik, anjing" dan / atau pembalikan.

  • Input ["kode", "golf", "pria", "buzz", "mol", "peran", "cetakan", "dingin", "emas", "mode"] akan menghasilkan jalur antara "kode dan "golf".

  • Input ["satu", "dua", "enam", "sepuluh"] sesuai dengan grafik tanpa tepi, sehingga menghasilkan satu atau beberapa jalur kata-tunggal (panjang nol).

  • Jika input berisi dua kata dengan panjang yang tidak sama, outputnya tidak ditentukan.

Aturan

  • Aturan golf kode standar berlaku
  • Akan ada beberapa jalur "terpendek". Anda harus mengeluarkan setidaknya satu, tetapi bebas untuk menghasilkan sebanyak yang Anda inginkan.
  • Anda bebas memutuskan bagaimana kamus input dimasukkan ke dalam program Anda.
  • Kode terpendek dalam byte menang.
jnfnt
sumber
3
Pikiran menambahkan beberapa kasus uji lagi?
Jonah
Selesai Juga ditambahkan diskusi tentang kasus di mana grafik tidak mengandung tepi.
jnfnt
Haruskah kita menerima input kosong (jawabannya adalah []atau [[]])?
Erik the Outgolfer
Saya senang perilaku tidak ditentukan pada input kosong.
jnfnt

Jawaban:

3

APL (Dyalog Classic) , 84 80 77 76 74 66 61 byte

{⍵⌷⍨{⍵,⍨⊃⍋(1a⌷⍨⊃⍵),⍪⍺⌷a}⍣d/⊃⍸a=d←⌈/512|,a←⌊.+⍨⍣≡9*⍨2⌊⍵+.≠⍉⍵}

Cobalah online!

input dan output adalah matriks karakter

⍵+.≠⍉⍵ matriks jarak hamming-like antara kata-kata

9*⍨2⌊biarkan 0s dan 1s utuh, ubah 2+ menjadi sejumlah besar (512 = 2 9 , digunakan sebagai "∞")

⌊.+⍨⍣≡ Algoritma jalur terpendek floyd & warshall

  • ⌊.+seperti multiplikasi matriks tetapi menggunakan min( ) dan +bukannya +dan ×masing - masing

  • gunakan matriks yang sama di kiri dan kanan

  • ⍣≡ ulangi sampai konvergensi

d←⌈/512|, panjang jalur terpanjang (bukan "∞"), ditugaskan ke d

⊃⍸a=yang mana dua node terhubung, sebut saja mereka i dan j

{⍵,⍨⊃⍋(1≠a⌷⍨⊃⍵),⍪⍺⌷a}⍣d/ merekonstruksi jalan

  • { }⍣d/mengevaluasi waktu { }fungsi d. arg kiri selalu i . arg kanan dimulai sebagai j dan secara bertahap mengakumulasi node internal path

  • (1≠a⌷⍨⊃⍵),⍪⍺⌷a buat matriks 2-kolom dari dua vektor ini:

    • 1≠a⌷⍨⊃⍵ booleans (0 atau 1) menunjukkan node mana pada jarak 1 ke yang pertama

    • ⍺⌷a jarak semua node grafik ke

  • ⊃⍋ indeks baris terkecil secara leksikografis

  • ⍵,⍨ dipertanggungjawabkan ke

⍵⌷⍨ indeks kata aslinya dengan path

ngn
sumber
2

Python 3 , 225 byte

from itertools import*
def f(a):b=[((p[0],p[-1]),(len(p),p))for i in range(len(a))for p in permutations(a,i+1)if all(sum(q!=r for q,r in zip(*x))<2for x in zip(p,p[1:]))];return max(min(r for q,r in b if x==q)for x,y in b)[1]

Cobalah online!

Pada dasarnya, ambil semua jalur yang mungkin, simpan jalur yang valid, lalu lewati setiap kombinasi awal-akhir, temukan jarak jalur minimum, dan temukan maksimumnya.

HyperNeutrino
sumber
1

JavaScript (ES6),  195  194 byte

Pengembalian [optimal_length, [optimal_path]].

f=(a,p=[],w=o=[],l=0)=>Object.values(o,o[k=[w,p[0]]]=(o[k]||0)[0]<l?o[k]:[l,p],a.map((v,i)=>w+w&&[...v].map((c,i)=>s-=c!=w[i],s=1)|s||f(a.filter(_=>i--),[...p,v],v,l+1))).sort(([a],[b])=>b-a)[0]

Cobalah online!

Bagaimana?

fow0w1[l,p]pw0w1l

plwpo

o[k = [w, p[0]]] = (o[k] || 0)[0] < l ? o[k] : [l, p]

o

Object.values(o).sort(([a], [b]) => b - a)[0]

(kode ini dieksekusi pada setiap kedalaman rekursi, tetapi hanya level root yang benar-benar penting)

vw

[...v].map((c, i) => s -= c != w[i], s = 1) | s

v

f(                    //
  a.filter(_ => i--), // remove the i-th word from a[]
  [...p, v],          // append v to p[]
  v,                  // pass v as the last word
  l + 1               // increment the length of the path
)                     //
Arnauld
sumber
0

Python 3, 228 byte.

def G(w):
    D={A+B:[A,B]if sum(a!=b for a,b in zip(A,B))<2else[0,0]*len(w)for A in w for B in w}
    for k in w:
        for i in w:
            for j in w:
                p=D[i+k]+D[k+j][1:]
                if len(p)<len(D[i+j]):D[i+j]=p
    return max(D.values(),key=len)

Menerapkan algoritma Floyd-Warshall untuk semua-pasangan jalur-terpendek, kemudian mengambil maksimum di atas jalur yang ditemukan.

16 karakter dalam implementasi ini adalah tab, yang tidak menguntungkan :(

rikhavshah
sumber
2
Ini tampaknya pecah ketika sebuah simpul tanpa tepi yang ada, misalnya, "print G (['bag', 'bat', 'cot'])"
jnfnt
Kiat golf untuk lekukan Python: gunakan spasi untuk level pertama, tab untuk yang kedua, tab, dan spasi untuk yang ketiga, dua tab untuk yang keempat, dll.
Peter Taylor
1
@PeterTaylor Tip yang baik, tetapi hanya berfungsi untuk Python 2. Python 3 tidak memungkinkan pencampuran tab dengan spasi.
OOBalance
1
Ah, tangkapan bagus @jnfnt. Sekarang saya berpikir tentang itu, itu hanya berfungsi ketika grafik terhubung.
rikhavshah