দ্বিমাত্রিক রশ্মি ট্রেসিং


9

চ্যালেঞ্জটি হ'ল পাঠ্য-ভিত্তিক একটি 2-মাত্রিক রশ্মি ট্রেসিং প্রোগ্রাম বাস্তবায়ন করা।

সাদা আলোর উত্স @প্রতীক। R, Gএবং Bহালকা ফিল্টার হয়। /এবং \80% প্রতিচ্ছবি সহ আয়না হয়। ?একটি হালকা সেন্সর। >, <, ^এবং Vউপযুক্ত দিক হালকা মেশা (যেমন যদি কেউ লাল, ও একটি সবুজ একটি এসেছিলেন >অধিকার দিকে নির্গত হবে হালকা এবং এটা হলুদ হবে)। অন্যান্য অ-হোয়াইটস্পেস অক্ষর সমস্ত আলো শোষণ করে। @প্রতীক থেকে আলো চারদিকে নির্গত হয় ।

যখন প্রোগ্রামটি চালানো হয়, তখন এটি আউটপুট একই ইনপুট হিসাবে তৈরি করা উচিত তবে ট্রেড রশ্মির সাহায্যে। কারণ এটি 2 মাত্রিক, এবং আমি ইনপুটটিতে গ্যারান্টি দিচ্ছি যে কোনও রশ্মি কখনই অতিক্রম করবে না, এতে কোনও সমস্যা হবে না। প্রতিটি রশ্মি একটি বর্ণ দ্বারা প্রতিনিধিত্ব করা উচিত; আর = লাল, জি = সবুজ, খ = নীল, সি = সায়ান, এম = ম্যাজেন্টা, ওয়াই = হলুদ, ডাব্লু = সাদা। কোনও টিনারারি রঙ কখনও হবে না। কেসিংটি ইনপুট থেকে আলাদা করতে গুরুত্বপূর্ণ। এই আউটপুট পরে, প্রশ্ন চিহ্ন দ্বারা ক্যাপচার আলোর মানগুলি (তাদের উপস্থিতির ক্রম অনুসারে, বাম থেকে ডান থেকে নীচে পর্যন্ত) শতাংশ এবং রঙ হিসাবে আউটপুট করা উচিত। উদাহরণস্বরূপ, এই ইনপুট:

 /                  @
                    -
 \R>                 ?

 @B/

আউটপুট দেওয়া উচিত:

 /wwwwwwwwwwwwwwwwww@w
 w                  -
w\R>mmmmmmmmmmmmmmmmm?
 w b
 @B/

#1: 72% Magenta

লক্ষণীয় আরেকটি গুরুত্বপূর্ণ বিষয় - যখন দুটি প্রিন্ট একটি "প্রিজম" (তীরগুলি) ব্যবহার করে একত্রিত হয় তখন সম্মিলিত আলোর শক্তি দুটির গড় শক্তি হয়ে যায়। আউটপুট অবশ্যই নির্দিষ্ট হিসাবে নির্দিষ্ট করা আবশ্যক (যেমন # x: [x] [x] x% রঙ )।

যদি আপনার ভাষা STDIN থেকে পড়তে না পারে এবং STDOUT এ লিখতে না পারে তবে একটি ফাংশন তৈরি করুন (বেনামে বা ল্যাম্বদা যখন পাওয়া যায়) এটি ইনপুটটিকে আর্গুমেন্ট হিসাবে গ্রহণ করে এবং ফলাফলটি ফেরত দেয়।

সংকলকটির নির্দেশাবলী, ভাষার তৈরি সমস্ত বা বেশিরভাগ প্রোগ্রামের জন্য প্রয়োজনীয় বা সুপারিশকৃত কাঠামো ইত্যাদি বাদ দেওয়া যেতে পারে। উদাহরণস্বরূপ, #includeএবং usingনির্দেশাবলী (তবে নয় #define) সি-স্টাইলের ভাষাগুলিতে, #/usr/bin/perl -optionsপার্লে এবং

 Module Module1
      Sub Main()
      End Sub
 End Module

উদাহরণস্বরূপ VB.NET এ। আপনি যদি নেমস্পেসগুলি আমদানি করেন বা নির্দেশাবলী অন্তর্ভুক্ত করেন তবে দয়া করে আপনার উত্তরে সেগুলি নোট করুন।

এখন কি তাই যথেষ্ট? :)


