Ngọn núi này được thắp sáng như thế nào? 🔥


62

Một ngọn núi được định nghĩa là một tập hợp các phân đoạn dòng có điểm đầu tiên có tọa độ (0,a)ở đâu a > 0và điểm cuối cùng có tọa độ (b,0), ở đâu b > 0. Tất cả các điểm trung gian có tọa độ y (tọa độ) lớn hơn 0. Bạn được cho các điểm trên núi được sắp xếp theo thứ tự tăng dần của tọa độ x (abscissa). Lưu ý rằng hai điểm có thể có cùng tọa độ x, tạo ra một đoạn thẳng đứng của ngọn núi. Nếu bạn được cho hai điểm có cùng tọa độ x, chúng sẽ được kết nối theo thứ tự chúng được cung cấp. Ngoài ra, có thể có những đoạn nằm ngang của ngọn núi Những đoạn nằm ngang này không được thắp sáng, không có vấn đề gì.Tất cả các tọa độ là số nguyên không âm.

Câu hỏi: tổng chiều dài của ngọn núi sẽ được thắp sáng là bao nhiêu, giả sử mặt trời là một mặt phẳng thẳng đứng vô hạn của ánh sáng nằm ở bên phải ngọn núi? Số này không cần làm tròn, nhưng nếu nó được làm tròn, bao gồm ít nhất bốn chữ số thập phân. Tôi đã bao gồm một hình ảnh: Núi Ở đây, các dòng được in đậm thể hiện các phân đoạn được thắp sáng. Lưu ý rằng trong đầu vào, P xuất hiện trước Q (PQ là đoạn thẳng đứng) nên điểm trước đó được kết nối với P chứ không phải Q.

Bạn có thể nhận đầu vào ở bất kỳ định dạng hợp lý nào, như danh sách danh sách, danh sách đơn, chuỗi, v.v.

Trường hợp thử nghiệm:

(0,3000)
(500, 3500)
(2500, 1000)
(5000,5000)
(9000,2000)
(9000,3500)
(10200,0)

Output: 6200.0000

Có hai phân đoạn sáng ở đây, như trong hình này: Trường hợp thử nghiệm Pic Cái thứ nhất có chiều dài 5000/2 = 2500 và cái thứ hai có chiều dài 3700.

Đây là , vì vậy câu trả lời ngắn nhất bằng byte sẽ thắng.


