পাইয়ের মন্টি কার্লো অনুমানকারী


25

শুভ পাই দিবস সবাই! কোনও কারণ ছাড়াই, আমি পাই এর একটি মন্টি কার্লো অনুমানকারী তৈরি করার চেষ্টা করছি যা যতটা সম্ভব সংক্ষিপ্ত। আমরা কি একটি টুইটে ফিট করতে পারে এমন একটি নির্মাণ করতে পারি?

স্পষ্ট করে বলার জন্য, আমার যা মনে আছে তা হ'ল ইউনিট স্কোয়ার থেকে এলোমেলো পয়েন্ট আঁকার এবং ইউনিট বৃত্তের মধ্যে যে অনুপাতটি আসে তার অনুপাত গণনা করা approach নমুনাগুলির সংখ্যা হার্ড কোডড হতে পারে বা নাও হতে পারে। আপনি যদি এগুলিকে হার্ডকোড করেন তবে আপনাকে কমপক্ষে 1000 টি নমুনা ব্যবহার করতে হবে। ফলটি ফ্লোটিং পয়েন্ট, স্থির পয়েন্ট বা যুক্তিসঙ্গত সংখ্যা হিসাবে ফেরত বা মুদ্রিত হতে পারে।

কোনও ট্রিগ ফাংশন বা পাই কনস্ট্যান্ট নয়, অবশ্যই মন্টি কার্লো পদ্ধতির হতে হবে।

এটি কোড গল্ফ, তাই সংক্ষিপ্ততম জমা (বাইটে) জিতেছে।


2
ট্রিগ ফাংশন অনুমোদিত? আমি আপনাকে সুস্পষ্টভাবে তাদের নিষিদ্ধ করার পরামর্শ দিচ্ছি।
স্তর নদী সেন্ট

((0..4e9).map{rand**2+rand**2<1}.to_s.sub(/./,"$1.")
জন ডিভোরাক

@ জনডভোরাক কীভাবে এটি কাজ করার কথা? না mapতোমাদের একটি অ্যারের দিতে trueএবং false?
মার্টিন এেন্ডার

@ মার্টিনব্যাটনার আহ, ওফ, দুঃখিত। .filter{...}.sizeযদিও কাজ করা উচিত।
জন ডিভোরাক

পুনঃটুইট এটি সত্যিই ঝরঝরে :)
মার্টিন এন্ডার

উত্তর:


17

80386 মেশিন কোড, 40 38 বাইট

কোডের হেক্সডাম্প:

60 33 db 51 0f c7 f0 f7 e0 52 0f c7 f0 f7 e0 58
03 d0 72 03 83 c3 04 e2 eb 53 db 04 24 58 db 04
24 58 de f9 61 c3

এই কোডটি কীভাবে পাবেন (সমাবেশ ভাষা থেকে):

    // ecx = n (number of iterations)
    pushad;
    xor ebx, ebx; // counter
    push ecx; // save n for later
myloop:
    rdrand eax; // make a random number x (range 0...2^32)
    mul eax; // calculate x^2 / 2^32
    push edx;
    rdrand eax; // make another random number y
    mul eax; // calculate y^2 / 2^32
    pop eax;
    add edx, eax; // calculate D = x^2+y^2 / 2^32 (range 0...2^33)
    jc skip; // skip the following if outside the circle
    add ebx, 4; // accumulate the result multiplied by 4
skip:
    loop myloop;
    push ebx; // convert the result
    fild dword ptr [esp]; // to floating-point
    pop eax;
    fild dword ptr [esp]; // convert n to floating-point
    pop eax;
    fdivp st(1), st; // divide

    popad;
    ret;

এমএস fastcallকলিং কনভেনশন ব্যবহার করে এটি একটি ফাংশন (রেজিস্ট্রারে পুনরাবৃত্তির সংখ্যা পাস করা হয় ecx)। এটি stরেজিস্টারে ফলাফল দেয় ।

এই কোড সম্পর্কে মজাদার জিনিস:

  • rdrand - একটি এলোমেলো সংখ্যা তৈরি করতে মাত্র 3 বাইট!
  • এটি (স্বাক্ষরবিহীন) পূর্ণসংখ্যার গাণিতিকটি চূড়ান্ত বিভাগ পর্যন্ত ব্যবহার করে।
  • Dস্কোয়ার ব্যাসার্ধের সাথে স্কোয়ার দূরত্বের ( ) তুলনা 2^32স্বয়ংক্রিয়ভাবে করা হয় - বহনকারী পতাকাটিতে ফলাফল রয়েছে।
  • 4 টি দিয়ে গুণন করতে, এটি 4 টি পদক্ষেপে নমুনাগুলি গণনা করে।

মন্তব্যে "x x 2% 2 ^ 32 গণনা" পড়তে হবে
কোল জনসন

@ কোল জনসন নং - এলোমেলো সংখ্যাটি রয়েছে eax; mulকমান্ড গুণিতক এটি নিজে এবং রাখে উচ্চ অংশ দ্বারা edx; নিম্ন অংশটি eaxফেলে দেওয়া হয়।
অ্যানাটলিগ

11

মতলব / অষ্টাভ, 27 বাইট

আমি জানি যে ইতিমধ্যে একটি মতলব / অক্টাভা উত্তর রয়েছে, কিন্তু আমি নিজের পদ্ধতির চেষ্টা করেছি। আমি 4/(1+x^2)0 এবং 1 এর মধ্যে অবিচ্ছেদ্য পাই ব্যবহার করেছিলাম ।

