ภูเขานี้สว่างแค่ไหน? 🔥


62

ภูเขาถูกกำหนดให้เป็นชุดของส่วนของเส้นตรงที่มีจุดแรกมีพิกัด(0,a)ที่a > 0และมีจุดสุดท้ายมีพิกัดที่(b,0) b > 0ทุกจุดกลางมีพิกัด y (ประสานงาน) มากกว่า 0 อย่างเคร่งครัดคุณจะได้รับคะแนนบนภูเขาเรียงตามลำดับจากน้อยไปมากพิกัด x (abscissa) โปรดทราบว่าจุดสองจุดสามารถมีพิกัด x เดียวกันทำให้เกิดส่วนแนวตั้งของภูเขา หากคุณได้รับสองจุดที่มีพิกัด x เดียวกันพวกเขาควรจะเชื่อมต่อตามลำดับที่ได้รับ นอกจากนี้ยังสามารถมีส่วนแนวนอนของภูเขาส่วนแนวนอนเหล่านี้จะไม่สว่างไม่ว่าอะไร พิกัดทั้งหมดเป็นจำนวนเต็มลบ

คำถาม: ความยาวทั้งหมดของภูเขาที่จะส่องสว่างคืออะไรสมมติว่าดวงอาทิตย์เป็นระนาบแนวตั้งที่ไม่มีที่สิ้นสุดของแสงที่ตั้งอยู่ทางด้านขวาของภูเขา? หมายเลขนี้ไม่จำเป็นต้องปัดเศษ แต่ถ้าปัดเศษให้ใส่ทศนิยมอย่างน้อยสี่ตำแหน่ง ฉันได้รวมรูปภาพ: ที่ ภูเขา นี่เส้นที่เป็นตัวหนาแสดงถึงกลุ่มที่สว่าง โปรดทราบว่าในอินพุต P จะปรากฏขึ้นก่อนหน้า Q (PQ เป็นส่วนของเส้นแนวตั้ง) ดังนั้นจุดก่อนหน้านี้เชื่อมต่อกับ P ไม่ใช่ Q

คุณสามารถป้อนข้อมูลในรูปแบบที่เหมาะสมเช่นรายการ, รายการเดียว, สตริง ฯลฯ

กรณีทดสอบ:

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

Output: 6200.0000

ที่นี่มีสองส่วนสว่างขึ้นดังที่แสดงในภาพนี้: กรณีทดสอบ Pic ส่วนแรกมีความยาว 5,000/2 = 2500 และกลุ่มที่สองมีความยาว 3700

นี่คือดังนั้นคำตอบที่สั้นที่สุดในหน่วยไบต์ชนะ


1
คำแนะนำ: เมื่อค้นหาความยาวของเซกเมนต์มีสามจุดที่คุณต้องพิจารณา: จุดปลายสองจุดและจุดที่ "บล็อก" มัน (ในภาพที่ 2 นั่นคือ (9000,3500) ซึ่งกำหนดความยาว ของส่วน 3-4-5. ให้จุดสองจุดในส่วนหลักจะเป็น(x1, y1)และ(x2,y2). จุดซึ่งเป็น "การปิดกั้น" มันเป็น(x3, y3). สมมติ y2 <y3 <= y1. แล้วความยาวของส่วนที่เป็น((y1 - y3)/(y1 - y2))*sqrt((x1 - x2)^2 + (y1 - y2)^2). นี้เป็นหลัก สูตรระยะทางคูณด้วยสัดส่วนของส่วนที่ใช้จริง
หัวเรือใหญ่

1
อาจเป็นแนวนอนหรือไม่
user202729

ใช่อาจมีส่วนแนวนอนบนภูเขา อย่างไรก็ตามมันจะไปที่ 0 ในบางจุด
rigged

1
แต่พวกเขาควรจะสว่าง?
user202729

พวกเขาไม่สว่าง แสงที่อยู่ในแนวนอนสมบูรณ์แบบสามารถวิ่งขนานไปกับพวกมันเท่านั้น ฉันแก้ไขปัญหาเพื่อชี้แจงสิ่งนี้
rigged

คำตอบ:


14

Python 2 ,  134 131 128 124 120 117 109  107 ไบต์

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

ลองออนไลน์!

รับอินพุตเป็นรายการของ tuples / รายการสององค์ประกอบของตัวเลขทศนิยม

คำอธิบาย

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

คณิตศาสตร์ - ส่วนใดของส่วนของเส้นที่สัมผัสกับแสง

ภูเขาที่ดึงได้ไม่ดี

(x1,y1)ymax(x2,y2)Lx3y1ymax

x3x2x1x3x2x1=y1ymaxy1x3=(y1ymax)(x2x1)y1

L=(y1ymax)2+x32

เมื่อเข้าร่วมทั้งสองสูตรเราได้มาถึงนิพจน์ต่อไปนี้ซึ่งเป็นแกนหลักของวิธีการนี้:

L=(y1ymax)2+((y1ymax)(x2x1)y1)2
L=(y1ymax)2(1+(x2x1)2y12)

รหัส - ทำงานอย่างไร

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.

การเปลี่ยนแปลง

  • ปรับสูตรให้เหมาะสมสำหรับการเล่นกอล์ฟ

  • ที่บันทึกไว้ 1 ไบต์ขอบคุณที่FlipTack

  • บันทึก 2 ไบต์โดยลบเงื่อนไขที่ไม่จำเป็นy>Yออกเนื่องจากถ้าค่าสูงสุดในพื้นที่ของY- coordinate หลังจากจุดปัจจุบันที่ถูกลบออกyเป็นค่าบวกเงื่อนไขนั้นจะซ้ำซ้อน น่าเสียดายที่นี่ทำให้กอล์ฟของ FlipTack เป็นโมฆะ

  • บันทึก 3 ไบต์ด้วยการเปลี่ยนอัลกอริทึมเป็นบิต: แทนที่จะมีตัวแปรตัวนับเพิ่มขึ้นและเพิ่มรายการเราจึงลบองค์ประกอบแรกในแต่ละการวนซ้ำ

  • บันทึก 8 ไบต์ขอบคุณovs ; การเปลี่ยนแปลง(x,y),(X,Y)ในสภาพลูปด้วยlist.pop()เทคนิค

  • บันทึก 2 ไบต์ขอบคุณØrjan Johansen (ปรับสูตรให้เหมาะสมเล็กน้อย)


12

JavaScript, 97 ไบต์

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 ไบต์อาจถูกบันทึกไว้หากการป้อนข้อมูลเวอร์ชันย้อนกลับถือว่าใช้ได้)


