Натуральний Пі № 0 - Рок


39

Мета

Створіть програму / функцію, яка приймає вхід N, перевірте, чи Nвипадкові пари цілих чисел є відносно простими, і повернеться sqrt(6 * N / #coprime).

TL; DR

Ці виклики - це моделювання алгоритмів, які потребують лише природи та вашого мозку (і, можливо, деяких повторно використаних ресурсів), щоб наблизити Pi. Якщо вам справді потрібен Пі під час апокаліпсису зомбі, ці методи не витрачають боєприпаси ! Попереду ще вісім викликів. Отримайте рекомендації в пісочниці .

Моделювання

Що ми моделюємо? Що ж, ймовірність того, що два випадкових цілих числа є відносно простими (тобто coprime або gcd == 1) є 6/Pi/Pi, тож природним способом обчислити Pi було б зібрати два відра (або жменьки) гірських порід; порахуйте їх; подивіться, чи їх gcd дорівнює 1; повторити. Зробивши це кілька разів, sqrt(6.0 * total / num_coprimes)будемо прагнути до цього Pi. Якщо обчислення квадратного кореня в пост-апокаліптичному світі змушує вас нервувати, не хвилюйтеся! Для цього існує метод Ньютона .

Як ми моделюємо це?

  • Візьміть внесок N
  • Виконайте наступні Nрази:
    • Рівномірно генерувати випадкові додатні цілі числа iтаj
    • З 1 <= i , j <= 10^6
    • Якщо gcd(i , j) == 1:result = 1
    • Ще: result = 0
  • Візьміть суму Nрезультатів,S
  • Повернення sqrt(6 * N / S)

введіть тут опис зображення

Специфікація

  • Вхідні дані
    • Гнучка, приймайте введення будь-яким із стандартних способів (наприклад, параметр функції, STDIN) та в будь-якому стандартному форматі (наприклад, String, Binary)
  • Вихідні дані
    • Гнучкі, дають вихід будь-яким із стандартних способів (наприклад, повернення, друк)
    • Білий простір, відсталий та провідний простір білого кольору прийнятний
    • Точність, будь ласка, вкажіть принаймні 4 знаки після коми (тобто 3.1416)
  • Оцінка балів
    • Найкоротший код виграє!

Випробування

Ваш результат може не співпадати з ними через випадкові випадковість. Але в середньому ви повинні отримати приблизно таку точність для заданого значення N.

Input     ->  Output 
-----         ------
100       ->  3.????
10000     ->  3.1???
1000000   ->  3.14??
code-golf  math  random  pi  approximation  popularity-contest  code-golf  sequence  number-theory  binary  coding-theory  code-golf  math  3d  code-golf  code-golf  math  number  code-golf  kolmogorov-complexity  code-golf  ascii-art  graphical-output  binary-tree  code-golf  ascii-art  code-golf  ascii-art  kolmogorov-complexity  code-golf  array-manipulation  hexadecimal  code-golf  math  number  set-theory  code-golf  math  arithmetic  number-theory  integer  code-golf  string  kolmogorov-complexity  code-golf  math  sequence  arithmetic  decision-problem  code-golf  code-golf  ascii-art  code-golf  array-manipulation  parsing  code-golf  string  ascii-art  kolmogorov-complexity  code-challenge  code-golf  sequence  code-golf  number  array-manipulation  sorting  code-golf  string  function  code-golf  arithmetic  code-golf  math  sequence  number-theory  primes  restricted-source  javascript  code-challenge  polyglot  rosetta-stone  code-golf  code-golf  regular-expression  code-golf  math  code-golf  math  primes  code-golf  ascii-art  kolmogorov-complexity  binary  code-golf  math  sequence  code-golf  sequence  subsequence  code-golf  string  code-golf  parsing  music  code-golf  grid  game  path-finding  board-game  code-golf  string  binary  code-golf  array-manipulation  balanced-string  code-golf  code-golf  algorithm  code-golf  string  number  arithmetic  array-manipulation  code-golf  array-manipulation  binary-tree  tree-traversal  code-golf  code-golf  tips  code-golf  string  base-conversion  code-golf  tips  s.i.l.o.s  code-golf  string  ascii-art  code-golf  code-challenge  code-golf  game 

1
Чи потрібно працювати з нашою відповіддю, N = 1000000чи це нормально, якщо програма повертається, наприклад, переповнення стека, якщо Nвоно занадто велике?
Фаталізувати

@ Фаталізуйте, якщо мова йде про обмеження мови. В іншому випадку потрібно впоратися N=10^6.
Нелінійний


2
Мета вводить в оману, вказується, що перевіряється лише одна пара цілих чисел.
користувач253751

1
Чи повинна верхня межа для генерованих випадкових чисел точно 1000000? Чи допустима буде більша верхня межа?
Сок

Відповіді:


12

APL, 23 байти

{.5*⍨6×⍵÷1+.=∨/?⍵2⍴1e6}

Пояснення:

  • ?⍵2⍴1e6: генерувати 2-на-⍵ матрицю випадкових чисел у діапазоні [1..10 6 ]
  • 1+.=∨/: отримайте GCD кожної пари і подивіться, скільки дорівнює 1. Це обчислює S.
  • .5*⍨6×⍵÷: (6 × ⍵ ÷ S) 0,5

11

Желе , 20 18 16 байт

-2 байти завдяки @ Pietu1998 (кількість ланцюгів та використання 1, ċ1замість менше двох сум <2S)

-2 байти завдяки @Dennis (повторити 1e6 кілька разів перед вибіркою, щоб уникнути ланцюга)

Ḥȷ6xX€g2/ċ1÷³6÷½

(Надзвичайно повільно через випадкову функцію)

Як?

Ḥȷ6xX€g2/ċ1÷³6÷½ - Main link: n
 ȷ6              - 1e6
   x             - repeat
Ḥ                -     double, 2n
    X€           - random integer in [1,1e6] for each
       2/        - pairwise reduce with
      g          -     gcd
         ċ1      - count 1s
           ÷     - divide
            ³    - first input, n
             6   - literal 6
              ÷  - divide
               ½ - square root

TryItOnline


ḤRµȷ6Xµ€g2/ċ1÷³6÷½економить 2 байти. ( ȷ6є 10 ^ 6 в одному ніладі, ċ1рахує одиниці)
PurkkaKoodari

Ах, я не міг розібратися, як це зв'язати так (я спробував кілька речей), і забув трюк підрахунку 1 - спасибі (я думаю ȷ², це крихітний крихіткий трохи швидше, ніж ȷ6)
Джонатан Аллан

Може бути. Тепер, коли я думаю про це, ȷ²наявність двох посилань тут не зашкодить, але знадобиться додаткове посилання або ¤для деяких випадків використання
PurkkaKoodari

1
Ḥȷ6xX€повинні працювати для випадкової вибірки.
Денніс

9

Python 2, 143 140 132 124 122 124 122 байт

Минуло досить довгий час, як я спробував гольф, тож я, можливо, щось тут пропустив! Буде оновлено, коли я скорочу це.

import random as r,fractions as f
n,s=input(),0
k=lambda:r.randrange(1e6)+1
exec's+=f.gcd(k(),k())<2;'*n
print(6.*n/s)**.5

Випробуй мене тут!

дякую Джонатану Аллану за двобайтове збереження :)


