Скільки часу знадобиться Санта, щоб вручити подарунки?


12

Нещодавно я опублікував цей виклик , який стосується того, скільки ельфів потребує Санта для подарунків.

Завдяки збільшенню чисельності населення, Санта в цьому році трохи більше наполягає. Хоча в минулому ми працювали дуже асинхронно, ми починаємо експериментувати з тим, щоб бути все більш і більше синхронізованими. Отже, Санта повинен знати, скільки часу знадобиться йому, щоб доставити подарунки до кожного регіону із заданою кількістю ельфів.

Вага вугілля не змінювався протягом останніх двох років - він все ще важчий за подарунки, тому Санта потребує трьох ельфів на неслухняну людину в будинку і два ельфи на одного приємного людини в будинку.

Цілий рік ельфи проводять на Різдво, тому їм не потрібно відпочивати між поставками. Вони можуть доставити подарунки в один будинок за один раз, і вони повинні повернутися на санях Санти і зібрати наступний подарунок, перш ніж перейти до наступного будинку. З причин, на які я не маю права ділитися, ельфи не проводять час подорожуючи між Санями на санях і будинками (але можуть подорожувати лише тоді, коли Сани на санях на даху), а також його сани не проводять час, переходячи від будинку до будинку. (Сашком Санти робить потреби в переході від хати до хати для того , щоб зібрати паливо, але я вже говорив надто багато).

Ельфам, які доставляють подарунки, потрібно витратити чотири секунди * кожен, хто доставляє подарунки, а ельфам, які доставляють вугілля, потрібно витратити п’ять секунд * на кожну його доставку (згідно з правилами адміністрації авіації Санта, рукавички з вугільним пилом на них слід спалити негайно посадка на сани, що займає деякий час). Крім того, будинки потрібно відвідувати у порядку, який вони є на карті, зліва направо, і ельфи не можуть розпочати доставку подарунків до інших будинків, поки всі подарунки не будуть доставлені до будинку, в якому вони перебувають.

Якби ми припустили, що Санта має більше ніж достатньо ельфів для цього регіону, це займе лише стільки часу, скільки потрібно, щоб доставити подарунок комусь із неслухняного списку, 5 секунд, за будинок або 4 секунди на будинок, якщо всім приємно.

Однак, на відміну від попередніх сезонів, у цього Різдва Санта може не мати більше ніж достатньо ельфів для кожного регіону, тому 4 секунди - це абсолютний мінімальний проміжок часу *, який знадобиться для доставки подарунків до будь-якого будинку, якщо немає 0 приємних людей і 0 неслухняних людей, в цьому випадку це займе 0 секунд.

Крім того, якщо навіть в одному з будинків хтось є в неслухняному списку, Санта потребує щонайменше трьох ельфів. Якщо принаймні в одному з будинків є хтось із приємних списків, і жоден з них не має людей у ​​неслухняному списку, Санта потребує хоча б двох ельфів. Якщо жоден з будинків не відповідає різдвяному духу, будь-яка кількість ельфів (включаючи 0) займе 0 секунд.

На карті Санта будинок представлений символом a *, а кожен будинок розділений символом a +. Санта все ще використовує ті ж карти, що і в іншому виклику , але я сюди включу документацію про них.

З обох боків будинку буде номер - той, що ліворуч представляє кількість неслухняних людей у ​​домі, і той, що праворуч представляє кількість приємних людей у ​​будинку. Якщо на одній стороні немає числа, це інтерпретується як 0.

Я знаю, що це може звучати божевільно, але деякі люди "не люблять Різдво", тому іноді будинок може не мати номера з обох боків.

Одна з карт Санта може виглядати приблизно так.

1*3+2*+*5+*+4*7

