Коли кулі стикаються


16

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

Завдання

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

Правила

  • Введення - це список невід’ємних цілих чисел, розділених будь-яким роздільником і одним необов’язковим символом до і після. Це дійсні входи: 1 2 3 4 5 6і [1,2,3,4,5,6]. Програміст робить вибір.
  • Виведіть правдиве значення, якщо хоча б одна куля збереглась назавжди, а помилкове значення - в іншому випадку.
  • Швидкість кулі подається в одиницях за секунду.
  • Кулі рухаються одночасно і безперервно.
  • Кулі можуть стикатися при часткових зміщеннях.
  • Кілька куль, які одночасно досягають точно такого ж положення, чи то при цілісному чи частковому зміщенні від початку, стикаються одна з одною.

Приклади

На цих діаграмах Gзображено знаряддя, >кулі та *періоди, коли кулі стикаються та вибухають.

Truthy

Вхід: 0

        0123456789
Time 0 G>
     1 G>
     2 G>
   ...

Вихід: 1


Вхід: 0 0 0

        0123456789
Time 0 G>
     1 G*
     2 G>
     3 G>
     4 G>
   ...

Вихід: 1


Вхід: 1

        0123456789
Time 0 G>
     1 G >
     2 G  >
     3 G   >
   ...

Вихід: 1


Вхід: 2 1

        0123456789
Time 0 G>
     1 G> >
     2 G >  >
     3 G  >   >
     4 G   >    >
   ...

Вихід: 1


Вхід: 2 3 1

        0123456789
Time 0 G>
     1 G> >
     2 G>  >>
     3 G >    *
     4 G  >
     5 G   >
   ...

Вихід: 1


Фальсі

Вхід: 1 2 3 4 5 6

        Unit      1111111111
        01234567890123456789
Time 0 G>
     1 G>>
     2 G> *
     3 G>  >
     4 G>   > >
     5 G>    >  >>
     6 G      >   > *
     7 G            >  >
     8 G                  > >
     9 G                        >>
    10 G                              *
                  111111111122222222223
        0123456789012345678901234567890

Вихід: 0


Вхід: 1 0 0 3

        Unit
        0123456789
Time 0 G>
     1 G>>
     2 G* >
     3 G>  >
     4 G   >>
     5 G     *

(Друге зіткнення відбувається в момент часу 4.5)
Вихід:0


Вхід: 2 1 2 3 6 5

        Unit      1111111111
        01234567890123456789
Time 0 G>
     1 G> >
     2 G>>  >
     3 G> *   >
     4 G>  >    >
     5 G>     *   >
     6 G     >      >
     7 G          >   >
     8 G               >>
     9 G                *
                  1111111111
        01234567890123456789

Вихід: 0


Вхід: 2 3 6

        Unit
        0123456789
Time 0 G>
     1 G> >
     2 G>  >>
     3 G      *

Вихід: 0


чи можу я вимагати, щоб введення було обмежено, як 1<enter>2<enter>3...?
кіт

@sysreq: Це підштовхує це, але я дозволю.
El'endia Starman

Я погоджуюся з кнітопією - цей виклик злий, але я працюю над рішенням ...
zmerch

Відповіді:


4

Пітон 2, 388 392 388 346 342 336 331 байт

z=k=input();l=len(k);v=range;u=v(l)
while l<z:
 r="";o=[r]*l;z=l
 for h in v(l):
    if r:o[h-1]=o[m]=r;m=h;r=""
    for j in v(h+1,l):
     p=k[h];q=k[j];t=u[j];n=(1.0*q*t-p*u[h])/(q-p)if q-p else""if p>0 else t
     if t<=n<r<()>o[j]>=n<=o[h]:r=n;m=j
 i=0;s=o and min(o)
 while i<l:
    if o[i]==s!="":del k[i],o[i],u[i];l-=1
    else:i+=1
print l

Боже, ця річ величезна, але я вірю, що вона насправді працює. Як тільки ви бачите всі тонкощі цього, цей виклик смішно важкий.

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

Великий основний цикл під час циклу, поки вхідний список не зменшиться.

Вкладена для циклу (чи можете ви повірити, що вкладена для циклу насправді найкоротша тут?) Петлі над кожною швидкістю кулі і використовує numpy.rootsдля обчислення обчислення, в який час ця куля зіткнеться з кожною кулею, що надійде після. Тут ""використовується для позначення нескінченності (без перетину). Необхідно включити додаткову умову, щоб гарантувати, що зупинені кулі позначаються як зіткнення в момент їх появи, а не в нульовий час.

Для кожного номера ми відслідковуємо, яка куля вона потрапить якнайшвидше, якщо така є, а потім oоновлюється мінімальними часом зіткнення для залучених куль.

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

Потім ми повторюємо весь процес на кулях, що залишилися, оскільки вони, можливо, вже зможуть дістати, коли кулі, з якими вони зіткнулися, були знищені.

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

EDIT: Особлива подяка feersum за тестування тестів, які допомогли мені знайти помилки.

EDIT 2: Збережено 42 байти, розв’язавши лінійне рівняння вручну, а не використовуючи numpy, і розділивши початкові часи на окремий список та реструктуризувавши умовно.

EDIT 3: Збережено 4 байти шляхом перейменування діапазону

EDIT 4: Збережено ще 6 байт, замінивши подвійні пробіли вкладками. Також feersum був досить добрим, щоб забезпечити його реалізацію, використовуючи дроби та набори для порівняння. Я трохи пограв у нього в гольф, і він виходить на 331 байт, пов'язуючи моє рішення.

EDIT 5: збережено 5 байтів, видаливши непотрібну ініціалізацію та переписавши умовно


Ви не перевіряли приклади знову? [1, 0, 0, 3] не працює.
feersum

@feersum це був єдиний, якого я не перевіряв, dangit. але зафіксовано З ВСІМ ЦІМ ЕФФОРМОМ Я НАЙКРАЩЕ ВІДПОВІДУЮТЬ ОГЛЯДУ. : P
Кінтопія

Все ще не працює. [1, 16, 18, 20, 30] має повернутися 1.
feersum

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