Daniel Lubarov

The worst pi generator?

This is the "dart method" of approximating pi, which is extremely slow to converge, but simple and fun to implement. To make things interesting, I tried writing it in Bash, which doesn't support floating point arithmetic.

#!/usr/bin/env bash

# This is a Monte Carlo approximation of pi. Imagine a circle of radius r. We
# repeatedly generate random points inside the circle's bounding square, and
# record how many points lie inside the circle. With some simple geometry, we
# find that pi ~= 4 * <points inside circle> / <total points>.

# Note: $RANDOM gives a random integer between zero and the largest signed
# short (2^15 - 1), inclusive. So we'll give our circle a radius of half that
# (approximately, since we can't easily represent non-integers in Bash).

r=$((2**14))
attempts=0
hits=0

function decimal_representation {
  numerator=$1
  denominator=$2

  div=$((numerator / denominator))
  rem=$((numerator % denominator))
  decimals=$((10000 * rem / denominator))

  echo "$div.$decimals"
}

while :; do
  x=$((RANDOM - r))
  y=$((RANDOM - r))
  if [ $((x**2 + y**2)) -lt $((r**2)) ]; then
    let "hits += 1"
  fi
  let "attempts += 1"
  echo -en "\r$(decimal_representation $((4 * hits)) $attempts)"
done