10

APL + WIN, 48 ไบต์

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

แสดงรายการของพิกัด x ตามด้วยรายการพิกัด y

คำอธิบาย

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)

ระยะทางแนวตั้งที่สว่าง = h และระยะทางแนวนอนที่สว่างคือ (3) * (1) / (2) ส่วนที่เหลือคือ Pythagoras


จะ+/.5*⍨(h*2)+×⍨((h←-2-/⌈\m)÷-2-/m←⌽⎕)×⌽-2-/⎕ทำงานอย่างไร
Kritixi Lithos

น่าเสียดายที่เวอร์ชันเก่าของ APL + WIN ของฉันไม่มีโอเปอเรเตอร์ดังนั้นฉันจึงไม่สามารถพูดได้
Graham

@Cows ต้มตุ๋นจัดการให้ลองใน Dyalog Unicode รุ่นเก่า (v13) และข้อเสนอแนะของคุณใช้งานได้
เกรแฮม

6

Swift , 190 ไบต์

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

ลองออนไลน์!

คำอธิบาย

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 bytes

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

ลองออนไลน์!


เนื่องจากเราได้รับอนุญาตให้ใช้รายการของค่า x และรายการค่า Y [::-1]เป็นสองอินพุตผมค่อนข้างมั่นใจว่าเราอาจจะใช้รายการพิกัดในกลับเป็นลบความจำเป็นในการ
Jonathan Allan

2

Python 2 , 89 ไบต์

M=t=0
for x,y in input()[::-1]:
 if y>M:t+=(y-M)*abs((x-X)/(y-Y)+1j);M=y
 X,Y=x,y
print t

ลองออนไลน์!

ใช้เวลาในรายการคู่ลอย ตามออกวิธีการแก้ปัญหาของ OVS


คิดว่าเราสามารถใช้รายการย้อนกลับ (เราได้รับอนุญาตให้ใช้ x และ y เป็นรายการที่แยกต่างหาก) [::-1]เพื่อให้คุณสามารถวาง
Jonathan Allan

1

APL (Dyalog Unicode) , 31 ไบต์SBCS

ใช้สูตรของเกรแฮม

ฟังก์ชั่นคำนำหน้าแบบไม่ระบุชื่อใช้เมทริกซ์ 2 × n ของข้อมูลเป็นอาร์กิวเมนต์ที่ถูกต้อง แถวแรกมีค่า x จากขวาไปซ้ายและแถวที่สองมีค่า y ที่สอดคล้องกัน

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

ลองออนไลน์!

{} แลมบ์ดานิรนามซึ่งเป็นที่ถกเถียงกันอยู่:

2-/⍵ เดลตา (จุดคู่ลบด้วยการลด)

÷⌿ΔxΔy (ลดการแบ่งส่วนแนวตั้ง)

×⍨ สแควร์ (เซลฟี่ทวีคูณสว่าง)

1+ หนึ่งเพิ่มไปที่

(...  คูณสิ่งต่อไปนี้ด้วย:

  2⌷⍵ อาร์กิวเมนต์แถวที่สอง (ค่า y)

  ⌈\ วิ่งสูงสุด (พบความสูงสูงสุดจนถึงปัจจุบันจากขวา)

  2-/ เดลต้าของ (จุดคู่ลดลบ)

  ×⍨ สแควร์ (เซลฟี่ทวีคูณสว่าง)

.5*⍨สแควร์รูท (เพิ่มขึ้นยกกำลังครึ่ง)

+/ รวม


1

เยลลี่ 23 ไบต์

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

ลิงก์ dyadic รับรายการค่า y ทางด้านซ้ายและรายการค่า x ตามลำดับทางด้านขวา (ตามที่ OP อนุญาตอย่างชัดเจนในความคิดเห็น)

ลองออนไลน์!

อย่างไร?

เศษส่วนของส่วน (ลาด) ที่ติดไฟเป็นเศษส่วนเดียวกับที่จะติดถ้ามันเป็นแนวตั้งลดลง โปรดทราบว่าเนื่องจากการยกกำลังสองเกิดขึ้นเพื่อประเมินความยาวของความลาดชันความสูงที่คำนวณไปตามทางอาจเป็นค่าลบ

ṀÐƤḊ_⁸«©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

รุ่น monadic ขนาด 25 ไบต์รับรายการ[x,y]พิกัด:

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

ลองอันนี้.


1
อินพุตสามารถเป็นสองรายการของค่า ฉันเคยถาม OP สักพักแล้วและพวกเขาก็บอกว่ามันโอเค
Mr. Xcoder

ฉันรู้สึกเหมือนมีมากเกินไปและs
Jonathan Allan

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.