এই ঘরটি কেমন জ্বলছে? 🔥 pt। 1


25

এই প্রশ্নের সাথে সম্পর্কিত ।

একটি কক্ষটি দ্বি-মাত্রিক স্থানাঙ্কের আদেশকৃত তালিকা হিসাবে প্রকাশিত, একটি (অগত্যা উত্তল নয়) অ-ছেদযুক্ত বহুভুজ হিসাবে সংজ্ঞায়িত করা হয়েছে। ঘরের অভ্যন্তরে একটি নির্দিষ্ট পয়েন্টে একটি পর্যাপ্ত উজ্জ্বল লাইটবুল্ব স্থাপন করা হয়েছে এবং প্রতিটি দিকের আলো আলোকিত করে। আপনার কাজটি হ'ল ঘরের মোট আলোকিত অঞ্চল সন্ধান করা। আপনি কোনও যুক্তিসঙ্গত বিন্যাসে ইনপুট নিতে পারেন। বহুভুজ / ঘরের পয়েন্টগুলির পাশাপাশি আলোর উত্সের স্থানাঙ্কগুলি যুক্তিযুক্ত সংখ্যা। এগুলি ঘড়ির কাঁটায় বা ঘড়ির কাঁটার বিপরীতে নেওয়া যেতে পারে, উভয় ফর্ম্যাটটি ভাল। সমস্যার পরীক্ষার কেসটি ঘড়ির কাঁটার বিপরীতে দেওয়া হয়।

নীচের ছবিতে দুটি উদাহরণ ঘর দেখানো হয়েছে, যেখানে বেগুনি বিন্দু আলোর উত্সকে উপস্থাপন করে এবং ছায়াযুক্ত অঞ্চল আলোকিত অঞ্চলকে উপস্থাপন করে।আলোকিত কক্ষের একটি অঙ্কন - ছায়াযুক্ত অঞ্চল আলোকিত হয়

পরীক্ষা ক্ষেত্রে:

(1/2, 18)
(1,3)
(5,1/2)
(7,5)
(12,7)
(16,3)
(15,11)
(8,19)
(3,7)
Light source located at (5,8)
Answer: 815523/6710 ≈ 121.538

এখানে সেই পরীক্ষার মামলার সমাধানের একটি গ্রাফিকাল চিত্র তুলে ধরা হচ্ছে। দুটি বহু পয়েন্ট যা মূল বহুভুজের উপর নয় এমন সমাধানটিকে সংজ্ঞায়িত করে সেগুলি হ'ল (55/61, 363/61) এবং (856/55, 357/55)। এখানে চিত্র বর্ণনা লিখুন

এই সূত্রটি অঞ্চলটি গণনা করতে সহায়ক হতে পারে। https://en.wikipedia.org/wiki/Shoelace_formula

যেহেতু এটি , তাই বাইটের মধ্যে সংক্ষিপ্ততম কোডটি জয়ী।


এই কৌতূহলের জন্য, ভাগ 2 পোস্ট করতে কিছুটা সময় নিতে পারে কারণ ছবি আঁকার জন্য এটি আমাকে চিরকালের জন্য নিয়ে যাবে, এবং আমি কীভাবে এটি সমাধান করতে জানি না।
কারচুপি করা হয়েছে

বহুভুজ / ঘরের পয়েন্টগুলির পাশাপাশি আলোর উত্সের স্থানাঙ্কগুলি যুক্তিযুক্ত সংখ্যা।
কারচুপি করা হয়েছে

শীর্ষবিন্দু সংখ্যার উপরের উপরের বাউন্ড বা আপনার প্রোগ্রামটি তাত্ত্বিকভাবে সীমাহীন সংখ্যা পরিচালনা করতে সক্ষম হওয়া উচিত? এছাড়াও, আপনার কোড-গল্ফ ট্যাগটি ভেঙে গেছে। এটি[tag:code-golf]
ভেসকা

3
আহ, ভাল জুতার ফর্মুলা ! যাইহোক, আমাদের কাছে ম্যাথজ্যাক্স রয়েছে সুতরাং আপনার কোনও সূত্রটি চিত্র হিসাবে এম্বেড করার দরকার নেই।
জিউসেপ