Згідно з ОП, 1 <= i , j <= 10^6так потрібно використовувати randrange(1,1e6+1).
mbomb007

1
Крім того, по-справжньому дивним є те, що посилання repl.it знаходиться в межах назви мови. Посилання в імені язика повинно бути на домашній сторінці мови, якщо що. Поставте своє посилання repl.it як окреме посилання під кодом.
mbomb007

@ mbomb007 Добре, я це виправив :) Був час!
Каде

1
k=lambda:r.randrange(1e6)+1економить два байти
Джонатан Аллан

1
@JonathanAllan гарний улов, дякую!
Каде

8

Математика, 49 48 51 байт

Збережено один байт та виправлено одну помилку завдяки @ LegionMammal978 .

(6#/Count[GCD@@{1,1*^6}~RandomInteger~{2,#},1])^.5&

1
Ви можете зберегти байт:(6#/Count[GCD@@1*^6~RandomInteger~{2,#},1])^.5&
LegionMammal978

1
Крім того, його 1*^6слід замінити, {1,1*^6}щоб переконатися, що i , j ≠ 0.
LegionMammal978

8

R, 103 99 95 99 98 94 байт

Можливо, можна трохи покататися на гольфі. Виріжте 4 байти завдяки @ antoine-sac та ще 4 байти, визначивши псевдонім для sample, використовуючи ^.5замість sqrtі 1e6замість 10^6. Додано 4 байти, щоб забезпечити вибірку iта jсправді рівномірну. Видалений один байт після того, як я зрозумів, що 6*N/sum(x)це те саме, що 6/mean(x). Використовується pryr::fзамість того, function(x,y)щоб зберегти 4 байти.

N=scan()
s=sample
g=pryr::f(ifelse(o<-x%%y,g(y,o),y))
(6/mean(g(s(1e6,N,1),s(1e6,N,1))==1))^.5

Вибірка зразка:

N=100     -> 3.333333
N=10000   -> 3.137794
N=1000000 -> 3.141709

1
Ви можете просто використовувати sample(10^6,N). Він не тільки коротший, але й набагато ефективніший.
asac

Я можу помилятися, але чи не слід використовувати зразок із заміною = T для належних однакових випадкових чисел. Наприклад sample(10,10), гарантовано повернути всі числа за 1:10, тоді як sample(10,10,T)буде створено випадковий вибір, де числа можна повторити.
MickyT

@MickyT Ви абсолютно праві, я щойно зрозумів це кілька хвилин тому. Я не зовсім впевнений, як це грає математично в цьому випадку - наскільки я можу сказати, обидва методи є приблизно однаково точними. Я відредагую своє повідомлення, щоб додати цю інформацію.
rturnbull

Обидва способи однаково точні, коли N << 10 ^ 6. Щоб обробити довільно великий N, вам доведеться робити вибірку із заміною, хорошим уловом.
asac

7

Власне, 19 байт

`6╤;Ju@Ju┤`nkΣß6*/√

Спробуйте в Інтернеті!

Пояснення:

`6╤;Ju@Ju┤`nkΣß6*/√
`6╤;Ju@Ju┤`n         do this N times:
 6╤;                   two copies of 10**6
    Ju                 random integer in [0, 10**6), increment
      @Ju              another random integer in [0, 10**6), increment
         ┤             1 if coprime else 0
            kΣ       sum the results
              ß      first input again
               6*    multiply by 6
                 /   divide by sum
                  √  square root

i, j не можуть бути 0
isaacg

1
@isaacg Вони ні. Якщо ви прочитаєте пояснення, воно говорить про те, що випадкові значення вибираються з [0, 10 ** 6), а потім збільшуються.
Мего

7

MATL , 22 байти

1e6Hi3$YrZ}Zd1=Ym6w/X^

Спробуйте в Інтернеті!

1e6      % Push 1e6
H        % Push 2
i        % Push input, N
3$Yr     % 2×N matrix of uniformly random integer values between 1 and 1e6
Z}       % Split into its two rows. Gives two 1×N arrays
Zd       % GCD, element-wise. Gives a 1×N array
1=       % Compare each entry with 1. Sets 1 to 0, and other values to 0
Ym       % Mean of the array
6w/      % 6 divided by that
X^       % Square root. Implicitly display