কোড গল্ফ সম্পর্কিত : স্ট্যাক ওভারফ্লোতে লেজাররা।
ডিএমকেকে --- প্রাক্তন-মডারেটর বিড়ালছানা

আপনার উদাহরণে আয়নাগুলির আচরণটি বোঝায় না। আপনার আলোর উপর প্রভাব ফেলে একটি light (পালিয়ে যাওয়া ভেঙে গেছে) যা সরাসরি চলেছে। আয়নার মতো একই সারিটিতে আলো আসতে এবং একই কলামে রেখে যাওয়া বা তার বিপরীতে আরও বোধগম্য মনে হয়। একইভাবে এটি >ক্যাপচারিং লাইট যা সরাসরি এটি অতীত হয়। wউপরের দিকটি যদি এর মধ্য দিয়ে যায় তবে নীচের দিক থেকেও Rউচিত b। অবশেষে (আমার মনে হয়), আপনি রে রোধ না করার বিষয়ে ভুল। একটি লাইনের উদাহরণ দেওয়ার জন্য, সঠিক আউটপুটটি @R> B@কী জন্য হবে ?
পিটার টেলর

আপনি কেন একটি এলোমেলো ডাব্লু যোগ করলেন এবং সমস্ত ব্যবধান ভেঙে ফেললেন? এবং আলো সরাসরি এটি অতীত হয় না, আপনি কী বোঝাতে চাইছেন তা নিশ্চিত নয়।
রাই-

@ এমনিটেক, যে @নীচে-বামে চারটি দিকের আলো আলোকিত করে, তাই না? সুতরাং বিশেষত, এটি নির্গত হয় w। এবং আমি কোনও স্পেসিং ভাঙ্গি নি, কমপক্ষে ক্রোমিয়ামে রেন্ডার হিসাবে। সরাসরি এটি অতিক্রম করতে হিসাবে, আমার সম্পাদনা যে পরিষ্কার হতে পারে।
পিটার টেলর

5
মিনিটেক: ভবিষ্যতের কাজগুলির জন্য পরামর্শ হিসাবে: প্রথমে স্যান্ডবক্স বা ধাঁধা ল্যাবে মন্তব্যগুলির জন্য জিজ্ঞাসা করুন যা অসম্পূর্ণতাগুলি এবং কাজের সাথে প্রাথমিক সমস্যার সমাধান করার পক্ষে যথেষ্ট। এইভাবে, একবার আপনি এখানে কাজটি পোস্ট করার পরে, আপনি জানেন যে এটি ইতিমধ্যে অন্য কেউ দ্বারা পরীক্ষা করা হয়েছে (এবং সম্ভবত বাস্তবায়িতও হয়েছে)।
জো

উত্তর:


2

পাইথন, 602 559 614 অক্ষর

import sys
S=sys.stdin.readlines()
X=max(len(s)for s in S)
I='#'*X+''.join(t[:-1]+' '*(X-len(t))+'\n'for t in S)+'#'*X
L=len(I)
R=range(L)
B=[0]*L
C=[0]*L
for p in R:
 if'@'!=I[p]:continue
 for d in(1,-1,X,-X):
  q=p;c=7;b=100.
  while 1:
   q+=d;a=I[q];B[q]+=b;C[q]|=c
   if a in'\/':d=(ord(a)/30-2)*X/d;b*=.8
   elif a in'RGB':c&=ord(a)/5-12
   elif a in'><^V':d={'>':1,'<':-1,'^':-X,'V':X}[a];b/=2
   elif' '!=a:break
