Старый беспроводной телефон

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

Правила:

  • Ваш курсор всегда будет начинаться с первой позиции списка;
  • Вы можете взять ввод Nи Lиз любого источника: клавиатура, параметры, файл и т. Д .;
  • Имена в списке могут быть в любом приемлемом формате, таком как: строки, целые числа, символы;
  • Когда вы дойдете до конца списка последних вызовов и снова нажмете [Вниз], курсор переместится. То же самое происходит, когда вы находитесь в начале списка недавних вызовов и нажимаете [Up];
  • Когда вы звоните кому-то, его имя будет перемещено на первую позицию в списке последних вызовов, а остальные будут сдвинуты вниз;
  • Когда вы звоните кому-то, ваш курсор будет перемещен в первую позицию;
  • Имя друга не может появляться более одного раза в списке последних вызовов;
  • Вы можете заполнить список последних звонков фиктивными записями (см. Пример);
  • Количество звонящих друзей не будет больше, чем N.
Фелипе Нарди Батиста
источник

Ответы:

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.

Nnnes
источник
3

Python 3 , 195 185 164 байта

-4 байта благодаря @notjagan
-27 байтов благодаря @FelipeNardiBatista

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)

овс
источник
-4 байта .
notjagan
@notjagan Это не работает, так как x=[x[a]]+x[:a]+x[a+1:]присваивает xновый объект списка. iвсе равно будет indexметод на старом объекте списка
овс
@ovs -10 байт, используя предложение Фелипе, и те, которые у меня были, кроме x.index.
notjagan
164 байта
Фелипе Нарди Батиста
@FelipeNardiBatista Большое спасибо
OVS
1

JavaScript (SpiderMonkey) , 213 143 байта

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

Попробуйте онлайн!

Создает оптимальное расположение данных имен, а затем подсчитывает количество нажатий клавиш.

Пропустил поколение и просто посчитал, сколько нажатий клавиш потребуется для каждого имени в оптимальном порядке

WaffleCohn
источник