Поступово починається


13

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

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

Технічні умови

  • Кожна смуга являє собою еліпс із напів-магістральними осями на 5 одиниць довше, ніж наступна найкоротша смуга. Для простоти припустимо, що смуги мають 0 ширини.
  • Найбільш внутрішня смуга завжди починається з 0, а кожна інша вихідна точка - це додатне ціле число, що більше, або дорівнює попередній вихідній точці.
  • Введення та вихід можуть бути у будь-якому зручному та розумному форматі.
  • Вхідні дані завжди будуть цілими числами.
  • Ви повинні обчислити окружність доріжки до 0,01 одиниць від фактичного значення.
  • Вихідні дані повинні бути округлені до найближчого цілого числа (у флорі).
  • Фінішна лінія є відправною точкою для найпотаємнішого гонщика. У гонці є лише один круг.
  • Довжину осей вимірюють за допомогою найпотаємнішої смуги колії.
  • Виведення 0 для зміщення самого внутрішнього смуги необов’язкове.

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

Формат: a, b, n -> <list of offsets, excluding innermost lane>

20, 10, 5 -> 30, 61, 92, 124
5, 5, 2 -> 31
15, 40, 7 -> 29, 60, 91, 121, 152, 183
35, 40, 4 -> 31, 62, 94

Ці тестові випадки були згенеровані за допомогою наступного сценарію Python 3, в якому використовується наближення окружності еліпса, розроблений Рамануджаном:

#!/usr/bin/env python3

import math

a = 35 # semi-major axis
b = 40 # semi-minor axis
n = 4  # number of lanes
w = 5  # spacing between lanes (constant)

h = lambda a,b:(a-b)**2/(a+b)**2
lane_lengths = [math.pi*(a+b+w*i*2)*(1+3*h(a+w*i,b+w*i)/(10+math.sqrt(4-3*h(a+w*i,b+w*i)))) for i in range(n)]

print("{}, {}, {} -> {}".format(a, b, n, ', '.join([str(int(x-lane_lengths[0])) for x in lane_lengths[1:]])))

Використовуване наближення:

наближення окружності еліпса

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

доріжка


Я використовую наближення Рамануджана, як і ви. Це ми повинні робити, чи ти хочеш, щоб ми оцінили збіжність нескінченного ряду?
Адам

1
@ Adám Ви можете зробити все, що потрібно, щоб отримати необхідну точність. Наближення Рамануджана добре для багатьох значень, оскільки його похибка знаходиться на порядку h**5, що досить добре 0.01для широкого діапазону значень.
Мего

Яка хороша мінімальна точність, коли немає обмеженого розміру вводу?
feersum

Відповіді:


2

05AB1E , 43 байти

UVFXY-nXY+WZn/3*©T4®-t+/>Z*žq*5DX+UY+V})¬-ï

Пояснення

UV                                           # X = a, Y = b
  F                                   }      # n times do
   XY-n                                      # (a-b)^2
       XY+W                                  # Z = (a + b)
             /                               # divide (a-b)^2
           Zn                                # by (a+b)^2
              3*                             # multiply by 3
                ©                            # C = 3h
                       /                     # 3h divided by 
                 T                           # 10
                      +                      # +
                  4®-t                       # sqrt(4-3h)
                        >                    # increment
                         Z*žq*               # times (a + b)*pi
                              5DX+UY+V       # increase a and b by 5
                                       )     # wrap in list of circumferences
                                        ¬-   # divide by inner circumference
                                          ï  # floor
                                             # implicitly display

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


2

Haskell, 103 98 байт

c!d|h<-3*d*d/c/c=pi*c*(1+h/(10+sqrt(4-h)))
f a b n|x<-a-b=[floor$(a+b+10*w)!x-(a+b)!x|w<-[1..n-1]]

1

Python 3, 168 164 байт

Завдяки @ Adám та @Mego по -2 байти кожен

from math import*
h=lambda a,b:3*(a-b)**2/(a+b)**2;C=lambda a,b:pi*(a+b)*(1+h(a,b)/(10+sqrt(4-h(a,b))))
f=lambda a,b,n:[int(C(a+i*5,b+i*5)-C(a,b))for i in range(n)]

Функція, fяка приймає введення через аргумент і повертає список зрушень смуги руху, в тому числі 0для самої внутрішньої смуги.

Як це працює

Для цього використовується наближення Рамануджана. Ми просто визначаємо функції hта Cдля обчислення параметра та окружності, а потім віднімаємо довжину найпотаємнішої смуги від довжини поточної смуги та підлоги для всіх смуг.

Спробуйте це на Ideone


sqrt(4-3*h(a,b))коротший як (4-3*h(a,b))**.5і floorможе бути замінений на int. Виконувати це обидва засоби означає, що вам не потрібно імпортувати math.
Мего

@Mego Дякую Якщо я не дурний, чи не ті перші два однакові? Однак якщо оператор імпорту видаляється, то виникає проблема визначення pi.
TheBikingViking

Включивши в 3*ін h, ви повинні зберегти два байта.
Адам

Я зовсім пропустив те, що ви використовуєте piВи, можливо, зможете його досить жорстко кодувати. І так, перші два мають однакову довжину - я мав на увазі, без імпорту, звичайно! : P
Мего

@ Adám Дякую, що вказав на це.
TheBikingViking

1

Діалог APL , 45 байт

Підказки для n , потім для a b . Потрібно, ⎕IO←0що за умовчанням для багатьох систем.

1↓(⊢-⊃)(○+×1+h÷10+.5*⍨4-h3×2*⍨-÷+)⌿⎕∘.+5×⍳⎕

⍳⎕запит на n , тоді дайте {0, 1, 2, ..., n −1)

помножити на п'ять , щоб отримати {0, 5, 10, ..., 5 п -5}

⎕∘.+запит на і б , а потім провести складання таблицю: , +5 +10 ... +5 п -5 б , б +5, б +10 ... б +5 п −5
  
  

(... )⌿застосувати функцію дужок до кожної вертикальної пари, тобто
  f ( a , b ), f ( a +5, b +5), f ( a +10, b +10), ..., f ( a + 5 п -5, б +5 п -5) ,
  де F ( х , у ) є *

пі-раз

( x + y ) разів

1+ один плюс

h ( x , y ) [функція h буде визначена пізніше] ділиться на

10+ десять плюс

.5*⍨ квадрат-корінь

4- чотири мінуси

h← h ( x , y ), що є

три рази

2*⍨ площа с

( x - y ) ділиться на

+ х + у

(⊢-⊃) за результатом функції, застосованої до кожної пари, віднімаємо значення першого результату

1↓ видалити перший (нуль)

округлити вниз

СпробуйтеAPL онлайн!


* Процедурною мовою:

-÷+знайдіть частку різниці між і сумою х і у

2*⍨ квадрат цієї дроби

помножте цю площу на три

h←призначити цей продукт h

4- відняти цей продукт із чотирьох

.5*⍨ візьміть квадратний корінь цієї різниці

10+ додати десять до цього квадратного кореня

ділимо h на цю суму

1+ додайте один до цього дробу

помножимо цю суму на суму х і у

помножте цей добуток на pi

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