print''.join(I[p]if' '!=I[p]else' bgcrmyw'[C[p]]for p in R[X:-X])
i=0
for p in R:
 if'?'==I[p]:i+=1;print'#%d:'%i,'%.0f%%'%B[p],[0,'Blue','Green','Cyan','Red','Magenta','Yellow','White'][C[p]]

সম্পাদনা: স্থির হয়েছে তাই এর পিছনে স্থানগুলির প্রয়োজন নেই।


প্রায় - তবে পরীক্ষার কেসের ফলাফলটি ভুল। দেখুন: ideone.com/kUTxE । যাইহোক +1, যদিও দুর্দান্ত!
রাই-

@ এমনিটেক: আমি মনে করি এটি পিছনের জায়গাগুলির অভাবের সাথে সম্পর্কযুক্ত। আমার কোড ধরে নেওয়া হয় যে প্রতিটি সারি একই দৈর্ঘ্য, প্রয়োজনে স্পেস দিয়ে প্যাড করা। এটা কি হয় না? যদি তাই হয় তবে আপনি কীভাবে জানেন, উদাহরণস্বরূপ, উপরের আলোর উত্সটি ডানদিকে কতদূর যায়?
কিথ র্যান্ডাল

এটি প্যাড করতে দীর্ঘতম লাইনের দৈর্ঘ্য ব্যবহার করে আপনি পুরো গ্রিডটি বের করতে পারেন। যাইহোক, শূন্যস্থানগুলির সাথে প্যাড করার পরেও এটি এটি দেয় (ইনপুট # 4): ideone.com/kUTxE
রাই-

@ এমনিটেক: আপনি ৪ র্থ লাইনে একটি জায়গা মিস করছেন। আমি আমার কোড ঠিক করব যাতে পিছনের জায়গার প্রয়োজন হয় না।
কিথ র্যান্ডাল

ওহ, বাহ এটা কাজ করে !! ভাল করেছ. তবে হ্যাঁ, প্যাডিংয়ের প্রয়োজন না থাকলে এটি ভাল।
রাই-

2

এফ #

#nowarn "0025"

open System

type MirrorDirection = bool
type LightDirection = bool * bool
type Sq =
  | Air // [ ]
  | Mirror of MirrorDirection // [/] [\]
  | FilterR
  | FilterG
  | FilterB
  | Sensor // [?]
  | Combine of LightDirection // [^] [v] [<] [>]
  | Emitter // [@]
  | Wall of Char // non-whitespace

let [ mL; mR ] : MirrorDirection list = [ true; false ]
(* true T^/
       F</>F
        /vT   false
 *)
let [ dN; dS; dW; dE ] : LightDirection list = [ true, true; false, true; true, false; false, false ]
let bounce (m : MirrorDirection) ((a, b) : LightDirection) =
  m <> a, not b

let dv (a : LightDirection) =
  if a = dN then 0, -1
  elif a = dS then 0, 1
  elif a = dW then -1, 0
  else 1, 0

let fo<'a> : (('a option)[,] -> 'a seq) =
  Seq.cast
  >> Seq.filter Option.isSome
  >> Seq.map Option.get

let input = Console.In.ReadToEnd().Replace("\r\n", "\n")
let sqs =
  input.Split('\n')
  |> Array.map (fun x ->
    x.ToCharArray()
    |> Array.map (
      function
      | ' ' | '\t' | '\v' -> Air
      | '/' -> Mirror mL
      | '\\' -> Mirror mR
      | 'R' -> FilterR
      | 'G' -> FilterG
      | 'B' -> FilterB
      | '?' -> Sensor
      | '^' -> Combine dN
      | 'v' -> Combine dS
      | '<' -> Combine dW
      | '>' -> Combine dE
      | '@' -> Emitter
      | x -> Wall x
    )
  )

let w =
  Array.map Array.length sqs
  |> Set.ofArray
  |> Set.maxElement
let h = sqs.Length

let ib x y = -1 < x && x < w && -1 < y && y < h

let arr = Array2D.init w h (fun x y ->
  if x < sqs.[y].Length then
    sqs.[y].[x]
  else
    Air
)