1
Gợi ý: Khi tìm độ dài của một đoạn, có ba điểm bạn cần xem xét: hai điểm cuối và điểm "chặn" nó (trong hình thứ 2, đó sẽ là (9000,3500) xác định độ dài của đoạn 3-4-5. Đặt hai điểm trên đoạn chính là (x1, y1)(x2,y2). Điểm đó là "chặn" (x3, y3). Giả sử y2 <y3 <= y1. Sau đó, độ dài của đoạn là ((y1 - y3)/(y1 - y2))*sqrt((x1 - x2)^2 + (y1 - y2)^2). Đây thực chất là công thức khoảng cách, nhân với tỷ lệ của phân khúc thực sự được sử dụng.
lận

1
Núi có thể nằm ngang?
dùng202729

Vâng, có thể có các phân đoạn ngang trên núi. Tuy nhiên, nó sẽ về 0 tại một số điểm.
lận

1
Nhưng họ có nên được thắp sáng?
dùng202729

Họ không được thắp sáng. Ánh sáng, nằm ngang hoàn hảo, chỉ có thể chạy song song với chúng và không bao giờ tấn công chúng. Tôi đã chỉnh sửa vấn đề để làm rõ điều này.
lận

Câu trả lời:


14

Python 2 ,  134 131 128 124 120 117 109  107 byte

p=input();s=0
for X,Y in p[1:]:x,y=p.pop(0);n=y-max(zip(*p)[1]);s+=n*(1+((X-x)/(y-Y))**2)**.5*(n>0)
print s

Hãy thử trực tuyến!

Lấy đầu vào dưới dạng danh sách các bộ / danh sách hai phần tử của số dấu phẩy động.

Giải trình

y1>y2for(x2,y2)(x1,y1)

Toán học - Phần nào của đoạn thẳng tiếp xúc với ánh sáng?

Một ngọn núi nghèo nàn

(x1,y1)ymmộtx(x2,y2)Lx3y1ymmộtx

x3x2-x1x3x2-x1= =y1-ymmộtxy1x3= =(y1-ymmộtx)(x2-x1)y1

L= =(y1-ymmộtx)2+x32

Bằng cách nối hai công thức, chúng ta đi đến biểu thức sau, đây là cốt lõi của phương pháp này:

L= =(y1-ymmộtx)2+((y1-ymmộtx)(x2-x1)y1)2
L= =(y1-ymmộtx)2(1+(x2-x1)2y12)

Mã - Nó hoạt động như thế nào?

p=input();s=0                             # Assign p and s to the input and 0 respectively.
for X,Y in p[1:]:                         # For each point (X, Y) in p with the first
                                          # element removed, do:
    x,y=p.pop(0)                          # Assign (x, y) to the first element of p and
                                          # remove them from the list. This basically
                                          # gets the coordinates of the previous point.
    n=y-max(zip(*p)[1])                   # Assign n to the maximum height after the
                                          # current one, subtracted from y.
    s+=n*(1+((X-x)/(y-Y))**2)**.5         # Add the result of the formula above to s.
                                 *(n>0)   # But make it null if n < 0 (if y is not the
                                          # local maxima of this part of the graph).
print s                                   # Output the result, s.

Thay đổi

  • Dần dần tối ưu hóa công thức cho mục đích chơi gôn.

  • Đã lưu 1 byte nhờ FlipTack .

  • Đã lưu 2 byte bằng cách loại bỏ điều kiện không cần thiết y>Y, vì nếu cực đại cục bộ của Y- phối hợp sau khi điểm hiện tại bị trừ ylà dương, thì điều kiện đó là dư thừa. Điều này không may làm mất hiệu lực golf của FlipTack, mặc dù.

  • Đã lưu 3 byte bằng cách thay đổi thuật toán một chút: thay vì có một biến đếm, tăng nó và theo đuôi danh sách, chúng tôi loại bỏ phần tử đầu tiên ở mỗi lần lặp.

  • Lưu được 8 byte nhờ vào ovs ; thay đổi (x,y),(X,Y)trong điều kiện vòng lặp với một list.pop()kỹ thuật.

  • Đã lưu 2 byte nhờ Ørjan Johansen (tối ưu hóa công thức một chút).


12

JavaScript, 97 byte

a=>a.reduceRight(([p,q,l=0,t=0],[x,y])=>[x,y,y>t?(y-t)/(s=y-q)*Math.hypot(x-p,s)+l:l,y>t?y:t])[2]

f=a=>a.reduceRight(([p,q,l=0,t=0],[x,y])=>[x,y,y>t?(y-t)/(s=y-q)*Math.hypot(x-p,s)+l:l,y>t?y:t])[2];
t=[[0, 3000], [500, 3500], [2500, 1000], [5000, 5000], [9000, 2000], [9000, 3500], [10200, 0]];
console.log(f(t));

(5 byte có thể được lưu, nếu lấy phiên bản đầu vào đảo ngược được coi là hợp lệ.)


10

APL + THẮNG, 48 byte

+/((h*2)+(((h←-2-/⌈\m)÷-2-/m←⌽⎕)×(⌽-2-/⎕))*2)*.5

Nhắc cho danh sách tọa độ x theo sau là danh sách tọa độ y

Giải trình

h←-2-/⌈\m difference between successive vertical maxima viewed from the right (1)

-2-/m←⌽⎕ vertical difference between points (2)

⌽-2-/⎕ horizontal difference between points (3)

Khoảng cách dọc sáng = h và khoảng cách ngang sáng là (3) * (1) / (2). Phần còn lại là Pythagoras.


Sẽ +/.5*⍨(h*2)+×⍨((h←-2-/⌈\m)÷-2-/m←⌽⎕)×⌽-2-/⎕làm việc?
Kritixi Lithos

Thật không may, phiên bản APL + WIN cũ của tôi không có nhà điều hành nên tôi không thể nói
Graham

@Cows quack Được quản lý để dùng thử trong phiên bản cũ của Dyalog Unicode (v13) và đề xuất của bạn không hoạt động
Graham

6

Swift , 190 byte

import Foundation
func f(a:[(Double,Double)]){var t=0.0,h=t,l=(t,t)
a.reversed().map{n in if l.0>=n.0&&n.1>l.1{t+=max((n.1-h)/(n.1-l.1)*hypot(n.0-l.0,n.1-l.1),0)
h=max(n.1,h)}
l=n}
print(t)}

Hãy thử trực tuyến!

Giải trình

import Foundation                  // Import hypot() function
func f(a:[(Double,Double)]){       // Main function
  var t=0.0,h=0.0,l=(0.0,0.0)      // Initialize variables
  a.reversed().map{n in            // For every vertex in the list (from right to left):
    if l.0>=n.0&&n.1>l.1{          //   If the line from the last vertex goes uphill:
      t+=max((n.1-h)/(n.1-l.1)     //     Add the fraction of the line that's above the
        *hypot(n.0-l.0,n.1-l.1),0) //     highest seen point times the length of the line
                                   //     to the total
      h=max(n.1,h)}                //     Update the highest seen point
    l=n}                           //   Update the last seen point
  print(t)}                        // Print the total

5

Python 2 , 122 120 byte

k=input()[::-1]
m=r=0
for(a,b),(c,d)in zip(k,k[1:]):
 if d>m:r+=(b>=m or(m-b)/(d-b))*((a-c)**2+(b-d)**2)**.5;m=d
print r

Hãy thử trực tuyến!


Vì chúng tôi được phép lấy danh sách các giá trị x và danh sách các giá trị y làm hai đầu vào nên tôi khá chắc chắn rằng chúng tôi có thể lấy danh sách tọa độ ngược lại, loại bỏ nhu cầu [::-1].
Jonathan Allan


1

APL (Dyalog Unicode) , 31 byte SBCS

Công dụng công thức của Graham .

Hàm tiền tố ẩn danh lấy ma trận 2 × n của dữ liệu làm đối số đúng. Hàng đầu tiên chứa các giá trị x từ phải sang trái và hàng thứ hai là các giá trị y tương ứng.

{+/.5*⍨(×⍨2-/⌈\2⌷⍵)×1+×⍨÷⌿2-/⍵}

Hãy thử trực tuyến!

{... } vô danh lambda nơi là lập luận:

2-/⍵ deltas (lit. cặp giảm trừ)

÷⌿Δx / Δy (lit. giảm phân chia dọc)

×⍨ hình vuông (nhân. selfie nhân)

1+ thêm vào đó

(Nhiều  nhân như sau với điều đó:

  2⌷⍵ hàng thứ hai của đối số (các giá trị y)

  ⌈\ chạy tối đa (chiều cao cao nhất đáp ứng cho đến bây giờ, đi từ phải sang)

  2-/ deltas của (lit. cặp giảm trừ)

  ×⍨ hình vuông (nhân. selfie nhân)

.5*⍨căn bậc hai (lit. nâng nó lên sức mạnh của một nửa)

+/ tổng


1

Thạch , 23 byte

ṀÐƤḊ_⁸«©0×⁹I¤÷⁸I¤,®²S½S

Một liên kết dyadic lấy danh sách các giá trị y ở bên trái và danh sách các giá trị x tương ứng ở bên phải (được OP cho phép rõ ràng trong các bình luận)

Hãy thử trực tuyến!

Làm sao?

Phần của phần (dốc) được thắp sáng là phần tương tự sẽ được thắp sáng nếu đó là phần thả thẳng đứng. Lưu ý rằng vì bình phương xảy ra để đánh giá độ dài dốc, độ cao tính toán trên đường đi có thể âm (cũng ở dưới độ dài chạy của độ dốc sáng được tính là âm chia cho âm).

ṀÐƤḊ_⁸«©0×⁹I¤÷⁸I¤,®²S½S - Link:list, yValues; list, xValues
 ÐƤ                     - for suffixes of the yValues:       e.g. [ 3000, 3500, 1000, 5000, 2000, 3500,    0]
Ṁ                       -   maximum                               [ 5000, 5000, 5000, 5000, 3500, 3500,    0]
   Ḋ                    - dequeue                                 [ 5000, 5000, 5000, 3500, 3500,    0]
     ⁸                  - chain's left argument, yValues          [ 3000, 3500, 1000, 5000, 2000, 3500,    0]
    _                   - subtract                                [ 2000, 1500, 4000,-1500, 1500,-3500,    0]
        0               - literal zero
      «                 - minimum (vectorises)                    [    0,    0,    0,-1500,    0,-3500,    0]
       ©                - copy to the register for later
            ¤           - nilad followed by link(s) as a nilad:
          ⁹             -   chain's right argument, xValues  e.g. [    0,  500, 2500, 5000, 9000, 9000, 10200]
           I            -   incremental differences               [  500, 2000, 2500, 4000,    0, 1200]
         ×              - multiply (vectorises)                   [    0,    0,    0,-6000000, 0,-4200000, 0]
                ¤       - nilad followed by link(s) as a nilad:
              ⁸         -   chain's left argument, yValues        [ 3000, 3500, 1000, 5000, 2000, 3500,    0]
               I        -   incremental differences               [  500,-2500, 4000,-3000, 1500,-3500]
             ÷          - divide (vectorises)                     [    0,    0,    0, 2000,    0, 1200,    0]
                  ®     - recall from the register                [    0,    0,    0,-1500,    0,-3500,    0]
                 ,      - pair (i.e. lit slope [runs, rises])     [[0, 0, 0,    2000, 0,    1200, 0], [0, 0, 0,   -1500, 0,    -3500, 0]]
                   ²    - square (vectorises)                     [[0, 0, 0, 4000000, 0, 1440000, 0], [0, 0, 0, 2250000, 0, 12250000, 0]]            
                    S   - sum (vectorises)                        [  0,   0,   0, 6250000,   0, 13690000,   0]
                     ½  - square root (vectorises)                [0.0, 0.0, 0.0,  2500.0, 0.0,   3700.0, 0.0]
                      S - sum                                     6200.0

Phiên bản đơn âm 25 byte lấy danh sách [x,y]tọa độ:

ṀÐƤḊ_«0
Z©Ṫµ®FI×Ç÷I,DzS½S

Hãy thử cái này


1
Đầu vào có thể là hai danh sách các giá trị. Tôi đã hỏi OP một lúc trước và họ nói nó ổn .
Ông Xcoder

Tôi cảm thấy như có quá nhiều s và s.
Jonathan Allan

0

Kotlin , 178 byte

fun L(h:List<List<Double>>)=with(h.zip(h.drop(1))){mapIndexed{i,(a,b)->val t=a[1]-drop(i).map{(_,y)->y[1]}.max()!!;if(t>0)t*Math.hypot(1.0,(a[0]-b[0])/(a[1]-b[1]))else .0}.sum()}

Hãy thử trực tuyến!

Phần kiểm tra là rất nhiều không chơi golf :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.