6

Pyth, 21 байт

@*6cQ/iMcmhO^T6yQ2lN2

Спробуйте в Інтернеті.

Пояснення

                Q          input number
               y           twice that
         m                 map numbers 0 to n-1:
             T                 10
            ^ 6                to the 6th power
           O                   random number from 0 to n-1
          h                    add one
        c        2         split into pairs
      iM                   gcd of each pair
     /            lN       count ones
   cQ                      divide input number by the result
 *6                        multiply by 6
@                   2      square root

6

Scala, 149 126 байт

val& =BigInt
def f(n: Int)={math.sqrt(6f*n/Seq.fill(n){val i,j=(math.random*99999+1).toInt
if(&(i).gcd(&(j))>1)0 else 1}.sum)}

Пояснення:

val& =BigInt                //define & as an alias to the object BigInt, because it has a gcd method
def f(n:Int)={              //define a method
  math.sqrt(                //take the sqrt of...
    6f * n /                //6 * n (6f is a floating-point literal to prevent integer division)
    Seq.fill(n){            //Build a sequence with n elements, where each element is..
      val i,j=(math.random*99999+1).toInt //take 2 random integers
      if(&(i).gcd(&(j))>1)0 else 1        //put 0 or 1 in the list by calling
                                          //the apply method of & to convert the numbers to
                                          //BigInt and calling its bcd method
    }.sum                   //calculate the sum
  )
}

Я <3 Скала! Тим більше, тому що іноді дійсно потрібно пояснення.
Роман Ґраф

@ RomanGräf Якщо чесно сказати, єдині речі, які я думаю, можуть бути незрозумілими 6f, Seq.fillі math.random.
corvus_192

5

Ракетка 92 байти

(λ(N)(sqrt(/(* 6 N)(for/sum((c N))(if(= 1(gcd(random 1 1000000)(random 1 1000000)))1 0)))))

Безголовки:

(define f
  (λ (N)
    (sqrt(/ (* 6 N) 
            (for/sum ((c N))
              (if (= 1
                     (gcd (random 1 1000000)
                          (random 1 1000000)))
                  1 0)
              )))))

Тестування:

(f 100)
(f 1000)
(f 100000)

Вихід:

2.970442628930023
3.188964020716403
3.144483068444827

5

JavaScript (ES7), 107 95 94 байт

n=>(n*6/(r=_=>Math.random()*1e6+1|0,g=(a,b)=>b?g(b,a%b):a<2,q=n=>n&&g(r(),r())+q(n-1))(n))**.5

Версія ES6 становить рівно 99 байт, але оператор експоненції ES7 **економить 5 байт Math.sqrt.

Безумовно

function pi(n) {
  function random() {
    return Math.floor(Math.random() * 1e6) + 1;
  }
  function gcd(a, b) {
    if (b == 0)
      return a;
    return gcd(b, a % b);
  }
  function q(n) {
    if (n == 0)
      return 0;
    return (gcd(random(), random()) == 1 ? 1 : 0) + q(n - 1));
  }
  return Math.sqrt(n * 6 / q(n));
}

У версії Ungolfed gcdназиває цю функціюg
Роман Ґраф

r=_=>це код чи малюнок?
aross

n=>(n*6/(r=_=>Math.random()*1e6,g=(a,b)=>b?g(b,a%b):a>-2,q=n=>n&&g(~r(),~r())+q(n-1))(n))**.51B коротше
l4m2

n=>(n*6/(q=_=>n--&&q(r=_=>Math.random()*1e6)+g(~r(),~r()))(g=(a,b)=>b?g(b,a%b):a>-2))**.5
l4m2

5

PHP, 82 77 74 байт

for(;$i++<$argn;)$s+=2>gmp_gcd(rand(1,1e6),rand(1,1e6));echo(6*$i/$s)**.5;

Бігайте так:

echo 10000 | php -R 'for(;$i++<$argn;)$s+=2>gmp_gcd(rand(1,1e6),rand(1,1e6));echo(6*$i/$s)**.5;' 2>/dev/null;echo

Пояснення

Робить те, що написано на жерсті. Потрібен PHP_GMP для gcd.

Налаштування

  • Збережено 3 байти за допомогою $argn

4

Perl, 64 байти

sub r{1+~~rand 9x6}$_=sqrt$_*6/grep{2>gcd r,r}1..$_

Потрібна опція командного рядка -pMntheory=gcd, що рахується як 13. Введення взято з stdin.

Використання зразка

$ echo 1000 | perl -pMntheory=gcd pi-rock.pl
3.14140431218772

4

R, 94 байти

N=scan();a=replicate(N,{x=sample(1e6,2);q=1:x[1];max(q[!x[1]%%q&!x[2]%%q])<2});(6*N/sum(a))^.5

Відносно повільний, але все-таки працює. Повторіть N разів функцію, яка займає 2 випадкових числа (від 1 до 1e6) і перевіряє, чи їх gcd менше 2 (використовуючи стару функцію gcd у мене ).


1
Якщо ви не переживаєте за попередження, 1:xспрацюєте.
MickyT

4

PowerShell v2 +, 118 114 байт

param($n)for(;$k-le$n;$k++){$i,$j=0,1|%{Random -mi 1};while($j){$i,$j=$j,($i%$j)}$o+=!($i-1)}[math]::Sqrt(6*$n/$o)

Бере введення $n , запускає forцикл, поки не $kдорівнює $n(неявно $k=0при першому введенні в цикл). Кожна ітерація, отримуйте нові Randomцифри $iта $j( -miмінімальний 1прапор гарантує, що ми є, >=1а максимальний прапор не дозволяє [int]::MaxValue, що дозволено ОП, оскільки він більший, ніж 10e6).

Потім ми переходимо до циклу GCDwhile . Потім, доки GCD 1, $oзбільшується. В кінці forциклу ми робимо простий [math]::Sqrt()дзвінок, який залишається на конвеєрі, а висновок неявний.

Займається близько 15 хвилин для роботи з 10000моїм ноутбуком Core i5 ~ 1 рік.

Приклади

PS C:\Tools\Scripts\golfing> .\natural-pi-0-rock.ps1 100
3.11085508419128

PS C:\Tools\Scripts\golfing> .\natural-pi-0-rock.ps1 1000
3.17820863081864

PS C:\Tools\Scripts\golfing> .\natural-pi-0-rock.ps1 10000
3.16756133579975