Скажімо, Санта має дев’ять ельфів на своїх санях.

  1. (0s) Перший будинок має 1 непослушних та 3 приємних людей. Три ельфи доставляють вугілля, займаючи п'ять секунд, а шість - подарунки, займаючи чотири секунди. Через п’ять секунд сани Санта рухаються до наступного будинку

  2. (5s) У другому будинку є 2 неслухняних і 0 приємних людей. Шість з ельфів доставляють вугілля, займаючи п'ять секунд. Через п’ять секунд сани Санта рухаються до наступного будинку

  3. (10s) У третьому будинку є 0 неслухняних та 5 приємних людей. Вісім ельфів вручають чотири подарунки (той, що залишився позаду, не може вручити подарунок). Через чотири секунди всі ельфи повернулися, і два з них вирушають, щоб доставити інший подарунок (сани повинні чекати, коли ельфи повернуться, перш ніж вирушити до наступного будинку), зайнявши ще чотири секунди

  4. (18-ті роки) Четвертий будинок не в різдвяному дусі, тому має 0 неслухняних і 0 приємних людей, і його пропускають

  5. (18-ті роки) У п'ятому будинку є 4 неслухняних та 7 приємних людей. Це стає трохи складніше ...

    I. Усі дев'ять ельфів ідуть, щоб доставити три подарунки вугілля (залишити t + 0s, повернути t + 5s) II. Після 5-х років всі вони повернулися на сани, і троє з них вирушають, щоб доставити останній подарунок вугілля (залиште t + 5s, поверніть t + 10s), а інші шість з них відправлять три приємні подарунки (залиште t + 5s, повернути t + 9s).

    ІІІ. Через чотири секунди шість ельфів повернулися і йдуть, щоб доставити ще три приємні подарунки (залиште t + 9s, поверніть t + 13s).

    IV. Через секунду після того, як вони поїдуть, три ельфи, які доставляли подарунок вугілля, повертаються назад, і два з них від'їжджають, щоб доставити останній приємний подарунок (відпустка + 10с, повернення t + 14с)

  6. (18 + 14 = 32 секунди ) Санта закінчує доставку подарунків до цього регіону.

Як ми бачимо, Санта займає 32 секунди, щоб доставити подарунки до цього регіону. Це була надто спрощена версія однієї з карт Санти. Зазвичай карти Санта мають кілька ліній і мають квадратну форму, щоб краще вписатись у його список. Звичайна карта може виглядати приблизно так (в \nкінці кожного рядка)

1*2+*+*4+1*
2*4+3*+1*6+*
*+*+4*2+1*1
*4+*3+1*+2*3
3*10+2*+*5+*

Маючи 26 ельфів (або будь-яку більшу кількість), Санта потребує 71 секунди .
З 20 ельфами Санта потребує 76 секунд .
З 15 ельфами Санта потребує 80 секунд .
З 3 ельфами Санта потребує 288 секунд .
З 2 ельфами (або будь-якою меншою кількістю) це було б неможливо.

О, і ще одне - порядок, в якому ельфи доставляють, пред'являє справи (через різницю часу вручення подарунків неслухняним / приємним людям), тому ваш код завжди повинен виводити найменший проміжок часу, який ельфи можуть приймати для подарунка.

Виклик

Допоможіть Санта визначити, скільки часу знадобиться даній кількості ельфів, щоб доставити подарунки.

Будинки

  • Будинок представлений а *
  • Будинки розділені на +
  • Цифра зліва від будинку символізує кількість неслухняних людей (число не означає 0)
  • Число праворуч символізує кількість приємних людей (жодне число не означає 0)
  • У \nвводі можуть бути нові рядки ( ), які також слід обробляти як розділення

Ельфи

  • Санта потребує допомоги трьох ельфів для неслухняних людей (вугілля набагато важче подарунків), і цим ельфам знадобиться п'ять секунд *, щоб доставити подарунки
  • Санта потребує допомоги двох ельфів для приємних людей, і цим ельфам знадобиться чотири секунди *, щоб доставити подарунки
  • Якщо немає номерів по обидва боки будинку, Санта не відвідуватиме цей будинок, і для цього це не займе часу (люди, які не в різдвяному дусі, навіть не заслуговують вугілля)

Санта

  • Санта повинен вручати подарунки будиночкам один на один
  • Санта не може переїхати до наступного будинку, поки всі ельфи не повернуться на сани і всі подарунки не будуть доставлені до цього будинку (ми не хочемо залишати ельфів позаду, чи не так?)
  • Сані Санта не витрачає часу на пересування від будинку до будинку (знову ж таки, з причин, якими я не можу ділитися)

Що робити

Давши карту будинків та декілька ельфів, роздрукуйте, скільки часу знадобиться Санта, щоб доставити подарунки до будинків на карті.

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

Правила

  • Є два входи - карта та кількість ельфів. Вхідні дані можуть бути взяті як аргументи функції, або з STDIN або еквівалента. Якщо взяти два введення неможливо у вашій мові, тоді і лише тоді ви можете прийняти два входи як єдиний рядок введення, який обмежений деяким символом, як правило, не вводиться (не один з +*\nабо 0-9- рядок введення не може бути неоднозначним) напр ,.
  • Кількість ельфів завжди буде невід'ємним цілим числом (0 дійсне)
  • Вихід може бути або зворотним значенням функції, або надрукованим на STDOUT або еквівалентним. Якщо Санта неможливо доставити подарунки до даного регіону із заданою кількістю ельфів, ви повинні вивести послідовне негативне число або послідовне повідомлення без будь-яких чисел у ньому
  • Все, надруковане на STDERR, буде ігноровано, тому ви можете не надрукувати результат або повідомлення про помилку в STDERR
  • Ваша програма не може вийти з ладу з огляду на недійсну кількість ельфів для регіону
  • Вихід повинен становити лише загальну кількість часу, яке знадобиться Санта, щоб доставити подарунки із заданою кількістю ельфів.
  • Вихід завжди повинен бути найменшим, скільки часу потрібно ельфам для вручення подарунків
  • Вхід буде містити тільки цифри, +, *і нового рядка \n(якщо не вказано інший символ , який вхід буде включати в себе , якщо ваш язик не може приймати два входи (вид на першому правилі) )
  • Застосовуються стандартні лазівки

