В шахматном порядке

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:]])))

Используемое приближение:

аппроксимация окружности эллипса

Наконец, вот полезная диаграмма для понимания расчетов смещений:

отслеживать

Mego
источник
Я использую приближение Рамануджана, как вы. Это то, что мы должны делать, или вы хотите, чтобы мы оценили сходимость бесконечного ряда?
Адам
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

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

Emigna
источник
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]]
Damien
источник
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

TheBikingViking
источник
sqrt(4-3*h(a,b))короче (4-3*h(a,b))**.5, и floorможет быть заменен на int. Выполнение этих двух действий означает, что вам не нужно импортировать math.
Мего
@ Мего Спасибо. Если я не глуп, разве эти первые два не имеют одинаковую длину? Однако если оператор import удаляется, возникает проблема определения числа pi.
TheBikingViking
Включая 3*в h, вы должны сохранить два байта.
Адам
Я полностью пропустил, что вы используете. piВозможно, вы сможете закодировать его с достаточной точностью. И да, первые два имеют одинаковую длину - я имел в виду без импорта, конечно! : P
Mego
@ Adám Спасибо за указание на это.
TheBikingViking
1

Dyalog APL , 45 байт

Запросы на п , то для в б . Требуется ⎕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 ( х , у ) является *

пи раз

( х + у ) раз

1+ один плюс

h ( x , y ) [функция h будет определена позже], разделенная на

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

.5*⍨ квадратный корень из

4- четыре минуса

h← h ( x , y ), что

три раза

2*⍨ площадь

( х - у ) делится на

+ х + у

(⊢-⊃) на результат функции, примененной к каждой паре, вычтите значение первого результата

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

округлить

Попробуй APL онлайн!


* На процедурном языке:

-÷+найти долю разницы между и суммой х и у

2*⍨ возвести в квадрат эту дробь

умножьте эту площадь на три

h←назначить этот продукт ч

4- вычесть этот продукт из четырех

.5*⍨ взять квадратный корень из этой разницы

10+ добавить десять к этому квадратному корню

разделить h на эту сумму

1+ добавить один к этой фракции

умножьте эту сумму на сумму х и у

умножить этот продукт на пи

Адам
источник