找出字图的直径


13

介绍

一个流行的单词拼图是通过一系列步骤将一个单词转换为另一个单词,这些步骤仅替换一个字母,并且始终生成有效的单词。例如,可以通过五个步骤将BAG转换为DOG:

袋-> BAT->猫-> COT-> COG->狗

在这种情况下,路径也较短。例如:

袋->沼泽->狗

如果绘制了一个图,其顶点被单词标记,则任何一对单词之间的边距相差一个字母,则从“ BAG”到“ DOG”的最短路径将由两个边组成。

挑战

您将要编写一个程序,该程序接收所有长度相同的单词的“字典”作为输入,这些单词代表所有可能出现的单词,这些单词可以沿路径显示为台阶。它应至少输出一个“最长最短路径”,即两个单词之间的路径:

  • 不超过这两个词之间的任何其他路径;

  • 至少与列表中任何其他单词对之间的最短路径一样长。

在上述图表的上下文中,这种路径的长度就是图表的直径

在简并的情况下,所有输入单词都不能转换成其他任何单词,输出至少一个长度为零的路径,即单个单词。

例子

  • 输入[“ bag”,“ bat”,“ cat”,“ cot”,“ dot”,“ dog”]应产生一条以该顺序(或相反顺序)遍历所有六个单词的路径,因为从“这个字典中“ bag”到“ dog”是最长的,五个步骤。

  • 输入[“ bag”,“ bat”,“ bot”,“ cat”,“ cot”,“ dot”,“ dog”]应产生路径“ bag,bat,bot,dot,dog”和/或其路径逆转。

  • 输入[“ code”,“ golf”,“ male”,“ buzz”,“ mole”,“ role”,“ mold”,“ cold”,“ gold”,“ mode”]应产生“ code”之间的路径和“高尔夫”。

  • 输入[“ one”,“ two”,“ six”,“ ten”]对应于没有边的图,因此输出一个或多个单字(零长度)路径。

  • 如果输入包含两个不等长的单词,则输出未定义。

规则

  • 适用标准守则的高尔夫球规则
  • 将有多个“最短”路径。您必须至少输出一个,但是可以自由输出任意数量的内容。
  • 您可以自由决定如何将输入字典传递到程序中。
  • 以字节为单位的最短代码获胜。

3
介意添加更多测试用例?
约拿(Jonah)

做完了 还增加了对图形不包含边的情况的讨论。
jnfnt


我们是否应该接受一个空输入(答案将是[][[]])?
乡村大佬埃里克(Erik the Outgolfer)

我很高兴在空输入中未定义行为。
jnfnt

Answers:



3

APL(Dyalog Classic)84 80 77 76 74 66 61字节

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

在线尝试!

输入和输出是字符矩阵

⍵+.≠⍉⍵ 单词之间的汉明式距离矩阵

9*⍨2⌊保持0和1不变,将2+变成一个较大的数字(512 = 2 9,用作“∞”)

⌊.+⍨⍣≡ floyd&warshall的最短路径算法

  • ⌊.+像矩阵乘法,但使用min)和+代替+×分别

  • 在左右使用相同的矩阵

  • ⍣≡ 重复直到收敛

d←⌈/512|, 最长(不是“∞”)路径的长度,分配给 d

⊃⍸a=它连接哪两个节点,我们称它们为ij

{⍵,⍨⊃⍋(1≠a⌷⍨⊃⍵),⍪⍺⌷a}⍣d/ 重建路径

  • { }⍣d/评估{ }功能d时间。左arg 始终是i。右边的arg j开始,并逐渐积累路径的内部节点

  • (1≠a⌷⍨⊃⍵),⍪⍺⌷a 建立这两个向量的2列矩阵:

    • 1≠a⌷⍨⊃⍵ 布尔值(0或1),指示哪些节点与第一个节点的距离为1

    • ⍺⌷a 所有图节点到的距离

  • ⊃⍋ 字典上最小行的索引

  • ⍵,⍨ 前置于

⍵⌷⍨ 用路径索引原始单词


2

Python 3,225字节

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]

在线尝试!

基本上,采取所有可能的路径,仅保留有效的路径,然后遍历每个起点-终点组合,找到最小路径距离,然后找到最大路径距离。



1

JavaScript的(ES6), 195个  194字节

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

在线尝试!

怎么样?

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]

(此代码在每个递归深度执行,但仅根级别确实重要)

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


0

Python 3,228个字节。

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)

为所有对的最短路径实现Floyd-Warshall算法,然后在找到的路径上取最大值。

此实现中的16个字符是制表符,很不幸:(


2
当没有入射边缘的顶点存在时,这似乎会中断,例如“ print G(['bag','bat','cot'])“
jnfnt

高尔夫尖端用于Python缩进:使用用于第一电平两个选项卡的第四等的空间,对于第二突出部,标签,用于第三空间,
彼得·泰勒

1
@PeterTaylor很好的技巧,但仅适用于Python2。Python3不允许将制表符与空格混合使用。
OOBalance

1
啊,很好@jnfnt。现在,我考虑了一下,它仅在连接图形时有效。
rikhavshah
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.