Випробування

"1*1", 5 elves => 5
"1*1", 3 elves => 9
"1*2", 7 elves => 5
"1*2", 5 elves => 10
"1*2", 3 elves => 13
"2*1", 8 elves => 5
"2*1", 5 elves => 9
"2*1", 3 elves => 14
"1*" , 3 elves => 5
"1*" , 2 elves => (error message)
"*1" , 2 elves => 4
"*1" , 0 elves => (error message)
"*"  , 0 elves => 0

"1*1+1*1",   5 elves => 10
"1*1+1*1",   3 elves => 18
"1*1+*+1*1", 3 elves => 18
"1*2+2*1",   8 elves => 10
"1*2+2*1",   7 elves => 14
"1*2+2*1",   6 elves => 18
"1*2+2*1",   3 elves => 27
"1*2+2*1",   2 elves => (error message)
"*+*+*+*",   2 elves => 0
"*+*+*+*",   0 elves => 0

"1*3+2*+*5+*+4*7", 9 elves => 32

(сподіваюся, у мене все це правильно)

Оцінка балів

Санта проводить кожен день, завжди переглядаючи багато речей - усі подарунки, які він збирається доставити, всі ельфи, які він має, усі будинки, які він дарує подарунки ... Для Санти найкращий різдвяний подарунок був би здатний трохи побачити щось. З цієї причини виграє найкоротше подання в байтах .

Таблиця лідерів

Це фрагмент стека, який генерує як таблицю лідерів, так і огляд переможців за мовою.

Щоб відповідь відображалась, будь ласка, почніть свою відповідь із заголовка, використовуючи наступний шаблон Markdown

## Language Name, N bytes

Де N - розмір поданих вами даних у байтах

Якщо ви хочете включити у свій заголовок кілька чисел (наприклад, пробивання старих балів або включення прапорів у кількість байтів), просто переконайтеся, що фактичний бал є останнім номером у вашому заголовку

## Language Name, <s>K</s> X + 2 = N bytes


Я думаю, що 288 повинен прочитати 281 : (1+0+0+1+2+3+1+0+0+0+4+1+0+0+1+2+3+2+0+0)*5+(2+0+4+0+4+0+6+0+0+0+2+1+4+3+0+3+10+0+5+0)*4=21*5+44*4=105+176=281(хоча мушу сказати, що я не прочитав цілого "есе"!)
Джонатан Аллан

@JonathanAllan Yea ... Я випадково витратив занадто багато часу на написання виклику ... На жаль, головне, чого не вистачає, це те, що Саня Санта повинен чекати, коли всі ельфи повернуться на борт, перш ніж переїхати до наступний будинок, тож хоча додавання всіх чисел та їх множення може спрацювати в деяких випадках, у більшості він не працює. Наприклад, з 9 ельфами будинок 4*7займає 14 секунд (це висвітлено приблизно вдвічі в «нарисі», перед введенням 2D-карти), але (4 * 5) + (7 * 4) = 48
Джодмо

Значення 288 є, наприклад, з 3 ельфами, тому їм завжди доведеться виконувати повний удар naughty*5+nice*4у кожному будинку, правда? (зауважте, що немає 4*7в цьому прикладі)
Джонатан Аллан

Чи завжди ельфи спочатку виводять вугілля з шляху (як у вашому прикладі) або вони планують ефективно? Наприклад, якби карта була 5*15і були 9ельфи, це знадобило б (мінімум) 20 секунд або 22 секунди? Дивіться ці текстові зображення, щоб побачити ілюстрацію цього прикладу.
Джонатан Аллан

EDIT вище 5*15слід прочитати 4*15.
Джонатан Аллан

Відповіді:


4

Ruby , 433 400 байт

Ну, це справді важко, тому що, як виявляється, планування ельфів є важким NP.

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

