Initial commit: Pi calculation benchmark with 34 languages
- Added implementations for: bash, brainfuck, c, cpp, crystal, csharp, d, dart, elixir, erlang, fortran, go, haskell, java, javascript, julia, kotlin, objective-c, scala, typescript, lua, nim, odin, perl, php, python, r, ruby, rust, swift, zig, assembly, vimscript, wolfram - All implementations use Machin's formula: π/4 = 4*arctan(1/5) - arctan(1/239) - Build system with ./build.sh, test system with ./test.sh - Performance testing with ./run_all.sh - Comprehensive README.md explaining performance differences - Test framework verifies correctness against known π values
This commit is contained in:
Executable
+29
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Elixir Build Script
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
echo "=== Elixir Build ==="
|
||||
echo ""
|
||||
|
||||
# Elixir är ett interpreterat språk, ingen kompilering behövs
|
||||
# Skapa wrapper script
|
||||
|
||||
mkdir -p bin
|
||||
cat > bin/print_hej << 'EOF'
|
||||
#!/bin/bash
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
elixir src/print_hej.exs "$@"
|
||||
EOF
|
||||
chmod +x bin/print_hej
|
||||
|
||||
echo "✓ Ingen kompilering behövs för Elixir"
|
||||
echo " Använder Elixir interpreter"
|
||||
echo ""
|
||||
echo "Wrapper script skapad: bin/print_hej"
|
||||
echo ""
|
||||
echo "För att köra:"
|
||||
echo " ./bin/print_hej [decimaler]"
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Elixir Test Script
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
echo "=== Elixir Test ==="
|
||||
echo ""
|
||||
|
||||
# Testa pi-beräkning med olika antal decimaler
|
||||
for decimals in 1 2 5 10 100; do
|
||||
result=$(./bin/print_hej $decimals 2>/dev/null)
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ $decimals decimaler: $result"
|
||||
else
|
||||
echo "✗ $decimals decimaler misslyckades"
|
||||
fi
|
||||
done
|
||||
@@ -0,0 +1,108 @@
|
||||
# Pi calculation using Machin's formula
|
||||
# pi/4 = 4*arctan(1/5) - arctan(1/239)
|
||||
|
||||
defmodule PiCalculator do
|
||||
# Calculate arctan(1/x) using Taylor series with arbitrary precision
|
||||
# arctan(1/x) = 1/x - 1/(3*x^3) + 1/(5*x^5) - ...
|
||||
def arctan(x, decimals) do
|
||||
# Use integer power to avoid float precision loss
|
||||
scale = power(10, decimals + 10)
|
||||
x_squared = x * x
|
||||
|
||||
# Taylor series: arctan(1/x) = sum((-1)^n * 1/((2n+1) * x^(2n+1)))
|
||||
# We compute this iteratively:
|
||||
# term_0 = scale / x (represents 1/x with scale factor)
|
||||
# For each n:
|
||||
# contrib = term / (2n+1)
|
||||
# result += sign * contrib
|
||||
# term = term / x²
|
||||
# sign = -sign
|
||||
|
||||
term = div(scale, x)
|
||||
compute(x_squared, term, 0, 0, true, decimals * 3)
|
||||
end
|
||||
|
||||
# Calculate 10^n using integer arithmetic
|
||||
defp power(10, n) when n >= 0 do
|
||||
Integer.pow(10, n)
|
||||
end
|
||||
|
||||
defp compute(_x_squared, 0, result, _n, _sign, _max_iterations), do: result
|
||||
defp compute(_x_squared, _term, result, n, _sign, max_iterations) when n >= max_iterations, do: result
|
||||
defp compute(x_squared, term, result, n, sign, max_iterations) do
|
||||
divisor = 2 * n + 1
|
||||
|
||||
# Only compute if divisor > 0
|
||||
if divisor > 0 do
|
||||
contrib = div(term, divisor)
|
||||
|
||||
new_result = if sign do
|
||||
result + contrib
|
||||
else
|
||||
result - contrib
|
||||
end
|
||||
|
||||
new_term = div(term, x_squared)
|
||||
|
||||
compute(x_squared, new_term, new_result, n + 1, not sign, max_iterations)
|
||||
else
|
||||
result
|
||||
end
|
||||
end
|
||||
|
||||
# Calculate pi using Machin's formula
|
||||
def calculate_pi(decimals) do
|
||||
actual_decimals = if decimals < 1, do: 100, else: decimals
|
||||
|
||||
# Machin's formula: pi/4 = 4*arctan(1/5) - arctan(1/239)
|
||||
# pi = 16*arctan(1/5) - 4*arctan(1/239)
|
||||
arctan5 = arctan(5, actual_decimals)
|
||||
arctan239 = arctan(239, actual_decimals)
|
||||
|
||||
pi = 16 * arctan5 - 4 * arctan239
|
||||
|
||||
# Format output
|
||||
pi_str = Integer.to_string(pi)
|
||||
|
||||
if actual_decimals == 0 do
|
||||
"3"
|
||||
else
|
||||
# Pad with zeros if needed
|
||||
padded = if String.length(pi_str) < actual_decimals + 1 do
|
||||
zeros_needed = actual_decimals + 1 - String.length(pi_str)
|
||||
String.duplicate("0", zeros_needed) <> pi_str
|
||||
else
|
||||
pi_str
|
||||
end
|
||||
|
||||
# Insert decimal point
|
||||
before_decimal = String.slice(padded, 0, 1)
|
||||
after_decimal = String.slice(padded, 1..-1//1)
|
||||
|
||||
# Pad or truncate to desired length
|
||||
final_after_decimal = if String.length(after_decimal) < actual_decimals do
|
||||
after_decimal <> String.duplicate("0", actual_decimals - String.length(after_decimal))
|
||||
else
|
||||
String.slice(after_decimal, 0, actual_decimals)
|
||||
end
|
||||
|
||||
"#{before_decimal}.#{final_after_decimal}"
|
||||
end
|
||||
end
|
||||
|
||||
def main(args) do
|
||||
decimals = case args do
|
||||
[d | _] ->
|
||||
case Integer.parse(d) do
|
||||
{n, _} when n > 0 -> n
|
||||
_ -> 100
|
||||
end
|
||||
[] -> 100
|
||||
end
|
||||
|
||||
IO.puts(calculate_pi(decimals))
|
||||
end
|
||||
end
|
||||
|
||||
# Run with: elixir print_hej.exs [decimals]
|
||||
PiCalculator.main(System.argv())
|
||||
Reference in New Issue
Block a user