Раньше я решал головоломки типа «гольф», как ты, но потом взял стрелу в колено.


18

Получение удара в колено стрелами, кажется, травма выбора прямо сейчас. В связи с этим я предлагаю следующий вызов для гольфа.

У вас есть искатель приключений, который выглядит так:

  O
 /|\
/ | \
  |
  |
 / \
/   \

Учитывая текстовый файл, который содержит один лук (нарисованный как }символ), набор стен (нарисованный как #символы) и один искатель приключений, напишите наименьший код, который вычисляет угол и начальную скорость, с которой вы должны стрелять, чтобы поразить он в колене.

Предположим следующее:

  • Каждый символ в файле 0,5 х 0,5 метра.
  • Стрелка стреляет из центра }, то есть смещение0.25m, 0.25m
  • Гравитация 10ms^-2
  • Стрелка весит 0.1kg
  • Стрелка - это точка, т.е. столкновения происходят только тогда, когда координата стрелки входит в один из блоков.
  • Максимальная начальная скорость 50m/s
  • Угол может быть между 0 (прямо вверх) и 180 (прямо вниз)
  • Удар по любой части ноги авантюриста считается ударом по колено.
  • Стена ( #персонаж) занимает целый блок размером 0,5 х 0,5 м.
  • Стрелка может перемещаться над «вершиной» файла, но ничто не мешает вводу начинаться с верхнего ряда #символов.
  • Вы не можете проникнуть сквозь стены со стрелами.
  • Попадание любой другой части искателя приключений не допускается!
  • Вы должны показать ошибку, если ударить его в колено невозможно.

Пример ввода:

                                 #                        
}                                                     O   
                        #                            /|\  
                                                    / | \ 
            #                                         |   
                            #                         |   
                                                     / \  
                                                    /   \  

Не стесняйтесь задавать вопросы, если вам нужно :)


1
Может ли стрелка перемещаться «над» областью, отображаемой в текстовом файле?
JB

2
Сколько людей вы знаете, кто выше 3 метров? : P
Питер Тейлор

@JB - Да, но ничто не мешает вводу, начинающемуся с большой строки #############...
Полином

2
@PeterTaylor - Все знают, что люди в ролевых играх непропорционально огромны;)
Полином

2
Вес стрелки избыточен?
Пол Р

Ответы:


11

Питон, 599 символов

import os,sys
from math import*
I=os.read(0,999)
O=[]
h=v=0
for i in I:
 if'#'==i:O+=[(h,v,h+1,v+1),(h+1,v,h,v+1)]
 if'O'==i:O+=[(h,v+1,h-2,v+3)];T=(h,v+5,h-2,v+7)
 if'}'==i:e=h+.5;c=v+.5
 h+=1
 if'\n'==i:v+=1;h=0

def X(K,L):
 A,B,C=K;p=L[0];q=L[2]-p;r=L[1];s=L[3]-r;A,B,C=A*q*q,2*A*p*q+B*q-s,A*p*p+B*p+C-r;d=B*B-4*A*C
 return 0 if d<0 else any(0<x<1 for x in[(sqrt(d)-B)/2/A,(-sqrt(d)-B)/2/A])

R=range(1,999)
for v in R:
 for z in R:
  z*=pi/999;d=v*sin(z)/10;b=-v*cos(z)/10
  K=20/d/d,b/d-40*e/d/d,c+20*e*e/d/d-b*e/d
  if X(K,T)and not any(X(K,x)for x in O):print v/2,z;sys.exit(0)
print'ERROR'

Процедура X(K,L)принимает параболу, K=(a,b,c)представляющую y = ax ^ 2 + bx + c, и отрезок, L=(a,b,c,d)представляющий отрезок между (a, b) и (c, d) . Оба препятствия ( O) и цель ( T) представлены в виде отрезков. Все расстояния масштабируются в 2 раза.

Пример ввода дает следующую траекторию (по умолчанию минимальная скорость):

  --                             #          --            
--                                            -       O   
                        #                      -     /|\  
                                                -   / | \ 
            #                                    -    |   
                            #                     -   |   
                                                   - / \  
                                                    -   \  

Вы можете повернуть вспять, Rчтобы получить максимальную скорость пути:

                                 #                        
-------------                                         O   
             -----------#                            /|\  
                        --------                    / | \ 
            #                   -------               |   
                            #          -----          |   
                                            -----    / \  
                                                 -----  \  

Хорошая работа. Единственная жалоба заключается в том, что ограничение размера ввода составляет 999 байт. Это вполне может быть больше, учитывая потенциальный размер этих рисунков ASCII. 9999 будет более разумным, за счет одного персонажа. (хотя в этот момент вы могли бы также сделать , 8**5чтобы получить 64kb)
Полиномиальный

Довольно , что вы могли бы сохранить , что один символ путем назначения w=v+1и замен 3 экземпляров v+1с w. Я не пишу много кода на Python, поэтому могу ошибаться.
Полином
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.