->e,h{h.split(/\+|\n/).map{|h|n,g=h.split(?*).map(&:to_i)+[0,0];return-1if(g>0&&e<2)||(n>0&&e<3);([[3,5]]*n+[[2,4]]*g).permutation.map{|j|c=[0]*e;j.map{|q|w,y=q;k=l=0;r=c.map{|x|a=b=0;c[k..e].map{|r|r<=x ?a+=1:break};(t=k+=1).times{c[t-=1]<=x ?b+=1:break};[a,b]};d=r.inject([]){|v,x|v<<l if x[0]>=w;l+=1;v}.min{|a,b|c[a]<=>c[b]};b=d-r[d][1]+1;z=c[d]+y;(b..(b+w-1)).map{|x|c[x]=z}};c.max}.min||0}.sum}

Спробуйте в Інтернеті!

Спочатку у мене були більш довгі тестові випадки, але оскільки я повторюю всі можливі перестановки для планування, то в деяких випадках це потребує довгого часу, тому я їх видалив.


2
Ласкаво просимо до PPCG! Ви напевно вибрали важкий виклик для своєї першої відповіді
Jo King

2

Java (OpenJDK 8) , 344 байти

Планування ельфів складніше, ніж я думав, тому це зайняло небагато часу, і це досить довго.

Незважаючи на це, це, безумовно, було моїм улюбленим завданням кодувати гольф!

(e,d)->{int r=0,x,y,c,p,b,g,m;for(String h:d[0].split("\\+")){d=h.split("\\*",-1);b=new Byte("0"+d[0]);g=new Byte("0"+d[1]);m=-1>>>1;for(y=1;y<=e/3&(x=(e-y*3)/2)>0;c=b/y+(b%y++<1?0:1),p=g/x+(g%x<1?0:1),x=c*5>p*4?c*5:p*4,m=x<m?x:m);for(y=0;b+g>0;b-=c,g-=p){c=e/3<b?e/3:b;x=(e-c*3)/2;p=x<g?x:g;if(c+p<1)return-1;y+=c>0?5:4;}r+=m<y?m:y;}return r;}

Спробуйте в Інтернеті (з усіма тестами)!

Пояснення;

Навчайте себе: це довгий

    int r=0,x,y,c,p,b,g,m;               // Define all the variables I need

    for(String h:d[0].split("\\+")){     // Split houses on '+' and loop through them

        d=h.split("\\*",-1);             // Split the current house on '*' using the limit
                                         // to preserve empty strings.

        b=new Byte("0"+d[0]);            // Parse the naughty (b) and nice (g) people
        g=new Byte("0"+d[1]);

        m=-1>>>1;                        // Initialise minimum time as max integer using
                                         // overflow

        for(y=1;y<=e/3&(x=(e-y*3)/2)>0;  // For each number of elves that can concurrently
                                         // deliver coal, and still leave enough elves to
                                         // deliver presents

            c=b/y+(b%y++<1?0:1),         // Determine the number of runs needed to deliver
                                         // all coal using this number of elves

            p=g/x+(g%x<1?0:1),           // Determine the number of runs needed to deliver
                                         // all presents using this number of elves

            x=c*5>p*4?c*5:p*4,           // Get the maximum time required for the
                                         // delivery of coal or presents

            m=x<m?x:m);                  // If this is less than the current minimum time,
                                         // set it as the minimum time


        for(y=0;b+g>0;b-=c,g-=p){        // While there are still people to deliver to;

            c=e/3<b?e/3:b;               // Determine the max amount of coal to deliver

            x=(e-c*3)/2;                 // Determine how many presents can be
                                         // delivered with the remaining elves.

            p=x<g?x:g;                   // If this number is more than nice people
                                         // remaining, just use the nice people remaining

            if(c+p<1)return-1;           // If no presents can be delivered, return the
                                         // error code (-1)

            y+=c>0?5:4;                  // Increase the time by 5 if coal was
                                         // delivered, and 4 if only presents

        }                                // At the end of each loop (see above)
                                         // remove the presents and coal delivered
                                         // from the number of naughty and nice houses

        r+=m<y?m:y;                      // Increment the total time by which ever
                                         // is smaller of the calculated times
    }
    return r;                            // Return the total time

NB: Ця відповідь залежить від правильності моїх виправлень у тестових випадках


Я думаю (e-y*3)/2-> e-y*3>>1зберігає байт. (Швидше за все, це стосується і (e-c*3)/2.)
Джонатан Фрех,

runTest("1*4",5,12);виходить з ладу (ви отримуєте "1*4", 5 elves => 13 FAILED. Я був вражений тим, як ваш алгоритм був такий хороший для планування в такій кількості байтів, тому я запустив його проти всіх можливих комбінацій від 0 до 7 (ельфів, неслухняних і приємних) і знайшов лише декілька, де це не вдається дайте оптимальний час. Це найменша комбінація, якщо вона не вдалася. До речі, дивовижна логіка розкладу, довго я не уявляв, як ви це зробили.
elyalvarado,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.