প্রাকৃতিক পাই # 1 - বালি


9

লক্ষ্য

Nঅভিন্ন দৈর্ঘ্যের ( ) এলোমেলো রেখাংশগুলি তৈরি করুন ( l), তারা tসমান্তরাল ( ) সমান্তরাল রেখাগুলি অতিক্রম করে কিনা তা পরীক্ষা করুন ।

ব্যাজ

আমরা কি অনুকরণ করছি? বুফনের সুই । আপনার স্যান্ডবক্সে বালি মসৃণ করুন, সমানভাবে ব্যবধানযুক্ত সমান্তরাল লাইনের একটি সেট আঁকুন (এর মধ্যে দূরত্বটি কল করুন t)। দৈর্ঘ্যের একটি সরল কাঠি নিন lএবং এটি Nবার বার স্যান্ডবক্সে ফেলে দিন। এটা অতিক্রম একটি লাইন হতে যতবার যাক c। তাহলে Pi = (2 * l * n) / (t * c)!

আমরা কীভাবে এটি অনুকরণ করছি?

  • ইনপুট নিন N,t,l
  • সঙ্গে N, t, lসব হচ্ছে ধনাত্মক পূর্ণসংখ্যা
  • নিম্নলিখিত Nসময়গুলি করুন:
    • অভিন্ন র্যান্ডম পূর্ণসংখ্যার সমন্বয় উত্পন্ন করুন x,y
    • সঙ্গে 1 <= x, y <= 10^6
    • x,y দৈর্ঘ্যের একটি রেখাংশের কেন্দ্র l
    • অভিন্ন র্যান্ডম পূর্ণসংখ্যার উত্পাদন করুন a
    • সঙ্গে 1 <= a <= 180
    • দিন Pরেখাংশটি এক্স-অক্ষকে অতিক্রম করবে এমন বিন্দু হতে
    • তারপরেই aকোণ(x,y), P, (inf,0)
  • cযে x = i*tকোনও পূর্ণসংখ্যার জন্য লাইনটি অতিক্রম করে এমন রেখাংশগুলির সংখ্যা,, গণনা করুনi
  • প্রত্যাবর্তন (2 * l * N) / (t * c)

এখানে চিত্র বর্ণনা লিখুন

এখানে চিত্র বর্ণনা লিখুন

সবিস্তার বিবরণী

  • ইনপুট
    • নমনীয়, মানক কোনও উপায়ে ইনপুট নিন (যেমন ফাংশন প্যারামিটার, এসটিডিআইএন) এবং কোনও মানক বিন্যাসে (যেমন স্ট্রিং, বাইনারি)
  • আউটপুট
    • নমনীয়, মানক কোনও উপায়ে আউটপুট দিন (যেমন রিটার্ন, প্রিন্ট)
    • সাদা স্থান, অনুসরণ এবং শীর্ষস্থানীয় সাদা স্থান গ্রহণযোগ্য
    • যথার্থতা, দয়া করে সঠিকতার জন্য কমপক্ষে 4 দশমিক স্থান সরবরাহ করুন (যেমন 3.1416)
  • স্কোরিং
    • সবচেয়ে কম কোড জয়!

পরীক্ষার কেস

আপনার আউটপুট এগুলির সাথে সামঞ্জস্য হতে পারে না, এলোমেলো সুযোগের কারণে। তবে গড়ে, আপনার প্রদত্ত মানটির জন্য এই নির্ভুলতাটি পাওয়া উচিত N, t, l

Input (N,t,l)    ->  Output 
-----------        ------
10,10,5          -> ?.????
10,100,50        -> ?.????
1000,1000,600    -> 3.????
10000,1000,700   -> 3.1???
100000,1000,700  -> 3.14??

টি এল; ডিআর

এই চ্যালেঞ্জগুলি হল অ্যালগরিদমের অনুকরণ যা কেবলমাত্র প্রকৃতি এবং আপনার মস্তিষ্কের (এবং সম্ভবত কিছু পুনরায় ব্যবহারযোগ্য সংস্থানসমূহ) আনুমানিক পাইয়ের প্রয়োজন। জম্বি অ্যাপোক্যালাইপসের সময় আপনার যদি সত্যই পাই দরকার হয় তবে এই পদ্ধতিগুলি বারুদ নষ্ট করবেন না ! আছে নয়টি চ্যালেঞ্জ মোট।


আমি ভেবেছি আপনি ইতিমধ্যে 1 নম্বর করেছেন?
কনর ও'ব্রায়েন

1
@ কনরোও ব্রায়েন আই এটি শূন্য-সূচক এটি এক্সডি
ননলাইনারফ্রুট

