Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Program to find number of sequences after adjacent k swaps and at most k swaps in Python
We need to find how many sequences can be generated from an array of first n natural numbers using exactly k adjacent swaps (S1) and at most k adjacent swaps (S2). Adjacent swaps means swapping elements at positions i and i+1.
Problem Understanding
Given an array A with first n natural numbers [1, 2, 3, ..., n], we calculate ?
- S1: Number of sequences after exactly k adjacent swaps
- S2: Number of sequences after at most k adjacent swaps
Example Walkthrough
For n = 3, k = 2 with original array [1, 2, 3] ?
Exactly 2 Adjacent Swaps (S1)
Starting from [1, 2, 3], we can get ?
- [1, 2, 3] ? [1, 3, 2] ? [3, 1, 2]
- [1, 2, 3] ? [2, 1, 3] ? [2, 3, 1]
- [1, 2, 3] ? [1, 3, 2] ? [1, 2, 3] (back to original)
So S1 = 3 unique sequences.
At Most 2 Adjacent Swaps (S2)
- 0 swaps: [1, 2, 3]
- 1 swap: [2, 1, 3], [1, 3, 2]
- 2 swaps: [1, 2, 3], [2, 3, 1], [3, 1, 2]
So S2 = 6 total sequences (including duplicates from different swap counts).
Algorithm Implementation
The solution uses dynamic programming to build arrays A and C that track the number of sequences ?
def solve(n, k):
p = 10**9 + 7
A = [1] # Tracks sequences for exact swaps
C = [1] # Tracks sequences for at most swaps
for curr_n in range(2, n + 1):
B = A[:]
A = [1]
D = C[:]
C = [1]
# Calculate sequences for exact swaps
max_swaps = min(k + 1, curr_n * (curr_n - 1) // 2 + 1)
for x in range(1, max_swaps):
val = A[-1]
if x < len(B):
val += B[x]
if x - curr_n >= 0 and x - curr_n < len(B):
val -= B[x - curr_n]
A.append(val % p)
# Calculate sequences for at most swaps
for x in range(1, curr_n - 1):
if x < len(D):
C.append((D[x] + (curr_n - 1) * D[x - 1]) % p)
if D:
C.append(curr_n * D[-1] % p)
# S1: Sum sequences with same parity as k
s1 = sum(A[k % 2:k + 1:2]) % p
# S2: Sequences with at most k swaps
s2 = C[min(curr_n - 1, k)] if min(curr_n - 1, k) < len(C) else 0
return s1, s2
# Test the function
n = 3
k = 2
result = solve(n, k)
print(f"Exactly {k} swaps: {result[0]}")
print(f"At most {k} swaps: {result[1]}")
Exactly 2 swaps: 3 At most 2 swaps: 6
How the Algorithm Works
The solution builds up results incrementally ?
- Array A: Stores number of sequences achievable with exactly x adjacent swaps
- Array C: Stores number of sequences achievable with at most x adjacent swaps
- For each array size from 2 to n, it updates both arrays using recurrence relations
- The final answer extracts S1 from A and S2 from C
Conclusion
This dynamic programming approach efficiently calculates both exact and at-most adjacent swap sequences. The algorithm handles the combinatorial complexity of tracking all possible swap sequences through careful state transitions.