3

Java 8, 164 151 байт

n->{int c=n,t=0,x,y;while(c-->0){x=1+(int)(Math.random()*10e6);y=1+(int)(Math.random()*10e6);while(y>0)y=x%(x=y);if(x<2)t++;}return Math.sqrt(6f*n/t);}

Пояснення

n->{
    int c=n,t=0,x,y;
    while(c-->0){                          // Repeat n times
        x=1+(int)(Math.random()*10e6);     // Random x
        y=1+(int)(Math.random()*10e6);     // Random y
        while(y>0)y=x%(x=y);               // GCD
        if(x<2)t++;                        // Coprime?
    }
    return Math.sqrt(6f*n/t);              // Pi
}

Тестовий джгут

class Main {
    public static interface F{ double f(int n); }
    public static void g(F s){
        System.out.println(s.f(100));
        System.out.println(s.f(1000));
        System.out.println(s.f(10000));
    }
    public static void main(String[] args) {
        g(
            n->{int c=n,t=0,y,x;while(c-->0){x=1+(int)(Math.random()*10e6);y=1+(int)(Math.random()*10e6);while(y>0)y=x%(x=y);if(x<2)t++;}return Math.sqrt(6f*n/t);}
        );
    }
}

Оновлення

  • -13 [16.10.2005] Завдяки @TNT та доданому тестовому джгуту

1
Вам не потрібні дужки навколо першого n, вони t+=1можуть стати t++, ви можете конденсувати свої intдекларації в один рядок, тобто int c=n,t=0,x,y;і !=0(я думаю) можуть стати >0. Це повинно заощадити 12 байт. Це охайний спосіб знаходження GCD x і y.
ТНТ


1

Fork, 84 89

r[]:=random[10^6]+1
g=n=eval[input[1]]
for a=1to n
g=g-1%gcd[r[],r[]]
println[(6*n/g)^.5]

Мені пощастило: g = n = ... зберігає байт над g = 0 n = ... ; і 1% gcd () дає (0,1) vs (1,0), щоб я міг відняти. І пощастило: п є попередньо встановлювати і використовується тому , що змінні циклу і їх оцінки є локальними і НЕ визначені поза циклом.

Багатослівний

r[] := random[10^6] + 1     // function. Frink parses Unicode superscript!
g = n = eval[input[""]]     // input number, [1] works too
for a = 1 to n              // repeat n times
   g = g - 1%gcd[r[], r[]]  // subtract 1 if gcd(i, j) > 1
println[(6*n/g)^.5]         // ^.5 is shorter than sqrt[x], but no super ".", no ½

Це 90 байт і 88 символів ...?
CalculatorFeline

Дякуємо, що це зробили. Я не рахував нові рядки, і хоча ², ³ лише 1 байт ⁶, це більше. Я зафіксував це до 89 байт без остаточного нового рядка.
травень

Ви не зафіксували багатослівний код.
CalculatorFeline

Це все одно не один на один матч з
пробілами


1

Піт , 37 35 байт

←Đ0⇹`25*⁶⁺Đ1⇹ɾ⇹1⇹ɾǤ1=⇹3Ș+⇹⁻łŕ⇹6*⇹/√

Пояснення:

←Đ                                              Push input onto stack twice
  0                                             Push 0
   ⇹                                            Swap top two elements of stack
    `                      ł                    Repeat until top of stack is 0
     25*⁶⁺Đ1⇹ɾ⇹1⇹ɾ                              Randomly generate two integers in the range [1,10^6]
                  Ǥ1=                           Is their GCD 1?
                     ⇹3Ș                        Reposition top three elements of stack
                        +                       Add the top 2 on the stack
                         ⇹⁻                     Swap the top two and subtract one from the new top of the stack
                            ŕ                   Remove the counter from the stack
                             ⇹                  Swap the top two on the stack
                              6*                Multiply top by 6
                                ⇹               Swap top two
                                 /              Divide the second on the stack by the first
                                  √             Get the square root

1

J, 27 байт

3 :'%:6*y%+/(1:=?+.?)y#1e6'

Пояснення:

3 :'                      '  | Explicit verb definition
                     y#1e6   | List of y copies of 1e6 = 1000000
            (1:=?+.?)        | for each item, generate i and j, and test whether their gcd is 1
          +/                 | Sum the resulting list
      6*y%                   | Divide y by it and multiply by six
    %:                       | Square root

Є дуже пощастило з 3.14157для N = 10000000, який зайняв 2.44секунд.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.