Skip to content

Commit 2948efc

Browse files
author
Tudor Marghidanu
committed
Ponylang implementation
1 parent 7dd7d11 commit 2948efc

File tree

3 files changed

+188
-0
lines changed

3 files changed

+188
-0
lines changed

PrimePony/solution_1/Dockerfile

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
FROM ponylang/ponyc:0.41.1-alpine AS build
2+
3+
WORKDIR /opt/app
4+
COPY primes.pony .
5+
6+
RUN ponyc . -b primes --static
7+
8+
FROM alpine:3.13
9+
10+
COPY --from=build /opt/app/primes /usr/local/bin
11+
12+
ENTRYPOINT [ "primes" ]

PrimePony/solution_1/README.md

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Pony implementation
2+
3+
![Algorithm](https://img.shields.io/badge/Algorithm-base-green)
4+
![Faithfulness](https://img.shields.io/badge/Faithful-yes-green)
5+
![Parallelism](https://img.shields.io/badge/Parallel-no-green)
6+
![Bit count](https://img.shields.io/badge/Bits-unknown-yellowgreen)
7+
8+
## Run
9+
10+
### Run locally
11+
12+
Pony installation instructions are available at: https://github.com/ponylang/ponyc/blob/main/INSTALL.md
13+
14+
### Docker
15+
16+
```
17+
docker build -t primes .
18+
docker run --rm primes
19+
```
20+
21+
## Benchmarks
22+
23+
**Machine:** MacBook Pro (13-inch, 2018, Four Thunderbolt 3 Ports)<br/>
24+
**Processor:** 2.3 GHz Quad-Core Intel Core i5<br/>
25+
**Memory:** 16GB 2133 MHz LPDDR3<br/>
26+
27+
```
28+
marghidanu;2203;5;1;algorithm=base,faithful=yes,bits=1
29+
marghidanu;2231;5;1;algorithm=base,faithful=yes,bits=1
30+
marghidanu;2272;5;1;algorithm=base,faithful=yes,bits=1
31+
marghidanu;2325;5;1;algorithm=base,faithful=yes,bits=1
32+
marghidanu;2338;5;1;algorithm=base,faithful=yes,bits=1
33+
marghidanu;2396;5;1;algorithm=base,faithful=yes,bits=1
34+
marghidanu;1974;5;1;algorithm=base,faithful=yes,bits=1
35+
marghidanu;2438;5;1;algorithm=base,faithful=yes,bits=1
36+
marghidanu;2457;5;1;algorithm=base,faithful=yes,bits=1
37+
marghidanu;2475;5;1;algorithm=base,faithful=yes,bits=1
38+
```
39+
40+
## Notes
41+
42+
I couldn't install the compiler on macOS; the entire development has been done inside a Docker container.
43+
Interesting language with exciting features, documentation could be better. I would love to see another take on this.
44+
45+
More information at https://www.ponylang.io/
46+
47+
## Author
48+
49+
Tudor Marghidanu
50+
https://marghidanu.com/

PrimePony/solution_1/primes.pony

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
use "collections"
2+
use "format"
3+
use "time"
4+
5+
class PrimeSieve
6+
let _env: Env
7+
let _dictionary: Map[U64, U64]
8+
let _sieve_size: U64
9+
let _bits: Array[Bool]
10+
11+
new create(env': Env, dictionary': Map[U64, U64], sieve_size': U64) =>
12+
_env = env'
13+
_dictionary = dictionary'
14+
15+
_sieve_size = sieve_size'
16+
_bits = Array[Bool].init(false, _sieve_size.usize())
17+
18+
fun ref run_sieve() =>
19+
var factor : U64 = U64(3)
20+
let q = _sieve_size.f64().sqrt().u64()
21+
22+
while factor <= q do
23+
var num = factor
24+
while num < _sieve_size do
25+
try
26+
if not _bits(num.usize())? then
27+
factor = num
28+
break
29+
end
30+
end
31+
32+
num = num + 2
33+
end
34+
35+
var num2 = factor * factor
36+
while num2 < _sieve_size do
37+
try _bits.update(num2.usize(), true)? end
38+
num2 = num2 + (factor * 2)
39+
end
40+
41+
factor = factor + 2
42+
end
43+
44+
fun print_results(show_results: Bool, duration: I64, passes: U64) =>
45+
if show_results then
46+
_env.out.print("2")
47+
end
48+
49+
var count: U64 = 1
50+
for index in Range[U64](3, _sieve_size, 2) do
51+
try
52+
if not _bits(index.usize())? then
53+
if show_results then _env.out.print(Format.int[U64](index)) end
54+
count = count + 1
55+
end
56+
end
57+
end
58+
59+
if show_results then
60+
_env.out.print("")
61+
end
62+
63+
_env.out.print(
64+
"Passes: " + Format.int[U64](passes) + " " +
65+
"Time: " + Format.int[I64](duration) + " " +
66+
"Limit: " + Format.int[U64](_sieve_size) + " " +
67+
"Count1: " + Format.int[U64](count) + " " +
68+
"Count2: " + Format.int[U64](count_primes()) + " " +
69+
"Valid: " + validate_results().string()
70+
)
71+
72+
_env.out.print(
73+
"marghidanu;" +
74+
Format.int[U64](passes) + ";" +
75+
Format.int[I64](duration) + ";" +
76+
"1;algorithm=base,faithful=yes,bits=1"
77+
)
78+
79+
fun count_primes() : U64 =>
80+
var count : U64 = 1
81+
for index in Range(3, _sieve_size.usize(), 2) do
82+
try
83+
if not _bits(index)? then
84+
count = count + 1
85+
end
86+
end
87+
end
88+
89+
count
90+
91+
fun validate_results() : Bool =>
92+
_dictionary.get_or_else(_sieve_size, 0) == count_primes()
93+
94+
95+
actor Main
96+
new create(env: Env) =>
97+
var passes = U64(0)
98+
let start_time = Time.now()._1
99+
100+
let dictionary = Map[U64, U64].create(10)
101+
dictionary.insert(10, 4)
102+
dictionary.insert(100, 25)
103+
dictionary.insert(1_000, 168)
104+
dictionary.insert(10_000, 1229)
105+
dictionary.insert(100_000, 9592)
106+
dictionary.insert(1_000_000, 78498)
107+
dictionary.insert(10_000_000, 664579)
108+
dictionary.insert(100_000_000, 5761455)
109+
dictionary.insert(1_000_000_000, 50847534)
110+
dictionary.insert(10_000_000_000, 45505251)
111+
112+
while true do
113+
// NOTE: Pony doesn't allow global variables
114+
// therefor we need to pass all dependencies to the class instance.
115+
let sieve = PrimeSieve.create(env, dictionary, U64(1_000_000))
116+
sieve.run_sieve()
117+
passes = passes + 1
118+
119+
// Unfortunately I can only get the seconds as an integer value.
120+
// Pony seems fast enough to make the time variance minimal.
121+
let duration = Time.now()._1 - start_time
122+
if duration >= 5 then
123+
sieve.print_results(false, duration, passes)
124+
break
125+
end
126+
end

0 commit comments

Comments
 (0)