1
হ্যাঁ, তাদের পরে ঘড়ির কাঁটার অর্ডার দেওয়ার গ্যারান্টি দেওয়া যেতে পারে। পরীক্ষার কেসটি ঘড়ির কাঁটার বিপরীতে অর্ডার করা হয়, তবে আমি মনে করি এটি "কোনও যুক্তিসঙ্গত বিন্যাসের" অধীনে পড়েছে
কারচুপি করা হয়েছে

উত্তর:


12

পাইথন 3 , 388 398 408 409 415 417 493 বাইট


এটি আরও নির্ভুল করতে, বৃদ্ধি করুন n

from random import*
u=uniform
c=lambda A,B,C:(C[1]-A[1])*(B[0]-A[0])>(B[1]-A[1])*(C[0]-A[0])
I=lambda A,B,C,D:c(A,C,D)!=c(B,C,D)and c(A,B,C)!=c(A,B,D)
def a(l,v,n=9**6,s=0):
 g=lambda i:(min(x[i]for x in v),max(x[i]for x in v))
 for _ in'x'*n:
  h=((u(*g(0)),u(*g(1))),l);s+=any([I(*f,*h)for f in list(zip(v,v[1:]+[v[0]]))])^1
 return(abs(g(0)[0]-g(0)[1])*abs(g(1)[0]-g(1)[1]))*float(s/n)

বেসিক মন্টি-কার্লো পদ্ধতির। নীচে তালিকাভুক্ত পদক্ষেপ।

  1. আকৃতিটি দখল করে এমন x এবং y রেঞ্জগুলি সন্ধান করুন।
  2. শীর্ষে দ্বারা তৈরি প্রান্তগুলির একটি তালিকা তৈরি করুন
  3. প্রচুর পরিমাণে পরিবেশন করুন (আরও ভাল)
  4. এক্স, ওয়াই রেঞ্জের ভিতরে একটি এলোমেলো পয়েন্ট (জে, কে) তৈরি করুন।
  5. কোন প্রান্তটি লাইট এবং এলোমেলো পয়েন্ট দ্বারা নির্মিত লাইন-সেগমেন্টের সাথে বাধা দেয় কিনা তা পরীক্ষা করে দেখুন। প্রান্তগুলির মধ্যে যদি কোনওটি বাধা দেয় তবে চলক বৃদ্ধি করুন incres
  6. sমোট সংখ্যা দ্বারা ভাগ করুন , তারপরে মোট পরিসর ক্ষেত্রফল দিয়ে গুণ করুন।

অবরুদ্ধ সংস্করণ:

import random

def ccw(A,B,C):
    return (C[1]-A[1])*(B[0]-A[0]) > (B[1]-A[1])*(C[0]-A[0])

def intersect(A,B,C,D):
    return ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)

def lit_area(light, vertices):
    # points: list of points
    # i     : x => i=0
    #       : y => i=1
    get_range = lambda i: (min(x[i] for x in vertices), max(x[i] for x in vertices))
    xr = abs(get_range(0)[0] - get_range(0)[1])
    yr = abs(get_range(1)[0] - get_range(1)[1])

    edges = list(zip(vertices, vertices[1:] + [vertices[0]]))

    num_sims = 1000000

    num_successes = 0
    for _ in range(num_sims):
        guess_x = random.uniform(*get_range(0))
        guess_y = random.uniform(*get_range(1))

        light_guess_line = ((guess_x, guess_y), light)

        if not any([intersect(*e, *light_guess_line) for e in edges]):
            num_successes += 1
    return float(num_successes / num_sims) * (xr * yr)


if __name__ == "__main__":
    points = [
    (1/2, 18),
    (1,3),
    (5,1/2),
    (7,5),
    (12,7),
    (16,3),
    (15,11),
    (8,19),
    (3,7)
    ]
    light_source = (5,8)
    print("Area lit by light: %f"% lit_area(light_source, points))

এটি অনলাইন চেষ্টা করুন!

লাইন ছেদ অ্যালগরিদমের জন্য ক্রেডিট

এছাড়াও, কীভাবে আরও গল্ফ করা যায় সে সম্পর্কে সমস্ত সহায়ক কমেন্টারকে কৃতিত্ব দিন।


প্রথম লাইনটি -2 বাইটের জন্য from random import*(লাইন ব্রেক) হয়ে উঠতে পারেu=uniform
কনার ও'ব্রায়েন

1
আপনি ফাংশনটির 4 টি স্পেসের প্রতিটি একক স্থান দিয়ে প্রতিস্থাপন করে আরও কিছু বাইট শেভ করতে পারেন এবং স্থানটি সরিয়ে ফেলতে পারেনg=lambda i:
কনর ওব্রায়েন