let board =
  Array2D.map (
    function
    | _ -> 0.0, 0.0, 0.0
  ) arr

let mutable rays =
  Array2D.mapi (fun x y a ->
    match a with
    | Emitter -> Some(x, y)
    | _ -> None
  ) arr
  |> fo
  |> Seq.map (fun (x, y) ->
    [|
      dN, x, y, 1., 1., 1.
      dS, x, y, 1., 1., 1.
      dW, x, y, 1., 1., 1.
      dE, x, y, 1., 1., 1.
    |]
  )
  |> Seq.reduce Array.append

for i = 0 to w * h * 2 do
  rays <-
    rays
    |> Array.map (
      (fun (dir, x, y, r, g, b) ->
        let dx, dy = dv dir
        dir, x + dx, y + dy, r, g, b
      )
      >> (fun (dir, x, y, r, g, b) ->
        if ib x y then
          match arr.[x, y] with
          | Wall _ -> Array.empty
          | Sensor -> [| dir, x, y, r, g, b |]
          | FilterR -> [| dir, x, y, r, 0., 0. |]
          | FilterG -> [| dir, x, y, 0., g, 0. |]
          | FilterB -> [| dir, x, y, 0., 0., b |]
          | Mirror d -> [| bounce d dir, x, y, r * 0.8, g * 0.8, b * 0.8 |]
          | _ -> [| dir, x, y, r, g, b |]
        else
          Array.empty
      ))
    |> Array.concat
  Array2D.mapi (fun x y a ->
    match a with
    | Combine d -> Some(x, y, d)
    | _ -> None
  ) arr
  |> fo
  |> Seq.iter (fun (x, y, d) ->
    for i = 0 to rays.Length - 1 do
      let (d', x', y', r, g, b) = rays.[i]
      if x' = x && y' = y then
        rays.[i] <- (d, x, y, r, g, b)
  )
  for d, x, y, r, g, b in rays do
    if ib x y then
      match board.[x, y] with
      | r', g', b' -> board.[x, y] <- r + r', g + g', b + b'

printfn "%s" (
  let mutable s = ""
  for y = 0 to h - 1 do
    for x = 0 to w - 1 do
      s <- s + (match arr.[x, y] with
                | Air ->
                  match board.[x, y] with
                  | r, g, b ->
                    if r + g + b = 0.0 then ' '
                    else
                      if g = 0.0 && b = 0.0 then 'r'
                      elif r = 0.0 && b = 0.0 then 'g'
                      elif r = 0.0 && g = 0.0 then 'b'
                      elif r = 0.0 then 'c'
                      elif g = 0.0 then 'm'
                      elif b = 0.0 then 'y'
                      else 'w'
                | Wall z -> z
                | Mirror z -> if z = mL then '/' else '\\'
                | FilterR -> 'R'
                | FilterG -> 'G'
                | FilterB -> 'B'
                | Sensor -> '?'
                | Combine z -> if z = dN then '^' elif z = dS then 'v' elif z = dW then '<' else '>'
                | Emitter -> '@'
                |> sprintf "%c")
    s <- s + "\n"
  s
)

Array2D.mapi (fun x y a ->
  match a with
  | Sensor -> Some(x, y)
  | _ -> None
) arr
|> fo
|> Seq.iteri (fun i (x, y) ->
  let (r, g, b) = board.[x, y]
  let desc =
    if r + g + b = 0.0 then "None"
    elif g = 0.0 && b = 0.0 then "Red"
    elif r = 0.0 && b = 0.0 then "Green"
    elif r = 0.0 && g = 0.0 then "Blue"
    elif r = 0.0 then "Cyan"
    elif g = 0.0 then "Magenta"
    elif b = 0.0 then "Yellow"
    else "White"
  let avg = int((r + g + b) * 100.0 / (match desc with
                                       | "White" | "None" -> 3.0
                                       | "Red" | "Green" | "Blue" -> 1.0
                                       | _ -> 2.0))
  printfn "#%d: %d%% %s" (i + 1) avg desc
)

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