এটির সাথে সমস্যাটি হ'ল জটিল সংখ্যা ব্যতীত ভাষাগুলিতে আপনাকে ০.১৮০ নম্বরটি 0..pi তে পরিণত করতে হবে যা বাফনের সুই পরীক্ষার উদ্দেশ্যকে বরং পরাভূত করে।
স্তর নদী সেন্ট

@ ননলাইনারফ্রুটটি aযদি অভিন্ন হয় তবে অন্য কোনও পদ্ধতি দ্বারাও দিকটি তৈরি করা যেতে পারে? (একটি 2 ডি গাউস বুদ্বুদ সম্পর্কে চিন্তাভাবনা)
কার্ল ন্যাপফ

1
এটা কি ধরে নেওয়া যায় t > l? নীচের দুটি সমাধান এই ধারণাটি তৈরি করে, যা ছেদ করার জন্য চেকটিকে বেশ খানিকটা সহজ করে তোলে।
primo

উত্তর:


9

আর, 113 100 75 70 68 67 65 59 63 57 বাইট

একটি পরিসংখ্যানগত, কার্যকরী প্রোগ্রামিং ভাষা হিসাবে, এটি আশ্চর্যজনক নয় যে আর এই ধরণের কাজের জন্য যথেষ্ট উপযুক্ত। বেশিরভাগ ফাংশন ভেক্টরাইজড ইনপুট নিতে পারে তা এই সমস্যাটির জন্য সত্যই সহায়ক, Nপুনরাবৃত্তির উপর লুপিংয়ের পরিবর্তে আমরা কেবল আকারের ভেক্টরগুলির কাছাকাছি চলে যাই N। @ বিলিউবকে এমন কিছু পরামর্শের জন্য ধন্যবাদ যা 4 বাইট কেটে ফেলতে পারে। @ প্রিমোকে অনেক ধন্যবাদ ধন্যবাদ ধৈর্য সহকারে আমাকে বোঝানোর জন্য যে আমার কোডটি সেই ক্ষেত্রে যেখানে t > lএখন ঠিক করা হয়েছে তাতে কীভাবে কাজ হচ্ছে না ।

pryr::f(2*l*N/t/sum(floor(runif(N)+sinpi(runif(N))*l/t)))

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

নমুনা আউটপুট:

N=1000, t=1000, l=500
3.037975

N=10000, t=1000, l=700
3.11943

N=100000, t=1000, l=700
3.140351

ব্যাখ্যা

xসূঁচের দুটি মান সমান্তরাল লাইনের উভয় দিকে রয়েছে কিনা তা নির্ধারণ করতে সমস্যাটি ফুটে ওঠে । এর কিছু গুরুত্বপূর্ণ পরিণতি রয়েছে:

  1. yমূল্যগুলি অপ্রাসঙ্গিক
  2. x-অ্যাক্সিসে নিখুঁত অবস্থানটি অপ্রাসঙ্গিক, কেবলমাত্র নিকটবর্তী সমান্তরাল লাইনের সাথে সম্পর্কিত অবস্থান relative

মূলত এটি 1-মাত্রিক স্থানের একটি কাজ, যেখানে আমরা [0, l] ( aদৈর্ঘ্যে কোণটি দৈর্ঘ্য নির্ধারণ করে) দিয়ে একটি লাইন তৈরি করি এবং তারপরে আমরা এই দৈর্ঘ্যটি কতবার ছাড়িয়ে যায় তা পরীক্ষা করে দেখি t। রুক্ষ অ্যালগরিদম তখন:

  1. x1[0, 1000000] এর থেকে নমুনা মান। যেহেতু সমান্তরাল রেখাগুলি প্রতিটি অক্ষের tসাথে x-axis বরাবর ঘটে , তাই আপেক্ষিক- xঅবস্থানটি xমডুলো হয় t
  2. একটি কোণ নমুনা a
  3. x2উপর ভিত্তি করে অবস্থান গণনা করুন a
  4. কতবার x1+x2ফিট হয় তা পরীক্ষা করুন t, অর্থাত্ ফ্লোরটি নিন (x1+x2)/t

স্যাম্পলিং N[0, 1e6] মডিউল সংখ্যা tকেবল স্যাম্পলিং সমতূল্য N[0, সংখ্যা t]। যেহেতু (x1+x2)/tসমতুল্য x1/t + x2/t, প্রথম ধাপটি [0, t] / থেকে tঅর্থাত্ [0, 1] হয়ে যায় becomes আমাদের জন্য ভাগ্যবান, এটি আর এর runifক্রিয়াকলাপের জন্য পূর্বনির্ধারিত পরিসীমা , যা Nইউনিফর্ম বিতরণ থেকে 0 থেকে 1 পর্যন্ত আসল সংখ্যা ফেরত দেয় ।

                          runif(N)

