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
+23
@@ -0,0 +1,23 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Haskell Build Script
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
echo "=== Haskell Build ==="
|
||||
echo ""
|
||||
|
||||
# Kompilera Haskell-programmet
|
||||
ghc -o bin/print_hej src/print_hej.hs
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "✓ Kompilering lyckades!"
|
||||
echo "Binär: bin/print_hej"
|
||||
echo ""
|
||||
echo "För att köra:"
|
||||
echo " ./bin/print_hej [decimaler]"
|
||||
else
|
||||
echo "✗ Kompilering misslyckades!"
|
||||
exit 1
|
||||
fi
|
||||
Executable
+19
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Haskell Unit Tests
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$SCRIPT_DIR"
|
||||
|
||||
echo "=== Haskell Pi-beräkning Unit Tester ==="
|
||||
echo ""
|
||||
|
||||
cd src
|
||||
ghc -o ../bin/pi_test PiTest.hs
|
||||
if [ $? -eq 0 ]; then
|
||||
../bin/pi_test
|
||||
exit $?
|
||||
else
|
||||
echo "✗ Kompilering av tester misslyckades!"
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,66 @@
|
||||
module Main where
|
||||
|
||||
import Test.HUnit
|
||||
import System.Process
|
||||
import Data.List (stripPrefix)
|
||||
|
||||
scriptPath :: String
|
||||
scriptPath = "/Users/einand/Code/test/haskell/print_hej"
|
||||
|
||||
runScript :: Maybe String -> IO String
|
||||
runScript mArgs = do
|
||||
let args = maybe [] (\x -> [x]) mArgs
|
||||
output <- readProcess scriptPath args ""
|
||||
return $ init output -- Remove trailing newline
|
||||
|
||||
test10Decimals :: Test
|
||||
test10Decimals = TestCase $ do
|
||||
result <- runScript (Just "10")
|
||||
let expected = "3.1415926535"
|
||||
assertEqual "10 decimals" expected result
|
||||
|
||||
test5Decimals :: Test
|
||||
test5Decimals = TestCase $ do
|
||||
result <- runScript (Just "5")
|
||||
let expected = "3.14159"
|
||||
assertEqual "5 decimals" expected result
|
||||
|
||||
test1Decimal :: Test
|
||||
test1Decimal = TestCase $ do
|
||||
result <- runScript (Just "1")
|
||||
let expected = "3.1"
|
||||
assertEqual "1 decimal" expected result
|
||||
|
||||
test100Decimals :: Test
|
||||
test100Decimals = TestCase $ do
|
||||
result <- runScript (Just "100")
|
||||
let expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
|
||||
assertEqual "100 decimals" expected result
|
||||
|
||||
testDefault100Decimals :: Test
|
||||
testDefault100Decimals = TestCase $ do
|
||||
result <- runScript Nothing
|
||||
let expected = "3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679"
|
||||
assertEqual "default 100 decimals" expected result
|
||||
|
||||
test10000Decimals :: Test
|
||||
test10000Decimals = TestCase $ do
|
||||
result <- runScript (Just "10000")
|
||||
-- Check length: "3." + 10000 digits = 10002 characters
|
||||
assertEqual "10000 decimals length" 10002 (length result)
|
||||
assertBool "10000 decimals starts with 3.14159" (take 7 result == "3.14159")
|
||||
|
||||
tests :: Test
|
||||
tests = TestList [
|
||||
TestLabel "test10Decimals" test10Decimals,
|
||||
TestLabel "test5Decimals" test5Decimals,
|
||||
TestLabel "test1Decimal" test1Decimal,
|
||||
TestLabel "test100Decimals" test100Decimals,
|
||||
TestLabel "testDefault100Decimals" testDefault100Decimals,
|
||||
TestLabel "test10000Decimals" test10000Decimals
|
||||
]
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
counts <- runTestTT tests
|
||||
putStrLn $ showCounts counts
|
||||
@@ -0,0 +1,49 @@
|
||||
module Main where
|
||||
|
||||
import System.Environment (getArgs)
|
||||
import Data.Char (digitToInt)
|
||||
|
||||
-- Calculate arctan(1/x) using Taylor series
|
||||
-- arctan(1/x) = 1/x - 1/(3*x^3) + 1/(5*x^5) - ...
|
||||
arctan :: Integer -> Integer -> Integer
|
||||
arctan x decimals = arctanIter scale xSquared term 0 0
|
||||
where
|
||||
scale = 10 ^ (decimals + 10)
|
||||
xSquared = x * x
|
||||
term = scale `div` x -- First term: scale / x
|
||||
|
||||
arctanIter :: Integer -> Integer -> Integer -> Integer -> Integer -> Integer
|
||||
arctanIter scale xSquared term n result
|
||||
| term == 0 || n > decimals * 3 = result
|
||||
| otherwise = arctanIter scale xSquared newTerm (n + 1) newResult
|
||||
where
|
||||
divisor = 2 * n + 1
|
||||
contrib = term `div` divisor
|
||||
newResult = if even n
|
||||
then result + contrib
|
||||
else result - contrib
|
||||
newTerm = term `div` xSquared -- Divide by x² each iteration
|
||||
|
||||
-- Calculate pi using Machin's formula
|
||||
-- pi/4 = 4*arctan(1/5) - arctan(1/239)
|
||||
calculatePi :: Integer -> Integer
|
||||
calculatePi decimals = 16 * atan1_5 - 4 * atan1_239
|
||||
where
|
||||
atan1_5 = arctan 5 decimals
|
||||
atan1_239 = arctan 239 decimals
|
||||
|
||||
-- Format pi with decimal point
|
||||
formatPi :: Integer -> Integer -> String
|
||||
formatPi pi decimals = "3." ++ take (fromIntegral decimals) (drop 1 (show pi))
|
||||
|
||||
main :: IO ()
|
||||
main = do
|
||||
args <- getArgs
|
||||
let decimals = case args of
|
||||
[] -> 100
|
||||
(x:_) -> case reads x :: [(Integer, String)] of
|
||||
[(d, _)] -> if d > 0 then d else 100
|
||||
_ -> 100
|
||||
|
||||
let pi = calculatePi decimals
|
||||
putStrLn (formatPi pi decimals)
|
||||
Reference in New Issue
Block a user