本周四年级数学作业:效率最低的旅行推销员


10

我女儿的数学作业有以下任务。想象一下,有六个朋友生活在一条名为E,F,G,H,J和K的直线上。他们在直线上的位置如下所示(未按比例):

因此,F从E居住五个单元,从G居住两个单元,依此类推。

您的作业:设计一个程序,该程序以朋友的位置和n为输入,以总长度n个单位的长度来精确地访问每个朋友一次。如果找到它,它应该报告该路径(例如,对于长度17,它可能报告“ E,F,G,H,J,K”,并且如果不存在任何解决方案,则应正常退出。对于它的价值,我完成了Mathematica中271个字节的非解决方案,我怀疑这可能比这更简洁。


3
作为一个接受输入(例如[0, 5, 7, 13, 16, 17]62)的程序,这样做可能会更好,这样您就可以确保它没有针对这种情况进行专门的硬编码。
门把手

@Doorknob,好点。我已经相应地调整了作业。
Michael Stern 2015年

1
路径是否始于任何朋友?
xnor 2015年

1
我可以定义输入和输出字符串的格式吗?输入"[0, 5, 7, 13, 16, 17], 62"和输出都可以"(7, 16, 0, 17, 5, 13)"吗?
逻辑骑士

1
@Geobits只是我的草率。已更正。
Michael Stern

Answers:


1

J,54个字节

输出一条正确的路线。如果没有路由,则不输出任何内容。

   f=.4 :'{.(x=+/|:2|@-/\"#.s A.y)#(s=.i.!6)A.''EFGHJK'''

   62 f 0 5 7 13 16 17
GJEKFH

输出所有路由的52字节代码(每行一条):

f=.4 :'(x=+/|:2|@-/\"#.s A.y)#(s=.i.!6)A.''EFGHJK'''

38个字节的代码,用于输出职位而不是字母:

f=.4 :'p#~x=+/|:2|@-/\"#.p=.(i.!6)A.y'

我无法审查代码,但是根据您的摘要,这似乎是解决问题所需的所有内容的最短条目。
迈克尔·斯特恩

6

Mathematica,55或90字节

您说过Mathematica吗?;)

