Skip to content

Commit 7401b65

Browse files
authored
init: add Position Pro permutation iterator and benchmark
- Core logic: Implement high-performance PP algorithm by Yusheng Hu. - Optimization: Tuned for JIT compilers (PyPy) with in-place list modification. - Benchmarking: Included automated comparison with itertools.permutations. - Standardization: Established standardized Markdown output for CI/CD integration.
1 parent 45bd6cb commit 7401b65

1 file changed

Lines changed: 97 additions & 0 deletions

File tree

python/pp_iter.py

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
"""
2+
Position Pro (PP) Algorithm
3+
A high-performance permutation generation algorithm.
4+
5+
Copyright (c) 2026 Yusheng Hu. All rights reserved.
6+
Author: Yusheng Hu
7+
"""
8+
9+
import itertools
10+
import time
11+
import sys
12+
import math
13+
14+
def pp_permutations(n):
15+
"""
16+
Position Pro (PP) Algorithm - Iterator Implementation.
17+
18+
Generates all permutations of n elements. This implementation is
19+
specifically optimized for JIT compilers (e.g., PyPy).
20+
21+
Args:
22+
n (int): Number of elements to permute.
23+
24+
Yields:
25+
list: The current permutation (yields the same list object modified in-place).
26+
"""
27+
# Initialize control and permutation arrays
28+
c = [0] * n
29+
d = list(range(n))
30+
31+
# Cache values for performance
32+
n_m_1 = n - 1
33+
n_m_2 = n - 2
34+
i = 0
35+
inner_indices = list(range(n))
36+
37+
while c[0] < 1:
38+
# Incremental synchronization phase
39+
while i < n_m_1:
40+
idx = i
41+
ci = c[idx]
42+
d[idx], d[ci] = d[ci], d[idx]
43+
i += 1
44+
45+
# Core high-speed generation phase
46+
last_val = d[n_m_1]
47+
for ii in inner_indices:
48+
temp_val = d[ii]
49+
d[n_m_1] = temp_val
50+
d[ii] = n_m_1
51+
52+
yield d
53+
54+
d[ii] = temp_val
55+
d[n_m_1] = last_val
56+
57+
# Carry logic for factorial progression
58+
d[c[n_m_2]], d[n_m_2] = d[n_m_2], d[c[n_m_2]]
59+
c[n_m_2] += 1
60+
61+
curr_i = n_m_2
62+
while curr_i > 0 and c[curr_i] > curr_i:
63+
c[curr_i] = 0
64+
curr_i -= 1
65+
c[curr_i] += 1
66+
# State backtracking
67+
p_idx = c[curr_i] - 1
68+
d[p_idx], d[curr_i] = d[curr_i], d[p_idx]
69+
i = curr_i
70+
71+
def run_performance_benchmarks(start_n=10, end_n=12):
72+
"""
73+
Runs performance benchmarks comparing PP Algorithm with itertools.permutations.
74+
Outputs results in Markdown table format for GitHub Action summaries.
75+
"""
76+
print(f"| N | Total Permutations | Itertools (s) | Position Pro (s) | Speed-up |")
77+
print(f"| :--- | :--- | :--- | :--- | :--- |")
78+
79+
for n in range(start_n, end_n + 1):
80+
# Benchmark itertools.permutations
81+
t0 = time.perf_counter()
82+
for _ in itertools.permutations(range(n)):
83+
pass
84+
t_std = time.perf_counter() - t0
85+
86+
# Benchmark Position Pro algorithm
87+
t1 = time.perf_counter()
88+
for _ in pp_permutations(n):
89+
pass
90+
t_pp = time.perf_counter() - t1
91+
92+
total = math.factorial(n)
93+
speed_up = t_std / t_pp
94+
print(f"| {n} | {total:,} | {t_std:.4f}s | {t_pp:.4f}s | **{speed_up:.2f}x** |")
95+
96+
if __name__ == "__main__":
97+
run_performance_benchmarks(10, 12)

0 commit comments

Comments
 (0)