Aşamalı Başlangıçlar


13

Yarışçıların kavisli bir pistin en az bir turunu döndürdüğü yarışlarda, her yarışçı için başlangıç ​​pozisyonları kademelendirilir, böylece her yarışçı pist boyunca aynı mesafeyi dolaşır (aksi takdirde, en içteki şeritteki yarışçı büyük bir avantaja sahip olur. ).

Eliptik bir parkurun ana ve küçük eksenlerinin (veya isterseniz yarı majör ve yarı minör) uzunlukları ve parkurdaki şerit sayısı göz önüne alındığında, en içteki şeridin her bir şeridin başlangıç ​​noktasından uzaklığı sendelemek gerekir.

Özellikler

  • Her şerit, bir sonraki en kısa şeritten 5 birim daha uzun yarı eksenleri olan bir elipstir. Basitlik için, şeritlerin 0 genişliğine sahip olduğunu varsayın.
  • En içteki şerit her zaman 0'dan başlar ve diğer her başlangıç ​​noktası, önceki başlangıç ​​noktasından daha büyük veya ona eşit pozitif bir tamsayıdır.
  • Giriş ve çıkış herhangi bir uygun ve makul biçimde olabilir.
  • Girişler her zaman tamsayı olacaktır.
  • Parkurun çevresini, gerçek değerin 0,01 birimi içinde hesaplamanız gerekir.
  • Çıkışlar en yakın tamsayıya (yuvarlanmış) yuvarlanmalıdır.
  • Bitiş çizgisi, en içteki yarışçı için başlangıç ​​noktasıdır. Yarışta sadece bir tur var.
  • Eksenlerin uzunlukları, rayın en iç şeridi kullanılarak ölçülür.
  • En içteki şerit ofseti için 0 çıktısı almak isteğe bağlıdır.

Test Durumları

Biçim: 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

Bu test senaryoları, Ramanujan tarafından tasarlanan bir elipsin çevresinin yaklaşık bir tahminini kullanan aşağıdaki Python 3 betiği ile oluşturuldu:

#!/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:]])))

Kullanılan yaklaşım:

elips çevresi yaklaşımı

Son olarak, ofsetlerin hesaplamalarını anlamak için yararlı bir diyagram:

Izlemek


Ramanujan'ın yaklaşımını senin gibi kullanıyorum. Yapmamız gereken şey bu mu yoksa sonsuz dizinin yakınsamasını değerlendirmemizi ister misiniz?
Adám

1
@ Adám Gerekli hassasiyeti elde etmek için ne gerekiyorsa yapabilirsiniz. Ramanujan yaklaşımı birçok değer için iyidir, çünkü hatası sıralıdır h**5, bu da 0.01geniş bir değer aralığı için oldukça altındadır .
Mego

Giriş boyutuna bağlı olmadığında minimum doğruluk ne işe yarar?
feersum

Yanıtlar:


2

05AB1E , 43 bayt

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

açıklama

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

Çevrimiçi deneyin!


2

Haskell, 103 98 bayt

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 bayt

Her biri -2 baytlık @ Adám ve @Mego'ya teşekkürler

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

Bağımsız fdeğişken aracılığıyla girdi alan ve 0en içteki şerit dahil olmak üzere şerit ofsetleri listesini döndüren bir işlev .

Nasıl çalışır

Bu Ramanujan'ın yaklaşımını kullanır. Sadece fonksiyonları tanımlarız hve Cparametre ve çevresini hesaplamak için, daha sonra tüm şeritler için en içteki şeridin uzunluğunu geçerli şeridin ve zeminin uzunluğundan çıkarırız.

Ideone üzerinde deneyin


sqrt(4-3*h(a,b))olarak kısadır (4-3*h(a,b))**.5ve floorile değiştirilebilir int. Bunların her ikisini de yapmanız, içe aktarmanız gerekmediği anlamına gelir math.
Mego

@Mego Teşekkürler. Aptal olmadıkça, ilk ikisi aynı uzunlukta değil mi? Ancak, import ifadesi kaldırılırsa, pi tanımlama sorunu vardır.
TheBikingViking

Dahil ederek 3*in h, iki bayt kaydetmek gerekir.
Adam

Kullandığınızı tamamen özledim piYeterince hassas bir şekilde kodlayabilirsiniz. Ve evet, ilk ikisi aynı uzunlukta - elbette ithalat olmadan demek istedim! : P
Mego

@ Adám Bunu işaret ettiğiniz için teşekkürler.
TheBikingViking

1

Dyalog APL , 45 bayt

İçin İstemler n daha sonra da, bir b . ⎕IO←0Birçok sistemde varsayılan olanı gerektirir .

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

⍳⎕n için sor , sonra {0, 1, 2, ..., n −1) ver

çok-katlı beş almak {0, 5, 10, ..., 5 , n -5}

⎕∘.+istemi bir ve b : sonra ilave bir masasına
  bir , bir + 5, bir + 10, ... bir +5 n -5
  b , b +5, b +10, ... b + 5 n -5

(... )⌿parantez içine alınmış işlevi her dikey çifte uygulayın, yani
  f ( a , b ), f ( a +5, b +5), f ( a +10, b +10), ..., f ( a + 5 n -5, b +5 n -5)
  burada f ( x , y ) 'dir *

pi kez

( x + y ) kez

1+ bir artı

h ( x , y ) [ h işlevi daha sonra tanımlanacak] bölü

10+ on artı

.5*⍨ kare kökü

4- dört eksi

h← h ( x , y ), yani

üç kere

2*⍨ karesi

( x - y ) bölü

+ x + y

(⊢-⊃) her bir çifte uygulanan fonksiyonun sonucu olarak, ilk sonucun değerini çıkarın

1↓ ilkini kaldır (sıfır)

aşağı yuvarlama

TryAPL çevrimiçi!


* Usul dilinde:

-÷+x ve y arasındaki farkın ve toplamının bir kısmını bul

2*⍨ o kesirin karesini al

o kareyi üçle çarp

h←bu ürünü h

4- bu ürünü dörtten çıkart

.5*⍨ bu farkın karekökünü al

10+ o karekökü on ekle

h'yi bu tutara böl

1+ o kesire bir tane ekle

bu toplamı x ve y toplamıyla çarpın

bu ürünü pi ile çarp

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.