Домашнє завдання з математики четвертого класу за тиждень: найефективніший продавець подорожей


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, хороший момент. Я відповідно скоригував завдання.
Майкл Стерн

1
Чи починається шлях у будь-якого друга?
xnor

1
Чи можу я визначити формат рядків вводу та виводу? Чи вхід як "[0, 5, 7, 13, 16, 17], 62"і вихід "(7, 16, 0, 17, 5, 13)"добре?
Логічний лицар

1
@Geobits просто неохайність з мого боку. Виправлено.
Майкл Стерн

Відповіді:


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

Математика, 55 або 90 байт

Математика ви сказали? ;)

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). Відстані між ними повинні бути передані функції, як ви робите у своєму рішенні.
Майкл Стерн

@MichaelStern Я додав версію, яка повертає масив рядків. Він підтримує будь-яку кількість позицій у списку, але після Zпродовжить наступні символи ASCII (не те, що ви хочете запустити мій код на n> 20 все одно: D).
Мартін Ендер

5

Python 2, 154 148 байт

(або 118 байт для загального рішення)

Ця програма приймає рядок зі списком і цілим числом на зразок '[0, 5, 7, 13, 16, 17], n' на stdin і друкує шлях на виході довжини 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

Джерело вимоги до ОП перед мініфікатором:

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

Дякуємо за пораду щодо імпорту. Я протистояти встановленню py3 та перетворенню бази мого коду. Я чекаю, поки кожен третій модуль, який я використовую, стане доступним та стабільним під py3 (я використовую багато старих і незрозумілих).
Логічний лицар

Чи можете ви налаштувати так, щоб він відповідав літерами, а не лише місцями?
Майкл Стерн

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

(Я сподіваюся, що цей формат вводу-виводу нормально ...)

Як це робиться:

(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()в Octave 3.6.2 на ideone.com виникають проблеми з вектором рядків.
Олексій А.

Цікаво. Я маю 3.8.1 локально.
dcsohl

2

Матлаб (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
>> 

Матлаб (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

Матлаб (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і видаліть позиційну частину.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.