আমরা aসূঁচের কোণটি উত্পন্ন করতে এই পদক্ষেপটি পুনরাবৃত্তি করি ।

                                         runif(N)

এই সংখ্যাগুলি অর্ধ-পালা (অর্থাৎ .590 ডিগ্রি) হিসাবে ব্যাখ্যা করা হয়। (ওপি 1 থেকে 180 ডিগ্রি চেয়েছে, তবে মন্তব্যে এটি স্পষ্ট করে দেওয়া হয়েছে যে কোনও পদ্ধতি যদি এটির মতো বা আরও সুনির্দিষ্ট হয় তবে তার অনুমতি দেওয়া হয়।) একটি কোণের জন্য θ, sin(θ)আমাদের সূঁচের প্রান্তের মধ্যে এক্স-অক্ষের দূরত্ব দেয়। (সাধারণত আপনি কোসাইনটিকে এরকম কোনও কিছুর জন্য ব্যবহার করতে চান; তবে আমাদের ক্ষেত্রে, আমরা কোণটি θy- অক্ষের সাথে সম্পর্কিত বলে বিবেচনা করছি, এক্স-অক্ষ নয় (যা 0 ডিগ্রির মান উপরে যায় , না অধিকার ), এবং এর ফলে আমরা সাইন, যা মূলত ফেজ-বদল আনতে সংখ্যা।) দ্বিগুন ব্যবহার lএই আমাদের দেয় xসুই শেষ অবস্থান।

                                   sinpi(runif(N))*l

এখন আমরা দ্বারা ভাগ করে মান tযোগ করব x1। এই ফলনটি (x1+x2)/tযা x1সমান্তরাল রেখার সংখ্যার ভিত্তিতে সূচকে কতদূর থেকে প্রসারিত করে। কতটি লাইন অতিক্রম করা হয়েছে তার পূর্ণসংখ্যা পেতে, আমরা এটি নিই floor

                    floor(runif(N)+sinpi(runif(N))*l/t)

আমরা cসূঁচ দ্বারা কতগুলি লাইন অতিক্রম করে তা গণনা করে আমরা যোগফল গণনা করি ।

                sum(floor(runif(N)+sinpi(runif(N))*l/t))

কোডের বাকী অংশগুলি কেবল পাই আনুমানিক করার সূত্রটি বাস্তবায়ন করছে, এটি (2*l*N)/(t*c)। আমরা এই বন্ধুত্বের উপর কয়েকটি বাইট সংরক্ষণ করি এই সত্যটির সুবিধা নিয়ে (2*l*N)/(t*c) == 2*l*N/t/c:

        2*l*N/t/sum(floor(runif(N)+sinpi(runif(N))*l/t))

এবং পুরো জিনিসটি একটি বেনামী ফাংশনে আবৃত:

pryr::f(2*l*N/t/sum(floor(runif(N)+sinpi(runif(N))*l/t)))

@ আর্টারনবুল ভাল লাগছে! আপনি কি প্রথমদিকে প্রথম বন্ধনী ছেড়ে যেতে সক্ষম হবেন না? (2*l*N) => 2*l*N?
বিলিওব

@ বিলিওব সুদর্শন! ধন্যবাদ।
rturnbull

@ আর্টারনবুল ওহ এবং যাইহোক, (2*l*N)/(t*c) = 2*l*N/t/cআপনি শেষ অংশেও প্রথম বন্ধন এড়িয়ে অন্য দুটি বাইট সংরক্ষণ করতে পারেন।
বিলিউব

@ বিলিওউব আবার, বেশ ভাল! আবার ধন্যবাদ.
rturnbull

1
@ প্রিমো আবার ধন্যবাদ, এটি এখনই ঠিক করা উচিত।
rturnbull

6

পার্ল, 97 বাইট

#!perl -p
/ \d+/;$_*=2*$'/$&/map{($x=(1+~~rand 1e6)/$&)-$a..$x+($a=$'/$&/2*sin~~rand(180)*71/4068)-1}1..$_

শেবাংকে এক হিসাবে গণনা করা, ইনপুট স্টিডিন থেকে নেওয়া হয়, স্থান পৃথক করা হয়। যদি অ-পূর্ণসংখ্যার এলোমেলো মানগুলির অনুমতি দেওয়া হয় তবে এটি কিছুটা ছোট হতে পারে।

আমি একটি স্বাধীনতা নিয়েছি, / / 180 কে 71/4068 হিসাবে প্রায় যা 1.48 · 10 -9-এর মধ্যে সঠিক ।

নমুনা ব্যবহার

$ echo 1000000 1000 70000 | perl pi-sand.pl
3.14115345174061

আরও কম-বেশি গাণিতিক সমতুল্য বিকল্পগুলি