না n10 একটি ক্ষমতা থাকতে হবে? অন্যথায় আপনি 9 এর পাওয়ার ব্যবহার করে একটি বাইট সংরক্ষণ করতে পারেন
নীল এ

না, 10 এর ক্ষমতার প্রয়োজন হয় না। আমি আগামীকাল আপনার সমস্ত পরামর্শ রাখব! ততদিনে সবাই ভালোবাসা দিবস!
জেপেরটেক

@ কনরও'ব্রায়েন যেমন উল্লেখ করেছেন, আপনি নেতৃস্থানীয় হোয়াইটস্পেসগুলি লোড করতে পারেন। এবং স্পেসের পাশাপাশি i:(min, স্থানটিও x[i]forসরানো যেতে পারে। এছাড়াও, return float(s/n)*(r*t)হতে পারে return(r*t)*float(s/n)। এবং আমি সম্পূর্ণরূপে নিশ্চিত নই, তবে আপনি কেবল একবার ব্যবহার করলেও পরিবর্তনশীলগুলি rএবং eসরানো এবং সরাসরি ব্যবহার করা যাবে না? এটি কোনওরকম gপরিবর্তিত না হওয়া সত্ত্বেও কিছুটা আলাদা ফলাফল দেয় , সুতরাং সেই অংশটি আমাকে কিছুটা বিভ্রান্ত করে (কেন ফলাফল কিছুটা আলাদা তা বোঝার জন্য আমি পাইথনের সাথে খুব বেশি পরিচিত নই)।
কেভিন ক্রুইজসেন

5

হাস্কেল , 559 618 632 বাইট

r(a:b)=b++[a]
s=zip<*>r
(?)a=sum.zipWith(*)a
o(a,b)=r a?b-a?r b
(a,b)!(c,d)=(c-a,d-b)
(a,b)#(c,d)=a*d-b*c
x i a@(e,f)b j c d|let k@(g,h)=a!b;l=c!d;m=c!a;n=l#k;o=m#l/n;p=m#k/n;q|i>0=o<0||o>1|let=o<=0||o>=1;r|n==0||q||p<0||p*j>1=[]|let=[(e+o*g,f+o*h)]=r
(a&b)(c:e@(d:_))|let(f,g)=span(/=d)b;h=zip f$r$f++[d]=concat[[k,l]|(i,j)<-h,[[k],[l]]<-[x 1 i j 0 a<$>[c,d]],and[x 0 m n 1 a o==[]|o<-[k,l],(m,n)<-h,(m,n)/=(i,j)]]++(a&g)e
(_&_)_=[]
z a b=sum[o$unzip[c,a,d]|e@(f:_)<-[[c|c<-b,and[all(==c)$x 1 d e 1 a c|(d,e)<-s b]]],(c,d)<-s$a&until((f==).head)r b$e++[f]]/2

সঠিক সমাধান (বাগগুলি ব্যতীত)। হাস্কেলের অন্তর্নির্মিত সঠিক যুক্তিযুক্ত পাটিগণিত রয়েছে। এটি অনলাইন চেষ্টা করুন!

নোট করুন যে এটি উদাহরণ কক্ষের জন্য দেয় 815523/6710না 814643/6710, এবং প্রথম প্রাচীর ছেদ হিসাবে গণনা করা হয় (55/61, 363/61)। আমি মোটামুটি নিশ্চিত যে এটি সঠিক কারণ মন্টে কার্লো প্রবেশ (ধীরে ধীরে) একই ফলাফলে রূপান্তরিত করে।

লেজেন্ড:

z light roomPoints
    -- Main function, returns lit area.
    -- Compute list of visible corners in the room, then calls (&).
(&) light roomPoints' visibleCorners
    -- Compute visibility polygon. visibleCorners is the subset of points
    -- that are visible from the light. The first point of roomPoints'
    -- must coincide with the first visibleCorner.
x pEndpoints p1 p2 qSegment q1 q2
    -- Intersect line segments (p1, p2) and (q1, q2).
    -- If pEndpoints, exclude endpoints p1, p2.
    -- If not qSegment, allow intersection to extend past q2 (i.e. raycast).
