# Problema cu raptori v1.7 # # Propusa de Randall Munroe (http://xkcd.com/135/) # Rezolvata de Popescu Mihai # # Datele problemei: # Un om se afla in centrul unui triunghi echilateral cu latura de 20 de metri. # In fiecare din cele trei varfuri ale triunghiului se afla cate un raptor. # Raptorii accelereaza cu 4m/s^2 pana la viteza maxima de 25 m/s. # Raptorul de sus are un picior ranit si are viteza maxima de 10 m/s. # Omul ajunge instantaneu la viteza maxima de 6 m/s. # La ce unghi trebuie sa alerge omul ca sa stea cat mai mult timp in viata? # # Changelog: # v1.0: Initial working release # v1.1: Speed improvements # v1.2: Documentation, improved readability # v1.3: Use built-in functions # v1.4: Direct deg output # v1.5: IMPORTANT BUG FIX # v1.6: Improved speed # v1.7: Finally working! # mobil = [ coord_ox , coord_oy , viteza , max_viteza ] # r1 = [ 0.0 , 0.0 , 0.0 , 25 ] # r2 = [ 20.0 , 0.0 , 0.0 , 25 ] # r3 = [ 10.0 , 17.3205 , 0.0 , 10 ] # om = [ 10.0 , 5.7735 , 6.0 , 6 ] # Importam modulul matematica, va fi util la afisarea rezultatului. import math # Se defineste un pas de-al omului in functie de unghi. def pas_om(panta_om): # Un pas dureaza 0.0001 secunde. lungime_pas_om = om[2]*0.0001 delta_x = abs(math.cos(panta_om))*lungime_pas_om delta_y = abs(math.sin(panta_om))*lungime_pas_om om[0] = om[0] + delta_x om[1] = om[1] + delta_y # Se defineste pasul unui raptor care urmareste omul. def pas_raptor(numar_raptor): # Unghiul la care alearga raptorul panta_raptor = abs((om[1]-numar_raptor[1])/(om[0]-numar_raptor[0])) lungime_pas_raptor = numar_raptor[2]*0.0001 delta_x = math.cos(panta_raptor)*lungime_pas_raptor delta_y = math.sin(panta_raptor)*lungime_pas_raptor # Orientarea raptorului in functie de delta_x si delta_y (coordonate) dintre om si raptor. if ((om[0]-numar_raptor[0]) < 0) and ((om[1]-numar_raptor[1]) < 0): numar_raptor[0] = numar_raptor[0] - delta_x numar_raptor[1] = numar_raptor[1] - delta_y elif ((om[0]-numar_raptor[0]) >= 0) and ((om[1]-numar_raptor[1]) < 0): numar_raptor[0] = numar_raptor[0] + delta_x numar_raptor[1] = numar_raptor[1] - delta_y elif ((om[0]-numar_raptor[0]) < 0) and ((om[1]-numar_raptor[1]) >= 0): numar_raptor[0] = numar_raptor[0] - delta_x numar_raptor[1] = numar_raptor[1] + delta_y else: numar_raptor[0] = numar_raptor[0] + delta_x numar_raptor[1] = numar_raptor[1] + delta_y # Daca viteza lui nu a ajuns la maximum, atunci accelereaza. if numar_raptor[2] < numar_raptor[3]: numar_raptor[2] = numar_raptor[2] + 0.0004 # Dictionarul cu rezultatele rezultate = {} # Omul incepe cu directie orizontala, in sensul pozitiv al axei ox si termina cu orientarea la 1 radian (57.29 grade) panta_om = 0 while panta_om <= 1: # Se reseteaza datele problemei (coordonate, viteze) numar_pasi = 0 r1 = [0.0,0.0,0.0,25] r2 = [20.0,0.0,0.0,25] r3 = [10.0,17.3205,0.0,10] om = [10.0,5.7735,6.0,6] # TODO: simplifica urmatoarea linie. while not ((abs(r1[0]-om[0]) <= 0.002 and abs(r1[1]-om[1]) <= 0.002) or (abs(r2[0]-om[0]) <= 0.002 and abs(r2[1]-om[1]) <= 0.002) or (abs(r3[0]-om[0]) <= 0.002 and abs(r3[1]-om[1]) <= 0.002)): # Cat timp raptorii nu au prins omul, se fac pasi succesivi. pas_om(panta_om) numar_pasi = numar_pasi + 1 pas_raptor(r1) pas_raptor(r2) pas_raptor(r3) print panta_om,numar_pasi # Se adauga in dictionar unghiul la care alearga omul si timpul de supravietuire. rezultate[panta_om] = numar_pasi # Creste unghiul cu 0.001 rad. panta_om = panta_om + 0.001 # Cauta cel mai mare timp de supravietuire si afiseaza pe ecran unghiul respectiv. print 'Unghiul la care alearga omul este',math.degrees(max(rezultate, key = lambda x: rezultate.get(x))),'grade.'