旧无绳电话


9

我需要打电话给朋友,但是无绳电话的按钮无法正常工作。我只能按下的按钮是[上],[下]和[通话]。[上]和[下]可用于导航我最近的通话,[电话]可用于呼叫所选名称。我的电话有一个保存N最近通话的列表,我知道我需要通话的所有朋友都在此列表中。


任务:

您会收到一个数字N和一个名称列表L

  • N 我的手机可以记住的最近通话次数;
  • L 具有我需要呼叫的顺序的名称。

您必须输出我在最近通话清单的最佳安排中需要进行的按键次数。


例:

->输入:

叫安娜,鲍勃,再叫安娜。最近的通话清单大小为5。

5
Anna
Bob
Anna

->输出:

可能的最佳安排: Anna, Foo, Bar, Foobar, Bob

5    # Key presses: [Call] Anna, [Up] + [Call] Bob, [Down] + [Call] Anna

更多测试用例:

Input: 5, Anna, Bob, Carl
Output: 5

Input: 5, Anna, Bob, Carl, Anna
Output: 8

Input: 5, A, B, C, D, E, A
Output: 11

Input: 6, A, B, C, D, E, A
Output: 12

Input: 4, A, B, C, B, A
Output: 10

规则:

  • 您的光标将始终从列表的第一位置开始。
  • 你可以把输入NL从任何来源:键盘,参数,文件等;
  • 列表中的名称可以采用任何合理的格式,例如:字符串,整数,字符;
  • 当您到达最近通话列表的末尾并再次按[Down]时,光标将环绕。当您位于最近通话列表的开头并按[Up]时,也会发生同样的情况。
  • 当您呼叫某人时,该人的名字将被移至最近通话列表的第一个位置,其余的将被下推;
  • 当您呼叫某人时,您的光标将移至第一个位置。
  • 朋友名称在最近通话列表中不能出现多次;
  • 您可以使用虚拟条目填充最近的通话列表(请参见示例)。
  • 致电的朋友人数不得超过N

Answers:


1

红宝石97 95 94字节

->n,a{r=a.size;1.upto(r-1){|i|r+=[p=a[(a[0,i].rindex(a[i])||i-2)+1...i].uniq.size,n-p].min};r}

在线尝试!

在最佳配置中,一个名字将按一次(Call)。尚未被调用的名称需要按两次(Up Call),而具有不同编号的名称则取决于此后已调用了多少个其他唯一名称,以及它们是否更靠近列表的顶部或底部。

我认为这与WaffleCohn的策略相似或相同。


3

Python 3195个 185 164字节

-4个字节,感谢@notjagan
-27个字节

lambda n,l:min(g([*x],l,n)for x in permutations(range(n)))
def g(x,l,n,r=0):
 for p in l:a=x.index(p);x=[x.pop(a)]+x;r-=~min(a,n-a)
 return r
from itertools import*

在线尝试!

L 被视为来自的整数列表 [0, N)



@notjagan不能像x=[x[a]]+x[:a]+x[a+1:]分配x给新列表对象那样工作。i仍然是index旧列表对象上的方法
ovs

@ovs -10使用费利佩的建议和而不是我的建议x.index
notjagan


@FelipeNardiBatista非常感谢
ovs '17

1

JavaScript(SpiderMonkey)213143字节

(N,L)=>L.reduce((t,v,i)=>{x=0,a=[v]
for(j=i;j-->=0&!~a.indexOf(L[j]);x++)a+=L[j]+","
return i?t+((x=L.indexOf(v)-i?x:1)<N-x?x:N-x):t},L.length)

在线尝试!

生成给定名称的最佳排列,然后计算按键次数。

跳过这一代,只计算按最佳布局排列每个名称的按键次数

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.