r   -- Rotate list by one, used to construct closed loops etc.
s   -- Construct closed loop
(!) -- Vector between two points
(?) -- Dot product
(#) -- Cross product
o   -- Polygon area

বোনাস: পরীক্ষার জন্য গ্লস জিইউআই। সেগুলি সরাতে পয়েন্টগুলির পাশে ক্লিক করুন।

import qualified Graphics.Gloss as G
import qualified Graphics.Gloss.Interface.IO.Interact as GI

solnPoly a b|let c@(d:_)=[c|c<-b,and[all(==c)$x 1 d e 1 a c|(d,e)<-s b]]=a&until((d==).head)r b$c++[d]
solnArea = z

main =
  let fromRatP (x, y) = (fromRational x, fromRational y)
      displayScale = 10
      scalePoints = G.scale (fromInteger displayScale) (fromInteger displayScale)
      displayMode = G.InWindow "" (512, 512) (0, 0)
      drawBasePoly pointSz ps =
          mconcat $ G.lineLoop ps :
                    [G.translate x y (G.circleSolid pointSz) | (x, y) <- ps]
      drawVisPolyOf light ps =
          G.color G.blue $ drawBasePoly 0.2 $ map fromRatP $ solnPoly light ps
      drawLight (x, y) =
          G.translate x y $
          G.color G.yellow (G.circleSolid 0.5) <> G.circle 0.5
      draw (light, ps) =
          mconcat [
              scalePoints $ drawLight (fromRatP light),
              scalePoints $ drawBasePoly 0.4 (map fromRatP ps),
              scalePoints $ drawVisPolyOf light ps,
              G.translate (-200) (-50) $ G.scale 0.2 0.2 $
                G.color G.blue $ G.text $ "Lit area: " ++ show (solnArea light ps)
          ]
      event (GI.EventKey (GI.MouseButton GI.LeftButton) GI.Down _ (curx_, cury_)) (light, ps) =
          let dist (x,y) (x',y') = (x'-x)^2 + (y'-y)^2
              curx = curx_ / fromInteger displayScale
              cury = cury_ / fromInteger displayScale
              cursorR = (fromInteger$round curx, fromInteger$round cury)
              maxDist = 3
              snapAmount = 1
              (d, i) = minimum [(dist p cursorR, i) | (p, i) <- zip (light : ps) [0..]]
              snapTo n a = fromInteger$n*round(a/fromInteger n)
              snapCursor = (snapTo snapAmount curx, snapTo snapAmount cury)
              light' | i == 0 && d < maxDist^2 = snapCursor
                     | otherwise = light
              ps' | i > 0 && d < maxDist^2 = take (i-1) ps ++ [snapCursor] ++ drop i ps
                  | otherwise = ps
          in (light', ps')
      event _ state = state
      state0 =
        ((2, 2), [(0, 0), (10, 0), (10, 5), (20, 0), (20, 20), (15, 5),
                  (10, 10), (6, 10), (10, 12), (0, 12), (4, 10), (0, 10)])
  in G.play displayMode G.white 60
            state0
            draw
            event
            (\_ -> id)

স্ক্রিনশট


আসলে, আপনি ঠিক বলেছেন। আমি অবশ্যই একটি টাইপো লোল তৈরি করেছি। এই সংখ্যাগুলিকে সামান্য আপডেট করবে
ধাক্কা

1

APL + + জয়

এটি এই আকর্ষণীয় চ্যালেঞ্জের একটি অবারিত সংস্করণ যা আমি আমার যুক্তি প্রদর্শন করার প্রস্তাব দিই। আমার এপিএল + ডাব্লুআইএন এর প্রাচীন সংস্করণটি গল্ফিং নেস্টেড কন্ট্রোল স্ট্রাকচারের পক্ষে ভাল নয়। আরও আধুনিক এপিএল আরও ভাল করতে পারে - চ্যালেঞ্জ?

যদি পাঠকরা যুক্তি বৈধ করেন তবে আমি এই সমাধানটি গল্ফ করে যাব। যুক্তিটি যদি ভুল হয় তবে আমি মুছে ফেলব।

r←b Room v

⍝Separate x and y coordinates of vertices               
x←v[;1] ⋄ y←v[;2]

⍝Intercept and slope of each line segment and ray through each vertex
s←(y,¨1⌽y)⌹¨(1E¯9+1,[1.1]¨x,¨1⌽1E¯9+x)
l←(y,¨b[2])⌹¨(1E¯9+1,[1.1]¨x,¨b[1]+1E¯9)                          

⍝Coordinates of vertices
x←x,¨1⌽x ⋄ y←y,¨1⌽y                                                  

⍝Initialise intersection matrix
r←((⍴s),0)⍴0

⍝Evaluate intersection matrix 
:for i :in ⍳⍴l 
    t←0⍴0
    :for j :in ⍳⍴s
        t←t,⍎1⍕∊((↑∊l[i])-↑∊s[j])÷((1↓∊s[j])-1↓∊l[i]) 
    :endfor
    z←r←r,t
:endfor 

⍝Identify x coordinates of valid intersections in the direction of the ray
:for i :in ⍳⍴l 
    t←(r[i;i])
    :for j :in ⍳⍴s
        :if t<b[1] 
            r[j;i]←r[j;i]×(r[j;i]<t)^r[j;i]>⌊/∊x[i]
        :else
            r[j;i]←r[j;i]×(r[j;i]>t)^r[j;i]<⌈/∊x[i]
        :endif
    :endfor
 :endfor

⍝Identify the edges intersected
e←(+/r≠0)/⍳⍴l 

⍝Intersection x coordinates
cx←(+/r)[e]

⍝Intersection y coordinates
cy←⍎1⍕+/¨(s[e])× 1,¨(+/r)[e]

⍝Replace original coordinates that are in shadow
x[e]←(1↓¨x[e]),¨cx
y[e]←(1↓¨y[e]),¨cy

⍝Calculate lit area
r←+/.5×(|-/¨x)×|-/¨y                                               

0

আর , 296 255 বাইট

function(s,l,u=cbind(s,s[,1]),d=t(diff(t(u))),q=l-u,r=apply(s,1,range),g=c(diff(r)))mean(replicate(1e6,!any((q[i<-1:ncol(s)*2]*(p=runif(2)*g+r[1,]-u)[j<-i-1]>p[i]*q[j])!=(q[i+2]*p[i+1]>q[i+1]*p[i+2])&(p[i]*d[j]>p[j]*d[i])!=(q[i]*d[j]>q[j]*d[i]))))*prod(g)

এটি অনলাইন চেষ্টা করুন!

এটি পাইথন উত্তরের আরও হ্রাস করা সংস্করণ । মূল মন্টি কার্লো পদ্ধতিটি একই, তবে আমি এগুলিকে সংক্ষিপ্ত করে তুলতে কিছু ফাংশন পুনরায় সাজিয়েছি। আমার প্রথম পুনরাবৃত্তিতে, আমি পুনর্বিন্যাসের ক্ষেত্রে অত্যধিক আক্রমণাত্মক ছিলাম এবং আমি তখন বুঝতে পারি যে অজগরটির কাছাকাছি ছেদটি অ্যালগরিদমের কোনও সংস্করণে ফিরে এসে আমি দৈর্ঘ্য এবং গতি উভয়ই অনুকূল করতে পারি।

এখানে একটি অসমাপ্ত সংস্করণ রয়েছে যা ফলাফলগুলি প্লট করে:

find_lit_ungolf <- function(shape, light, plot = TRUE) {
  lines <- cbind(shape ,shape[,1])
  diffs <- t(diff(t(lines)))
  light_minus_lines <- light - lines
  shape_range <- apply(s,1,range)
  shape_range_diff <- c(diff(shape_range))
  successes <- t(replicate(
    n = 1e5,
    {
      random_point <- runif(2) * shape_range_diff + shape_range[1, ]
      random_minus_lines <- random_point - lines
      q <- light_minus_lines
      p <- random_minus_lines
      d <- diffs
      i <- 1:ncol(s)*2
      success <-
        !any((q[i]*p[i-1]>p[i]*q[i-1])!=(q[i+2]*p[i+1]>q[i+1]*p[i+2])&(p[i]*d[i-1]>p[i-1]*d[i])!=(q[i]*d[i-1]>q[i-1]*d[i]))
      c(random_point, success)
    }))
  colnames(successes) <- c("x", "y", "success")
  if (plot) {
    shape <- t(shape)
    colnames(shape) <- c("x", "y")
    print(ggplot(as_tibble(successes), aes(x, y)) +
      geom_point(aes(colour = factor(success)), alpha = 0.3) +
      geom_polygon(data = as_tibble(shape), alpha = 0.2) +
      annotate("point", light[1], light[2], col = "yellow"))
  }
  mean(successes[, 3]) * prod(shape_range_diff)
}
find_lit_ungolf(s, l)

ঘরে আলোর প্লট

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.