mean(4./(1+rand(1,1e5).^2))

একটি ভিন্ন অ্যালগরিদম সর্বদা দুর্দান্ত! আরও দক্ষ!
anatolyg

7

আর, 40 (বা 28 বা 24 অন্যান্য পদ্ধতি ব্যবহার করে)

mean(4*replicate(1e5,sum(runif(2)^2)<1))

mean(4*sqrt(1-runif(1e7)^2))

mean(4/(1+runif(1e7)^2))

পাইথন 2, 56

আর একটি পাইথন হ'ল, যদি নাম্পি মঞ্জুরিপ্রাপ্ত তবে মাতলাব / অক্টাভা-র সাথে বেশ অনুরূপ:

import numpy;sum(sum(numpy.random.rand(2,8e5)**2)<1)/2e5

6

গণিত, 42 40 39 বাইট (বা 31/29?)

আমি 42 টি বাইটে তিনটি সমাধান পেয়েছি:

4Count[1~RandomReal~{#,2},p_/;Norm@p<1]/#&
4Tr@Ceiling[1-Norm/@1~RandomReal~{#,2}]/#&
4Tr@Round[1.5-Norm/@1~RandomReal~{#,2}]/#&

এগুলি সমস্ত নামবিহীন ফাংশন যা নমুনাগুলির সংখ্যা নিয়ে যায় এবং nযুক্তিযুক্ত আনুমানিক π প্রদান করে π প্রথমে তারা সকলেই nধনাত্মক কোয়াড্রেন্টে ইউনিট স্কোয়ারে পয়েন্ট উত্পন্ন করে । তারপরে তারা ইউনিট বৃত্তের মধ্যে থাকা সেই নমুনাগুলির সংখ্যা নির্ধারণ করে এবং তারপরে তারা নমুনাগুলির সংখ্যা দ্বারা বিভক্ত হয় এবং গুণিত করে 4। পার্থক্যটি কীভাবে তারা ইউনিট বৃত্তের অভ্যন্তরে সাম্পলগুলির সংখ্যা নির্ধারণ করে:

  • প্রথমটি Countশর্তটি ব্যবহার করে Norm[p] < 1
  • দ্বিতীয়টি প্রতিটি পয়েন্টের আদর্শটি বিয়োগ করে 1এবং পরে গোল করে। এটি ইউনিট বৃত্তের ভিতরে 1এবং বাহিরের মধ্যে সংখ্যাগুলি ঘুরিয়ে দেয় 0। এরপরে আমি কেবল তাদের সাথে সমস্তগুলি সংযুক্ত করছি Tr
  • তৃতীয়টি মূলত একই কাজ করে তবে এর থেকে বিয়োগ করে 1.5, তাই আমি এর Roundপরিবর্তে ব্যবহার করতে পারি Ceiling

এআআআআ্যান্ড এটি লেখার সময় , আমার কাছে ঘটেছিল যে সত্যিই একটি সংক্ষিপ্ত সমাধান রয়েছে, যদি আমি কেবল এখান থেকে বিয়োগ করে 2ব্যবহার করি Floor:

4Tr@Floor[2-Norm/@1~RandomReal~{#,2}]/#&

অথবা ইউনিকোড মেঝে বা সিলিং অপারেটর ব্যবহার করে অন্য একটি বাইট সংরক্ষণ করুন:

4Tr@⌊2-Norm/@1~RandomReal~{#,2}⌋/#&
4Tr@⌈1-Norm/@1~RandomReal~{#,2}⌉/#&

নোট করুন যে তিনটি রাউন্ডিং-ভিত্তিক সমাধানগুলি আবার একই বাইটের Meanপরিবর্তে Trএবং ছাড়াও লেখা যেতে পারে /#


যদি অন্য মন্টি কার্লো ভিত্তিক পন্থাগুলি ভাল হয় (বিশেষত, একজন পিটার বেছে নিয়েছে), আমি এই বারের ভাসমান পয়েন্ট সংখ্যা হিসাবে দেওয়া ইন্টিগ্রাল ব্যবহার করে 29 বা এর ইন্টিগ্রালটি অনুমান করে 31 বাইট করতে পারি :√(1-x2)1/(1+x2)

4Mean@Sqrt[1-1~RandomReal~#^2]&
Mean[4/(1+1~RandomReal~#^2)]&

9
আপনার কাছে জীবন, মহাবিশ্ব এবং সমস্ত কিছুর তিনটি সমাধান রয়েছে এবং আপনি এটিকে নষ্ট করার সিদ্ধান্ত নিয়েছেন? বৈধর্ম্য।
21


6

সিজেএম, 27 23 22 বা 20 বাইট

4rd__{{1dmr}2*mhi-}*//

রানার 1212-এর জন্য 2 বাইট সংরক্ষণ করা হয়েছে, স্প 3000-তে 1 বাইট সংরক্ষণ করা হয়েছে

এটি একটি ইনপুট হিসাবে STDIN থেকে পুনরাবৃত্তি গণনা নেয়।

এটি এটি হিসাবে সরাসরি এগিয়ে। এইগুলি জড়িত প্রধান পদক্ষেপগুলি:

  • ইনপুটটি পড়ুন এবং মন্টে কার্লো পুনরাবৃত্তিগুলি চালান যা বহুবার
  • প্রতিটি পুনরাবৃত্তিতে, 0 থেকে 1 পর্যন্ত দুটি এলোমেলো ফ্লোটের বর্গের যোগফল পান এবং এটি 1 এর চেয়ে কম কিনা তা দেখুন
  • মোট পুনরাবৃত্তির দ্বারা আমরা 1 টির চেয়ে কম কতবার অনুপাত পেয়েছি এবং পিআই পেতে এটি 4 দিয়ে গুণ করি

কোড সম্প্রসারণ :

4rd                     "Put 4 on stack, read input and convert it to a double";
   __{            }*    "Take two copies, one of them determines the iteration"
                        "count for this code block";
      {1dmr}2*          "Generate 2 random doubles from 0 to 1 and put them on stack";
              mh        "Take hypot (sqrt(x^2 + y^2)) where x & y are the above two numbers";
                i       "Convert the hypot to 0 if its less than 1, 1 otherwise";
                 -      "Subtract it from the total sum of input (the first copy of input)";
                    //  "This is essentially taking the ratio of iterations where hypot";
                        "is less than 1 by total iterations and then multiplying by 4";

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


যদি এর গড় মানও 1/(1+x^2)মন্টি কার্লো হিসাবে বিবেচিত হয়, তবে এটি 20 বাইটে করা যেতে পারে:

Urd:K{4Xdmr_*)/+}*K/

এখানে চেষ্টা করুন


2
আমি পাশাপাশি একটি সিজেএম উত্তর চেষ্টা করেছিলাম এবং আপনার স্কোরের অধীনে 2 বাইটে আসতে সক্ষম হয়েছি। তবে আমার কোডটি আপনার মত একইভাবে প্রকাশিত হয়েছিল, আমি আলাদা উত্তর হিসাবে পোস্ট করা নোংরা অনুভব করব। সবকিছু পরিবর্তনশীল পছন্দ এবং এই দুটি অপ্টিমাইজেশন ছাড়া একই ছিল: 1 0 থেকে একটি র্যান্ডম নম্বর পেতে 1dmrপরিবর্তে KmrK/, এবং বেশি 1 পরীক্ষা যদি বর্গের সমষ্টি iপরিবর্তে 1>(আমি এই এক বিশেষ করে চালাক ছিল না) ।
রানার 1112

@ রানার 1112 ধন্যবাদ iকৌতুক সত্যিই ঝরঝরে হয়! এবং এর জন্য ডকুমেন্টেশনের অভাবে অভিশাপ1dmr
অপ্টিমাইজার 21

5

পাইথন 2, 77 75 বাইট

from random import*;r=random;a=0;exec"a+=r()**2+r()**2<1;"*4000;print a/1e3

4000 নমুনা ব্যবহার করে বাইটগুলি সংরক্ষণ করে 1e3


5
বিনা ব্যয়ে আপনি আরও কিছুটা নির্ভুলতা পেতে পারেন ...*8000;print a/2e3
লজিক নাইট

5

কমোডোর 64 বেসিক, 45 বাইট

1F┌I=1TO1E3:C=C-(R/(1)↑2+R/(1)↑2<1):N─:?C/250

PETSCII বিকল্পগুলি: = SHIFT+E, /= SHIFT+N, =SHIFT+O

প্রথম চতুর্ভুজটিতে 1000 পয়েন্ট উত্পন্ন করে; প্রত্যেকটির জন্য, চলমান গণনায় "x ^ 2 + y ^ 2 <1" এর সত্যতা যুক্ত করুন, তারপরে গণনাটিকে 250 দ্বারা ভাগ করে নিন pi। (বিয়োগ চিহ্নের উপস্থিতি হ'ল কারণ C64, "সত্য" = -1।)



@ ক্রিস্টোফারসন, আপনি এটি ভুলভাবে পড়ছেন। /বিভাগ চিহ্ন নয়, এটি SHIFT+Nএকটি কমডোর keyboard৪ কীবোর্ডে টাইপ করে নির্মিত চরিত্র character R/(1)শর্টকাট ফর্ম RND(1), যেমন। "বর্তমান আরএনজি বীজ ব্যবহার করে 0 এবং 1 এর মধ্যে একটি এলোমেলো সংখ্যা তৈরি করুন"।
মার্ক

ওহ আপনি ঠিক! পুরানো PETSCII গ্রাফিক্সের অক্ষর Good
ইক্রিস্টোফারসন

5

জে, 17 বাইট

পরিসীমাটিতে 40000ফাংশনটির নমুনার মানগুলির গড় মান গণনা করে ।4*sqrt(1-sqr(x))[0,1]

হাতের মুঠোয় 0 o.xফিরে আসে sqrt(1-sqr(x))

   1e4%~+/0 o.?4e4$0
3.14915

4

> <> (ফিশ) , 114 বাইট

:00[2>d1[   01v
1-:?!vr:@>x|  >r
c]~$~< |+!/$2*^.3
 .41~/?:-1r
|]:*!r$:*+! \
r+)*: *:*8 8/v?:-1
;n*4, $-{:~ /\r10.

এখন,> <> এর অন্তর্নির্মিত এলোমেলো সংখ্যা জেনারেটর নেই। তবে এটিতে একটি ফাংশন রয়েছে যা পয়েন্টারটিকে এলোমেলো দিকের দিকে প্রেরণ করে। আমার কোডে এলোমেলো নম্বর জেনারেটর:

______d1[   01v
1-:?!vr:@>x|  >r
_]~$~< |+!/$2*^__
 __________
___________ _
_____ ____ _______
_____ ____~ ______

এটি মূলত এলোমেলো বিট তৈরি করে যা বাইনারি সংখ্যা তৈরি করে এবং তারপরে সেই র্যান্ডম বাইনারি সংখ্যাটিকে দশমিক হিসাবে রূপান্তর করে।

বাকিটি বর্গক্ষেত্রের নিয়মিত পয়েন্ট।

ব্যবহার: আপনি কোডটি চালানোর সময় অবশ্যই স্যাম্পেলগুলির সংখ্যার সাথে স্ট্যাকটি (-v পাইথন ইন্টারপ্রেটারে) প্রিপুলেট করা নিশ্চিত করতে হবে

pi.fish -v 1000

আয়

3.164

4

মতলব বা অক্টোব 29 29 বাইট (flawr ধন্যবাদ!)

mean(sum(rand(2,4e6).^2)<1)*4

(<1 ঠিক আছে কিনা আমি নিশ্চিত নই। আমি পড়লাম এটি <= 1 হওয়া উচিত But তবে ঠিক 1 আঁকার সম্ভাবনা কত বড় ...)

মতলব বা অক্টাভ 31 বাইট

sum(sum(rand(2,4e3).^2)<=1)/1e3

1
খুব সুন্দর ধারণা! আপনি এর সাথে দুটি অতিরিক্ত বাইট সংরক্ষণ করতে পারেন mean(sum(rand(2,4e6).^2)<1)*4
flawr

4

জাভা, 108 বাইট

double π(){double π=0,x,i=0;for(;i++<4e5;)π+=(x=Math.random())*x+(x=Math.random())*x<1?1e-5:0;return π;}

চার হাজার পুনরাবৃত্তি, প্রতি পয়েন্ট ইউনিট বৃত্তের অভ্যন্তরে 0.001 যোগ করে। খুব বেসিক স্টাফ।

দ্রষ্টব্য: হ্যাঁ, আমি জানি আমি πএকটি একক বাইট চরিত্রে পরিবর্তন করে চার বাইট ফেলতে পারি । আমি এইভাবে পছন্দ করি।


কেন 9999 পুনরাবৃত্তি না?
অপ্টিমাইজার

1
@ অপ্টিমাইজার এটি যোগফলকে আরও সংক্ষিপ্ত করে তোলে। 9999 পুনরাবৃত্তির জন্য, আমাকে প্রতিবার পরিবর্তে আরও সুনির্দিষ্ট সংখ্যা যুক্ত করতে হবে, যার জন্য আমার অঙ্কগুলি পড়বে।
জিওবিটস

1
আপনি অন্য বাইট সংরক্ষণ করতে পারেন এবং সংখ্যার জন্য "4e5" এবং "1e-5" ব্যবহার করে নির্ভুলতা উন্নত করতে পারেন।
উইলমন্তাস বড়ানউস্কাস

@ ভিলমান্টাস বারানাউসকাস ধন্যবাদ! আমি এটি সম্পর্কে সর্বদা ভুলে যাই :) পরিবর্তে 4e9 এবং 1e-9 ব্যবহার করা লোভনীয়, তবে এতে বেশ খানিকটা সময় লাগে ...
জিওবিটস

প্রতিবাদ: গল্ফ করার সময়, আপনাকে আসলে বাইটগুলি হ্রাস করা উচিত, কৃত্রিমভাবে সেগুলি বাড়ানো উচিত নয়
ধ্বংসাত্মক লেবু

3

জাভাস্ক্রিপ্ট: 62 বাইট

for(r=Math.random,t=c=8e4;t--;c-=r()**2+r()**2|0);alert(c/2e4)

আমি পূর্ববর্তী (এখন মুছে ফেলা) জাভাস্ক্রিপ্ট উত্তর ব্যবহার করেছি এবং 5 বাইট চাঁচা করেছি।


আপনি পারে cfern এর উত্তর এর প্রতি সংযোগ আছে সঠিকভাবে দিতে ক্রেডিট।
জোনাথন ফ্রেচ

আপনার উত্তরটি একটি স্নিপেট হিসাবে দেখা যাচ্ছে যা I / O- কে অনুমোদিত নয় । দয়া করে হয় আপনার পোস্টটি ঠিক করুন বা মুছুন।
জোনাথন ফ্রেচ

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

হ্যাঁ; পূর্ববর্তী উত্তরটি অবৈধ বলে মুছে ফেলা হয়েছিল - আমি মুছে ফেলার প্রস্তাব দেওয়ার আগে আপনার উত্তরটি দেখেছিলাম, সুতরাং মন্তব্যটি। একটি বৈধ উত্তর জমা দেওয়ার জন্য +1; পিপিসিজিতে আপনাকে স্বাগতম!
জোনাথন ফ্রেচ 15

2

গল্ফস্ক্রিপ্ট (34 টি অক্ষর)

0{^3?^rand.*^.*+/+}2000:^*`1/('.'@

অনলাইন ডেমো

এটি স্থির বিন্দু ব্যবহার করে কারণ জিএসের আসলে ভাসমান পয়েন্ট নেই। এটি স্থির বিন্দুর ব্যবহারকে সামান্যভাবে অপব্যবহার করে, তাই আপনি যদি পুনরাবৃত্তি গণনাটি পরিবর্তন করতে চান তবে নিশ্চিত হয়ে নিন যে এটি দশবারের দ্বিগুণ।

নিযুক্ত বিশেষ মন্টি কার্লো পদ্ধতির জন্য xnor এ ক্রেডিট ।


2

পাইথন 2, 90 85 81 বাইট

from random import*;r=random;print sum(4.for i in[0]*9**7if r()**2+r()**2<1)/9**7

3.14120037157উদাহরণস্বরূপ প্রত্যাবর্তন নমুনার গণনা 4782969 (9 ^ 7)। আপনি 9 ^ 9 দিয়ে আরও ভাল পাই পেতে পারেন তবে আপনাকে ধৈর্য ধরতে হবে।


আপনি ব্যবহার না করায় আপনি 3 বা কিছু প্রতিস্থাপনের range(9**7)মাধ্যমে সংরক্ষণ [0]*9**7করতে পারেন i। এবং তালিকাটি মেমরির সমস্যাগুলির জন্য চালানোর জন্য খুব দীর্ঘ নয়।
Sp3000

ধন্যবাদ। আমি পরিত্রাণ পেতে চেয়েছিলাম range()কিন্তু আমি সেই কৌশলটি পুরোপুরি ভুলে গিয়েছিলাম।
লজিক নাইট

আমার একটা অনুভূতি [0]9**7বৈধ সিনট্যাক্স নয়।
সন্ধান করুন

তুমি ঠিক. আমি হারিয়ে যাওয়া অ্যাসেরিক্সটি পুনরায় সংযুক্ত করেছি (এটি আমার ডেস্কের নীচে ছিল)।
লজিক নাইট

2

রুবি, 39 বাইট

p (1..8e5).count{rand**2+rand**2<1}/2e5

হাইলাইটগুলির মধ্যে একটি হ'ল 8e5এটির একটি স্বরলিপিটি ব্যবহার করতে সক্ষম , যা এটি একই প্রোগ্রামের বাইট গণনায় ~ 8e9 নমুনা পর্যন্ত প্রসারিত করে।



1

স্কালা, 87 77 66 বাইট

def s=math.pow(math.random,2);Seq.fill(1000)(s+s).count(_<1)/250d

যদি আপনি উভয় 1000সাথে 8000এবং আপনার 250dসাথে প্রতিস্থাপন করেন তবে 2e4একটি বাইট সংরক্ষণ করুন এবং 8 এর একটি ফ্যাক্টর দ্বারা নমুনাগুলির সংখ্যা বৃদ্ধি করুন
ডেভ সোয়ার্টজ

1

খাঁটি বাশ, 65 বাইট

for((;i++<$1*4;a+=RANDOM**2+RANDOM**2<32767**2));{ :;}
echo $a/$1

একটি একক কমান্ড-লাইন প্যারামিটার নেয় যা নমুনাগুলির সংখ্যা দিতে 4 দ্বারা গুণিত হয়। ব্যাশ পাটিগণিত কেবলমাত্র পূর্ণসংখ্যা, সুতরাং একটি যুক্তিযুক্ত আউটপুট। এটি bc -lচূড়ান্ত বিভাগের জন্য পাইপ করা যেতে পারে :

$ ./montepi.sh 10000
31477/10000
$ ./montepi.sh 10000|bc -l
3.13410000000000000000
$ 

1

জো , 20 19 বাইট

দ্রষ্টব্য: এই উত্তরটি প্রতিদ্বন্দ্বিতাপূর্ণ, কারণ 0.1.2 সংস্করণ, যা এলোমেলো যোগ করেছে, এই চ্যালেঞ্জের পরে প্রকাশিত হয়েছিল।

নামকরণ ফাংশন এফ:

:%$,(4*/+1>/+*,?2~;

নামহীন ফাংশন:

%$,(4*/+1>/+*,?2~;)

এই উভয়ই আর্গুমেন্ট হিসাবে নমুনা গণনা গ্রহণ করে ফলাফলটি ফেরত দেয়। তারা কিভাবে কাজ করে?

%$,(4*/+1>/+*,?2~;)
   (4*/+1>/+*,?2~;) defines a chain, where functions are called right-to-left
               2~;  appends 2 to the argument, giving [x, 2]
              ?     create a table of random values from 0 to 1 with that shape
            *,      take square of every value
          /+         sum rows, giving a list of (x**2+y**2) values
        1>           check if a value is less than 1, per atom
      /+             sum the results
    4*               multiply by four
%$,                  divide the result by the original parameter

উদাহরণ রান:

   :%$,(4*/+1>/+*,?2~;
   F400000
3.14154
   F400000
3.14302

1

ডিসি, 59 টি অক্ষর (সাদা স্থান উপেক্ষা করা হবে)

[? 2^ ? 2^ + 1>i]su
[lx 1+ sx]si
[lu x lm 1+ d sm ln>z]sz

5k
?sn
lzx
lx ln / 4* p
q

আমি এটি প্ল্যান 9 এবং ওপেনবিএসডি-তে পরীক্ষা করেছি, তাই আমি ধারণা করি এটি লিনাক্স (জিএনইউ?) এ কাজ করবে dc

লাইন দ্বারা ব্যাখ্যা:

  1. স্টোর কোডে [পড়া এবং স্কোয়ার টু ফ্লোট; i1 যদি তাদের স্কোয়ারের যোগফলের চেয়ে বড় হয় তবে রেজিস্টার কার্যকর করুনu
  2. স্টোর কোডগুলিতে [বর্ধিত রেজিস্টার x1 দ্বারা] রেজিস্টারে i
  3. থেকে স্টোর কোড [রেজিস্টার করো চালানো u, বৃদ্ধি রেজিস্টার m, এবং তারপর চালানো রেজিস্টার zযদি রেজিস্টার mরেজিস্টার চেয়ে বেশী n] রেজিস্টারে z
  4. স্কেলটি 5 দশমিক পয়েন্টে সেট করুন।

  5. ইনপুট প্রথম লাইন থেকে নমুনা পয়েন্ট সংখ্যা পড়ুন।
  6. নিবন্ধন কার্যকর করুন z
  7. রেজিস্টার x( nপয়েন্টের সংখ্যা ) দ্বারা রেজিস্টার ( হিটের সংখ্যা) ভাগ করুন, ফলাফলটি 4 দ্বারা গুণিত করুন এবং মুদ্রণ করুন।
  8. ছাড়ো।

তবে, আমি প্রতারণা করেছি:

প্রোগ্রামটির 0 থেকে 1 এর মধ্যে এলোমেলো ফ্লোটের সরবরাহ প্রয়োজন।

/* frand.c */
#include <u.h>
#include <libc.h>

void
main(void)
{
    srand(time(0));

    for(;;)
        print("%f\n", frand());
}

ব্যবহার:

#!/bin/rc
# runpi <number of samples>

{ echo $1; frand } | dc pi.dc

পরীক্ষা রান:

% runpi 10000
3.14840

এখন কম প্রতারণার সাথে (100 বাইট)

কেউ উল্লেখ করেছেন যে আমি একটি সহজ prng অন্তর্ভুক্ত করতে পারেন।
http://en.wikipedia.org/wiki/RANDU

[lrx2^lrx2^+1>i]su[lx1+sx]si[luxlm1+dsmln>z]sz[0kls65539*2 31^%dsslkk2 31^/]sr?sn5dksk1sslzxlxlm/4*p

Ungolfed

[
Registers:
u - routine : execute i if sum of squares less than 1
i - routine : increment register x
z - routine : iterator - execute u while n > m++
r - routine : RANDU PRNG
m - variable: number of samples
x - variable: number of samples inside circle
s - variable: seed for r
k - variable: scale for division
n - variable: number of iterations (user input)
]c
[lrx 2^ lrx 2^ + 1>i]su
[lx 1+ sx]si
[lu x lm 1+ d sm ln>z]sz
[0k ls 65539 * 2 31^ % d ss lkk 2 31 ^ /]sr
? sn
5dksk
1 ss
lzx
lx lm / 4*
p

পরীক্ষা রান:

$ echo 10000 | dc pigolf.dc
3.13640

1

পাইথ, 19

c*4sm<sm^OQ2 2*QQQQ

ইনপুট হিসাবে পছন্দসই সংখ্যার পুনরাবৃত্তি দিন।

প্রদর্শন

পাইথের যেহেতু "র্যান্ডম ফ্লোটিং নাম্বার" ফাংশন নেই, তাই আমাকে অসম্পূর্ণ করতে হয়েছিল। প্রোগ্রামটি ইনপুট, স্কোয়ারস, অঙ্কগুলি এবং ইনপুট স্কোয়ারের তুলনায় কম দুটি এলোমেলো ধনাত্মক পূর্ণসংখ্যার পছন্দ করে। এটি ইনপুট সমান একাধিকবার সম্পাদন করে, তারপরে ফলাফলটি 4 দ্বারা গুণিত হয় এবং ইনপুট দ্বারা বিভক্ত হয়।

সম্পর্কিত খবরে, আমি শীঘ্রই পাইথের সাথে একটি এলোমেলো ভাসমান পয়েন্ট নম্বর ক্রিয়াকলাপটি যুক্ত করব। তবে এই প্রোগ্রামটি সেই বৈশিষ্ট্যটি ব্যবহার করে না।


যদি আমরা ব্যাখ্যা করি "ফলটি ভাসমান পয়েন্ট, নির্দিষ্ট পয়েন্ট বা যুক্তি সংখ্যার হিসাবে ফেরত বা মুদ্রিত হতে পারে।" উদারপন্থী, তারপরে ফলাফল ভগ্নাংশের অঙ্ক এবং ডিনোমিনেটর প্রিন্ট করা যথেষ্ট। এই ক্ষেত্রে:

পাইথ, 18

*4sm<sm^OQ2 2*QQQQ

এটি একটি অভিন্ন প্রোগ্রাম, ভাসমান পয়েন্ট বিভাগ অপারেশন ( c) সরানো সহ।


1

জুলিয়া, 37 বাইট

4mean(1-floor(sum(rand(4^8,2).^2,2)))

নমুনার সংখ্যা 65536 (= 4 ^ 8)।

একটি স্লিগ দীর্ঘতর রূপ: sএকমাত্র যুক্তি হিসাবে নমুনার সংখ্যা সহ একটি ফাংশন :

s->4mean(1-floor(sum(rand(s,2).^2,2)))

1

সি, 130 বাইট

#include<stdlib.h>f(){double x,y,c=0;for(int i=0;i<8e6;++i)x=rand(),y=rand(),c+=x*x+y*y<1.0*RAND_MAX*RAND_MAX;printf("%f",c/2e6);}

Ungolfed:

#include <stdlib.h>
f(){
 double x,y,c=0;
 for(int i=0; i<8e6; ++i) x=rand(), y=rand(), c+=x*x+y*y<1.0*RAND_MAX*RAND_MAX;
 printf("%f",c/2e6);
}

অবশ্যই, আপনার সম্ভবত সাদা অংশটি ছাড়াই সংস্করণটি পোস্ট করা উচিত ("সংস্কৃত / সাদা অংশের সাথে" শিরোনামের সাথে বর্তমান সংস্করণটি রাখুন)
ধ্বংসাত্মক লেবু

পছন্দ করুন
কার্ল ন্যাপফ

সমাধানটি এর আগে কোনও নতুন লাইন ছাড়া জিসিসিতে কাজ করে না f()। আপনি কোন সংকলক ব্যবহার করেছেন? Tio.run/##Pc49C4JAHIDx3U9xGMG9ZdYgwWkgtNbQ1BZ6L/UHO8M07hA/…
eush77


1

প্রকৃতপক্ষে , 14 বাইট (প্রতিযোগিতামূলক)

`G²G²+1>`nkæ4*

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

এই সমাধানটি প্রতিযোগিতামূলক নয় কারণ ভাষা চ্যালেঞ্জের পরে-তারিখের। নমুনাগুলির সংখ্যা ইনপুট হিসাবে দেওয়া হয় (হার্ড কোডিংয়ের চেয়ে)।

ব্যাখ্যা:

`G²G²+1>`nkæ4*
`G²G²+1>`n      do the following N times:
 G²G²+            rand()**2 + rand()**2
      1>          is 1 greater?
          kæ    mean of results
            4*  multiply by 4

2
ডাউনটা কেন?
ধ্বংসাত্মক লেবু

1

র্যাকেট 63 বাইট

@ ম্যাট দ্বারা আর ভাষার উত্তরের পদ্ধতি ব্যবহার করে:

(/(for/sum((i n))(define a(/(random 11)10))(/ 4(+ 1(* a a))))n)

Ungolfed:

(define(f n)
   (/
    (for/sum ((i n))
      (define a (/(random 11)10))
      (/ 4(+ 1(* a a))))
    n))

পরীক্ষামূলক:

(f 10000)

আউটপুট (ভগ্নাংশ):

3 31491308966059784/243801776017028125

দশমিক হিসাবে:

(exact->inexact(f 10000))

3.13583200307849

1

ফরট্রান (জিএফোর্টরান) , 84 83 বাইট

CALL SRAND(0)
DO I=1,4E3
X=RAND()
Y=RAND()
IF(X*X+Y*Y<1)A=A+1E-3
ENDDO
PRINT*,A
END

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

এই কোড খুব খারাপ লেখা। এটি ব্যর্থ হবে যদি গফর্ট্রান Aঅন্যান্য মানের সাথে পরিবর্তনশীল আরম্ভ করার সিদ্ধান্ত নেয় তবে 0 (যা সংকলনের প্রায় 50% ঘটবে) এবং যদি A0 হিসাবে আরম্ভ করা হয় তবে এটি সর্বদা প্রদত্ত বীজের জন্য একই র্যান্ডম ক্রম উত্পন্ন করবে। তারপরে, পাই এর জন্য একই মান সর্বদা মুদ্রিত হয়।

এটি একটি আরও ভাল প্রোগ্রাম:

ফরট্রান (জিএফোর্টরান) , 100 99 বাইট

A=0
DO I=1,4E3
CALL RANDOM_NUMBER(X)
CALL RANDOM_NUMBER(Y)
IF(X*X+Y*Y<1)A=A+1E-3
ENDDO
PRINT*,A
END

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

(প্রতিটি সংস্করণে একটি বাইট সংরক্ষণ করা হয়েছে; ধন্যবাদ পেঙ্গুইনো)।


1
প্রতিটি সংস্করণে আপনি 'ডি আই আই = 1,1E3' থেকে 'ডিও আই = 1,4E3' পরিবর্তন করে, 'এ = এ + 1' থেকে 'এ = এ + 1 ই -3' পরিবর্তন করে এবং 'পরিবর্তন করে একটি বাইট সংরক্ষণ করতে পারবেন PRINT *, A / 250 'থেকে' PRINT *, A '
পেঙ্গুইনো

হ্যাঁ, আপনি নিশ্চিত! পরামর্শের জন্য ধন্যবাদ!
rafa11111

1

জাপট , 26 বা 18 বাইট

o r_+ÂMhMr p +Mr p <1Ã*4/U

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

অনুরূপ অপ্টিমাইজার এর উত্তর , প্রধানত শুধু Japt শিখতে চেষ্টা।
অন্তর্নিহিত ইনপুট হিসাবে চালানোর জন্য পুনরাবৃত্তির সংখ্যা নেয় U

o                           Take the input and turn it into a range [0, U),
                            essentially a cheap way to get a large array.
  r_                        Reduce it with the default initial value of 0.
    +Â                      On each iteration, add one if
      MhMr p +Mr p          the hypotenuse of a random [0,1)x[0,1) right triangle
                   <1       is smaller than one.
                     Ã*4/U  Multiply the whole result by four and divide by input.

যদি 1/(1+x^2)অনুমতি দেওয়া হয় (দুটি পৃথক এলোমেলো পরিবর্তে), তবে আমরা একই যুক্তি দিয়ে 18 বাইট অর্জন করতে পারি।

o r_Ä/(1+Mr pÃ*4/U

1
আপনি Mhনিজেই না করে হাইপোপেনজ গণনা করে কয়েকটি বাইট সংরক্ষণ করতে পারেন ;-) এছাড়াও, আপনি xযোগ দ্বারা হ্রাস করার পরিবর্তে একটি অ্যারের যোগফল গ্রহণ করতে পারেন :o x@MhMr Mr)<1Ã*4/U
ETH প্রোডাকশনগুলি

@ ইথ প্রডাকশনগুলি ঝরঝরে, আমি জানতাম না যে আপনি এর Mhমতো ব্যবহার করতে পারেন , ধন্যবাদ! আপনার দ্বি-এলোমেলো উত্তরটি কেবলমাত্র একটি উত্তর দিয়ে আমার উত্তর হিসাবে প্রায় সংক্ষিপ্ত, এটি দুর্দান্ত। আমি মনে রাখব x, গল্ফ স্টাফ করার চেষ্টা করার সময় আমি অনেক হ্রাস ব্যবহার করার প্রবণতা রাখি, তাই এটি খুব কার্যকর হবে।
নিট

1

এফ #, 149 বাইট

open System;
let r=new Random()
let q()=
 let b=r.NextDouble()
 b*b
let m(s:float)=(s-Seq.sumBy(fun x->q()+q()|>Math.Sqrt|>Math.Floor)[1.0..s])*4.0/s

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

যতদূর আমি আউট করতে পারি, এফ # তে এই জাতীয় চলমান মোট কাজ করার জন্য এটি সংখ্যার একটি অ্যারে তৈরি করা এবং Seq.sumByএকটি for..to..doব্লক ব্যবহারের চেয়ে পদ্ধতিটি ব্যবহার করা সংক্ষিপ্ত ।

এই কোডটি কী করে যে এটি 1 থেকে শুরু করে ভাসমান-পয়েন্ট সংখ্যাগুলির সংগ্রহ তৈরি করে, সংগ্রহের উপাদানগুলির সংখ্যার জন্য sকার্য সম্পাদন করে এবং ফলাফলটির যোগফল fun x->...দেয়। আছে sসংগ্রহের উপাদান, তাই র্যান্ডম পরীক্ষা সম্পন্ন হয় sবার। সংগ্রহের আসল সংখ্যাগুলি অগ্রাহ্য করা হয়েছে ( fun x->, তবেx ব্যবহৃত হয় না)।

এর অর্থ হ'ল অ্যাপ্লিকেশনটিকে প্রথমে অ্যারে তৈরি করতে হবে এবং পূরণ করতে হবে এবং তারপরে এটি পুনরাবৃত্তি করতে হবে। সুতরাং এটি সম্ভবত দুবার দ্বিগুণ slowfor..to..do লুপের । এবং অ্যারে তৈরির সাথে মেমরির ব্যবহার ও (চ ** কে) অঞ্চলে!

প্রকৃত পরীক্ষার জন্য নিজেই কোনও if then elseবিবৃতি ব্যবহারের পরিবর্তে এটি কী করে তা দূরত্ব ( q()+q()|>Math.Sqrt) নির্ণয় করে এবং এর সাথে গোল করে Math.Floor। দূরত্বটি যদি বৃত্তের মধ্যে থাকে তবে এটি 0 টি গোল হয়ে যাবে the যদি দূরত্বটি বৃত্তের বাইরে থাকে তবে এটি নীচে 1 গোল করা হবে TheSeq.sumBy পদ্ধতি তারপর মোট হবে এই ফলাফল।

তারপরে নোট করুন যেটি Seq.sumByমোটটি বেঁধেছে তা বৃত্তের ভিতরে থাকা বিন্দু নয়, এর বাইরের বিন্দু । সুতরাং ফলাফলের জন্য এটি গ্রহণ করে s(আমাদের নমুনা আকার) এবং এটি থেকে মোট বিয়োগ করে।

এটি আরও উপস্থিত হয় যে একটি নমুনা আকারকে প্যারামিটার হিসাবে গ্রহণ করা মান-কোডিংয়ের চেয়ে কম। তাই আমি কিছুটা প্রতারণা করছি ...


1

হাস্কেল, 116 114 110 96 বাইট

d=8^9
g[a,b]=sum[4|a*a+b*b<d*d]
p n=(sum.take(floor n)$g<$>iterate((\x->mod(9*x+1)d)<$>)[0,6])/n

যেহেতু ডিল করার ক্ষেত্রে import System.Random; r=randoms(mkStdGen 2)অনেকগুলি মূল্যবান বাইট লাগবে, তাই আমি রৈখিক একত্রিত জেনারেটরের সাথে এলোমেলো সংখ্যার একটি তালিকা তৈরি করি যা কেউ কেউ বলে থাকেন প্রায় ক্রিপ্টোগ্রাফিকভাবে শক্তিশালী: x↦x*9+1 mod 8^9হুল-ডোবেল উপপাদ্যটির পুরো সময়ের রয়েছে 8^9

g4যদি এলোমেলো সংখ্যার জোড়ার জন্য এলোমেলো সংখ্যা পয়েন্ট বৃত্তের ভিতরে থাকে তবে ফলন হয়[0..8^9-1] কারণ এটি ব্যবহৃত সূত্রে একটি গুণকে দূর করে।

ব্যবহার:

> p 100000
3.14208

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


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