require "big"

def pow10(exp : Int32) : BigInt
  result = BigInt.new(1)
  exp.times do
    result *= 10
  end
  result
end

def arctan(x : Int32, decimals : Int32) : BigInt
  scale = pow10(decimals + 10)
  x_squared = x * x
  
  term = scale // x
  result = BigInt.new(0)
  n = 0
  
  while term != 0
    divisor = 2 * n + 1
    contrib = term // divisor
    
    if n % 2 == 0
      result += contrib
    else
      result -= contrib
    end
    
    term = term // x_squared
    n += 1
  end
  
  result
end

def calculate_pi(decimals : Int32) : String
  atan1_5 = arctan(5, decimals)
  atan1_239 = arctan(239, decimals)
  
  # pi = 16*arctan(1/5) - 4*arctan(1/239)
  pi = 16 * atan1_5 - 4 * atan1_239
  
  pi_str = pi.to_s
  
  # Format with decimal point
  result = "3."
  start = 1
  
  decimals.times do |i|
    if start + i < pi_str.size
      result += pi_str[start + i].to_s
    else
      result += "0"
    end
  end
  
  result
end

# Main
decimals = ARGV.size > 0 ? ARGV[0].to_i? || 100 : 100

puts calculate_pi(decimals)