प्राकृतिक पाई # 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बिंदु जहां रेखा खंड x- अक्ष को पार करेगा
    • फिर 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
@ ConorO'Brien I शून्य-सूचकांक इसे XD
NonlinearFruit

इसके साथ समस्या यह है कि जटिल संख्या के बिना भाषाओं में, आपको 0..180 में संख्या 0..180 को मोड़ने की आवश्यकता है, जो बफन की सुई के प्रयोग के उद्देश्य को पराजित करता है।
स्तर नदी सेंट

@ नोनलियरफ्रंट की दिशा aएक और विधि द्वारा भी बनाई जा सकती है, अगर यह एक समान हो? (एक 2D गॉस बबल की सोच)
कार्ल नेफ

1
क्या यह माना जा सकता है कि t > l? नीचे दिए गए दो समाधान इस धारणा को बनाते हैं, जो चौराहे के लिए चेक को काफी सरल करता है।
प्राइमो

जवाबों:


9

आर, 113 100 75 70 68 67 65 59 63 57 बाइट्स

एक सांख्यिकीय, कार्यात्मक प्रोग्रामिंग भाषा के रूप में, यह आश्चर्यजनक नहीं है कि आर इस तरह के कार्य के लिए काफी अच्छी तरह से अनुकूल है। तथ्य यह है कि अधिकांश फ़ंक्शन वेक्टरकृत इनपुट ले सकते हैं, वास्तव में इस समस्या के लिए सहायक है, जैसे कि ओवर लूपिंग के बजायN पुनरावृत्तियों , हम बस आकार के वैक्टर के आसपास से गुजरते हैं N। कुछ सुझावों के लिए @Billywob को धन्यवाद जो 4 बाइट्स काटने के लिए नेतृत्व करते हैं। कई बार @Primo को धैर्यपूर्वक समझाने के लिए कि मेरा कोड उन मामलों के लिए कैसे काम नहीं कर रहा है 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-एक्सिस अप्रासंगिक है, केवल निकटतम समानांतर लाइनों के सापेक्ष स्थिति।

अनिवार्य रूप से यह 1-आयामी स्थान में एक कार्य है, जहां हम [0 l] में लंबाई के साथ एक रेखा उत्पन्न करते हैं (कोण aइस लंबाई को निर्धारित करता है), और फिर हम यह देखने के लिए जांचते हैं कि यह लंबाई कितनी बार अधिक है t। किसी न किसी एल्गोरिथ्म तो है:

  1. नमूना x1मान [0, 1000000] से। चूंकि -एक्सिस के tसाथ प्रत्येक वें बिंदु पर समानांतर रेखाएं होती हैं x, सापेक्ष- माप xमोडुलो है ।xt
  2. एक कोण नमूना a
  3. के x2आधार पर स्थिति की गणना करें a
  4. कितनी बार x1+x2फिट बैठता है t, की जाँच करें , यानी की मंजिल ले लो (x1+x2)/t

नमूनाकरण Nसंख्या [0, 1e6] मोडुलो में [0] में tकेवल नमूना Nसंख्या के बराबर है t। चूंकि (x1+x2)/t, इसके बराबर है x1/t + x2/t, पहला चरण [0, t] / t, यानी [0, 1] से नमूना बन जाता है । हमारे लिए भाग्यशाली, आर के runifफ़ंक्शन के लिए डिफ़ॉल्ट सीमा है , जो Nएक समान वितरण से 0 से 1 तक वास्तविक संख्या देता है ।

                          runif(N)

हम aसुई के कोण को उत्पन्न करने के लिए इस चरण को दोहराते हैं ।

                                         runif(N)

इन नंबरों की व्याख्या एक आधे-मोड़ के रूप में की जाती है (अर्थात .590 डिग्री)। (ओपी 1 से 180 तक की डिग्री मांगता है, लेकिन टिप्पणियों में यह स्पष्ट किया गया है कि किसी भी विधि की अनुमति दी जाती है यदि यह अधिक या सटीक है।) कोण के लिए θ, sin(θ)हमें सुई के सिरों के बीच x- अक्ष दूरी प्रदान करता है। (सामान्य रूप से आप कोसाइन का उपयोग कुछ इस तरह से करेंगे; लेकिन हमारे मामले में, हम कोण θको y- अक्ष के सापेक्ष मान रहे हैं , x- अक्ष नहीं (अर्थात, 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))

बाकी कोड सिर्फ pi को सन्निकटन करने के सूत्र को लागू कर रहा है, अर्थात (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)))

@rturnbull अच्छा लगा! हालांकि आप शुरुआत में कोष्ठकों को छोड़ नहीं सकते हैं? (2*l*N) => 2*l*N?
बिलीवोब

@ बिलीवॉब-स्पॉटेड! धन्यवाद।
rturnbull

@rturnbull ओह और वैसे, (2*l*N)/(t*c) = 2*l*N/t/cतो आप पिछले भाग पर भी कोष्ठक को छोड़ कर एक और दो बाइट्स बचा सकते हैं।
बिल्वोब

@ बिलीवोब फिर, अच्छी तरह से देखा! एक बार फिर धन्यवाद।
rturnbull

1
@primo फिर से धन्यवाद, यह अब तय किया जाना चाहिए।
20

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..$_

ऊपर बफन की सुई का एक गणितीय रूप से सही अनुकरण है। हालाँकि, इस बिंदु पर मुझे लगता है कि ज्यादातर लोग इस बात से सहमत होंगे कि वास्तव में यह सवाल नहीं है।


वास्तव में यह pushin '

हम परीक्षण के मामलों में से आधे को ही फेंक सकते हैं, जब भी दूसरा समापन बिंदु पहले की बाईं ओर होता है (बजाय उन्हें स्वैप करने के):

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
प्रिमो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.