FirstCase[Permutations@#,p_/;Tr@Abs@Differences@p==#2]&

这是一个匿名函数,它首先获取朋友的位置(以任何顺序),然​​后获取目标长度。Missing[NotFound]如果不存在这样的路径,则返回。

FirstCase[Permutations@#,p_/;Tr@Abs@Differences@p==#2]&[{0, 5, 7, 13, 16, 17}, 62]
(* {7, 16, 0, 17, 5, 13} *)

如果允许返回所有有效路径(FirstCase-> Cases),我可以节省四个字节。

返回一个字符串数组比较麻烦:

FromCharacterCode[68+#]&/@Ordering@FirstCase[Permutations@#,p_/;Tr@Abs@Differences@p==#2]&

您是否可以调整以使其响应字母而不只是位置?
迈克尔·斯特恩

@MichaelStern从这个问题上还不清楚,应该对多少进行硬编码以及将多少作为参数的一部分?输入是否应该像字母到位置的映射?
马丁·恩德

假定字母始终按上面数字行中给出的顺序(E,F,G,H,J,K)。它们之间的距离应该像在解决方案中一样传递给函数。
Michael Stern

@MichaelStern我添加了一个返回字符串数组的版本。它支持列表中任意数量的位置,但是之后Z将继续使用下一个ASCII字符(不是您无论如何都想将我的代码运行为n> 20:D)。
马丁·恩德

5

Python 2中,154个 148字节的

(或一般解决方案为118字节)

此程序在stdin上接受带有列表的行和整数,例如'[0,5,7,13,13,16,17],n',并在输出的长度为n的输出上打印路径,如果不可能,则不输出任何内容。

# echo "[0, 5, 7, 13, 16, 17], 62" | python soln.py 
['G', 'J', 'E', 'K', 'F', 'H']

用Python编写需要置换的小型程序是一项挑战。这种导入和使用非常昂贵。

from itertools import*
a,c=input()
for b in permutations(a):
 if sum(abs(p-q)for p,q in zip(b[1:],b))==c:print['EFGHJK'[a.index(n)]for n in b];break

缩小器之前的OP要求的来源:

from itertools import*

puzzle, goal = input()
for option in permutations(puzzle):
    if sum(abs(p-q) for p,q in zip(option[1:], option)) == goal :
        print ['EFGHJK'[puzzle.index(n)] for n in option];
        break

通用解决方案(未缩小):

from itertools import*

puzzle, goal = input()
for option in permutations(puzzle):
    if sum(abs(p-q) for p,q in zip(option[1:], option)) == goal :
        print option;
        break

由于简单的算法和大量的组合,执行20多个初始位置将非常缓慢。


您可以使用保存几个字节from itertools import*。同样,Python 3可能会更短,input()并且*a,c=map(...)是否可以与程序的其余部分一起使用。
grc 2015年

感谢您的导入提示。我拒绝我的代码库进行py3安装和转换。我一直等到我使用的每个第3方模块都可用并且在py3下稳定(我使用了许多旧的且晦涩的模块)。
逻辑骑士

您是否可以调整以使其响应字母而不只是位置?
Michael Stern

chr(a.index(n)+69)
马丁·恩德

很好的优化。但是我认为@MichaelStern真的很想看'EFGHJK',它很容易,所以我以这种方式编写了代码。
逻辑骑士

4

J(48或65)

我假设这可以使更多的事情发生。随意使用它作为起点,进一步打高尔夫球

]A.~[:I.(=([:([:+/}:([:|-)}.)"1(A.~([:i.[:!#))))

或带字母:

([:I.(=([:([:+/}:([:|-)}.)"1(A.~([:i.[:!#)))))A.[:(a.{~65+[:i.#)]

它能做什么:

   62 (]A.~[:I.(=([:([:+/}:([:|-)}.)"1(A.~([:i.[:!#))))) 0 5 7 13 16 17
 7 16  0 17  5 13
 7 16  5 17  0 13
 7 17  0 16  5 13
 7 17  5 16  0 13
13  0 16  5 17  7
13  0 17  5 16  7
13  5 16  0 17  7
13  5 17  0 16  7

(我希望这种I / O格式是可以的...)

怎么做的:

(A.~([:i.[:!#))

生成输入的所有排列

([:+/}:([:|-)}.)"1

计算距离

(]A.~[: I. (= ([:distance perms)))

查看哪些结果与输入相同,然后重新生成这些排列(我怀疑这里可以删除一些字符)

带字母:

((a.{~65+[:i.#))

创建前n个字母的列表,其中n是输入列表的长度

indices A. [: letters ]

与上述相同


您可以调整它以字母形式报告答案吗?
迈克尔·斯特恩

@MichaelStern我可以,但是那会增加很多字符数(J对于字符串很糟糕)。现在,我将尝试一下,以查看可能造成的损害。
ɐɔıʇǝɥʇuʎs

3

八度,73

function r=t(l,d,s)r=perms(l)(find(sum(abs(diff(perms(d)')))==s,1),:);end

确实没有问题,所以让我尝试解释一下...从内到外,我们对所有距离进行置换,然后对于每个置换,我们将房屋之间的差异取为基准,将绝对值作为距离,并将其相加向上,找到具有所需距离的第一个排列的索引,然后排列字母并找到该字母的特定排列。

octave:15> t(["E" "F" "G" "H" "J" "K"],[0 5 7 13 16 17],62)
ans = HEJFKG

这是13-0-16-5-17-7 => 13 + 16 + 11 + 12 + 10 = 62。

octave:16> t(["E" "F" "G" "H" "J" "K"],[0 5 7 13 16 17],2)
ans = 

(空白为不可能的输入)


我不知道这笔交易是什么,但是perms()在ideone.com的Octave 3.6.2中,字符串向量存在问题。
Alex A.

有趣。我在本地有3.8.1。
dcsohl

2

Matlab(86)

x=input('');X=perms(1:6);disp(char(X(find(sum(abs(diff(x(X).')))==input(''),1),:)+64))

存在解决方案的示例:

>> x=input('');X=perms(1:6);disp(char(X(find(sum(abs(diff(x(X).')))==input(''),1),:)+64))
[0, 5, 7, 13, 16, 17]
62
DBFAEC
>>

不存在解决方案的示例:

>> x=input('');X=perms(1:6);disp(char(X(find(sum(abs(diff(x(X).')))==input(''),1),:)+64))
[0, 5, 7, 13, 16, 17]
100
>> 

Matlab(62)

如果可以通过产生位置而不是字母来放宽输出格式,并且如果不存在解决方案,则产生一个空矩阵:

X=perms(input(''));X(find(sum(abs(diff(X.')))==input(''),1),:)

存在解决方案的示例:

>> X=perms(input(''));X(find(sum(abs(diff(X.')))==input(''),1),:)
[0, 5, 7, 13, 16, 17]
62
ans =
    13     5    17     0    16     7

不存在解决方案的示例:

>> X=perms(input(''));X(find(sum(abs(diff(X.')))==input(''),1),:)
[0, 5, 7, 13, 16, 17]
62
ans =
   Empty matrix: 0-by-6

Matlab(54)

如果程序提供所有有效路径是可接受的:

X=perms(input(''));X(sum(abs(diff(X.')))==input(''),:)

存在解决方案的示例:

>> X=perms(input(''));X(sum(abs(diff(X.')))==input(''),:)
[0, 5, 7, 13, 16, 17]
62
ans =
    13     5    17     0    16     7
    13     5    16     0    17     7
    13     0    17     5    16     7
    13     0    16     5    17     7
     7    16     5    17     0    13
     7    16     0    17     5    13
     7    17     5    16     0    13
     7    17     0    16     5    13

1

Haskell,109个字节

import Data.List
a%b=abs$snd a-snd b
n#l=[map(fst)p|p<-permutations(zip['E'..]l),n==sum(zipWith(%)p(tail p))]

用法示例:17 # [0, 5, 7, 13, 16, 17]输出所有有效路径,即["EFGHIJ","JIHGFE"]。如果没有有效的路径,[]则返回空列表。

字母列表包括I(希望如此)。

工作原理:制作(name, position)成对的列表,排列并取其路径长度相等的那些,n并去除位置部分。

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.