এক্স-কোর্ডিনেট ধরে নিলে সমস্যাটির বর্ণনায় উল্লিখিত সূঁচের মাঝামাঝি না করে সুচির বাম-পয়েন্ট উপস্থাপন করে:

89 বাইট

#!perl -p
/ \d+/;$_*=2*$'/$&/map{($x=(1+~~rand 1e6)/$&)..$x+($'/$&*sin~~rand(180)*71/4068)-1}1..$_

সমস্যাটি উল্লেখ করে যে xএলোমেলো পূর্ণসংখ্যা হিসাবে নমুনা করা উচিত। আমরা যদি লাইনে একটি একটি ফাঁক থেকে ব্যবধান প্রকল্প, এই আমাদের ফর্মের মান ছাড়বে n/tসঙ্গে 0 <= n < tঅগত্যা অভিন্ন না, যদি tসমানভাবে ভাগ করে নেই 1e6। ধরে নিই যে অভিন্ন বন্টন তবুও গ্রহণযোগ্য:

76 বাইট

#!perl -p
/ \d+/;$_*=2*$'/$&/map{($x=rand)..$x+($'/$&*sin~~rand(180)*71/4068)-1}1..$_

মনে রাখবেন যেহেতু randসর্বদা একজনের চেয়ে কম হবে (এবং তাই শূন্যকে ছাঁটাই করা হবে), সুতরাং পরিসরের শুরুতে এটি প্রয়োজনীয় নয়:

70 বাইট

#!perl -p
/ \d+/;$_*=2*$'/$&/map{1..(rand)+($'/$&*sin~~rand(180)*71/4068)}1..$_

ধরে নিলাম যে সূঁচের কোণটি একটি পূর্ণসংখ্যার ডিগ্রী হওয়া উচিত নয়, তবে কেবল অভিন্ন র্যান্ডম:

59 বাইট

#!perl -p
/ \d+/;$_*=2*$'/$&/map{1..(rand)+abs$'/$&*sin rand$`}1..$_

অনুমান করা হয় যে কোণটি কোনও অভিন্ন বিতরণ হতে পারে:

52 বাইট

#!perl -p
/ \d+/;$_*=2*$'/$&/map{1..(rand)+abs$'/$&*sin}1..$_

উপরেরটি বুফনের সুইয়ের গাণিতিকভাবে সঠিক সিমুলেশন। যাইহোক, এই মুহুর্তে আমি মনে করি বেশিরভাগ লোকেরা সম্মত হবেন যে এটি আসলে প্রশ্নটি চেয়েছিল তা নয়।


সত্যিই এটা ধাক্কা

যখনই দ্বিতীয় শেষ পয়েন্টটি প্রথম বামদিকে হয় (সেগুলি পরিবর্তনের পরিবর্তে) আমরা কেবলমাত্র অর্ধেক পরীক্ষার কেস ফেলে দিতে পারি:

47 বাইট

#!perl -p
/ \d+/;$_*=$'/$&/map{1..(rand)+$'/$&*sin}1..$_

মনে রাখবেন যে, মান tএবং lপরীক্ষা ফলাফল তুচ্ছ হয়। আমরা কেবল এগুলি উপেক্ষা করতে পারি (স্পষ্টতই তাদের সমান বলে ধরে নিচ্ছি):

28 বাইট

#!perl -p
$_/=map{1..(rand)+sin}1..$_

স্পষ্টতই প্রতিযোগিতামূলক নয়, তবে আপনাকে স্বীকার করতে হবে এটির একটি নির্দিষ্ট কমনীয়তা আছে।


4

পাইথন 2, 141 বাইট

rtumbull এর নির্লজ্জ বন্দর, ইতিমধ্যে এড়িয়ে চলেছে yকারণ সম্পূর্ণ প্রয়োজন হয় না।

from math import*
from random import*
lambda N,t,l:(2.*l*N)/(t*sum(randint(1,1e6)%t+abs(cos(randint(1,180)*pi/180))*l>t for _ in range(N)))

সমস্যা কেবলমাত্র, সেই পাইটি প্রোগ্রামটিতে ইতিমধ্যে পরিচিত।

এখানে এটি (গল্ফযোগ্য) অজানা পাই এবং কোনও ত্রিকোণমিত্রিক ফাংশন নেই

def g(N,t,l):
 c=0
 for _ in range(N):
    x,y=gauss(0,1),gauss(0,1);c+=randint(1,1e6)%t+abs(x/sqrt(x*x+y*y))*l>t
 return(2.*l*N)/(t*c)

x,yইন gশুধুমাত্র দিকের জন্য।


প্রয়োজন from random import randint;from math import cos,pit < lযেমন ব্যর্থ হয় 1000000,1000,70000
primo
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.