5 Best Ways to Check if a Sequence Can Form an Arithmetic Progression in Python

Rate this post

πŸ’‘ Problem Formulation: The task is to determine whether a given sequence of numbers can be reordered to form an arithmetic progression, where each term after the first is obtained by adding a constant difference to the previous term. For example, given the input [1, 5, 3], the desired output is True, as the sequence can be reordered to [1, 3, 5], which is an arithmetic progression with a common difference of 2.

Method 1: Sorting and Validating

This method involves sorting the sequence and then checking if the difference between consecutive elements is constant. This approach is straightforward and efficient, ensuring the sequence can be traversed linearly to validate the arithmetic progression.

Here’s an example:

def is_arithmetic_progression(seq):
    seq.sort()
    difference = seq[1] - seq[0]
    return all(seq[i] - seq[i - 1] == difference for i in range(2, len(seq)))

print(is_arithmetic_progression([1, 5, 3]))

Output: True

The code snippet defines a function is_arithmetic_progression(), which first sorts the sequence. It then calculates the common difference and checks if all consecutive pairs have the same difference. If the differences are consistent, it returns True, indicating an arithmetic progression is possible.

Method 2: Using Set Mathematics

This method employs set mathematics to reduce complexity. By calculating the potential common difference using the min and max values and verifying the set of sequence diffs, we can determine the possibility of an arithmetic progression without sorting.

Here’s an example:

def can_form_arithmetic_prog(seq):
    if len(seq) < 2: return True
    seq_set = set(seq)
    min_val, max_val = min(seq_set), max(seq_set)
    expected_diff = (max_val - min_val) / (len(seq) - 1)
    return all((min_val + i * expected_diff) in seq_set for i in range(len(seq)))

print(can_form_arithmetic_prog([1, 5, 3]))

Output: True

This code defines a function can_form_arithmetic_prog() that calculates the expected common difference with the given formula. It then verifies if each expected term, based on this difference, is in the set of sequence values. An arithmetic progression is possible if all expected values are present.

Method 3: Using Statistics

This method employs statistical measures (mean and median) to ascertain the possibility of forming an arithmetic progression. The mean and median of an arithmetic series match if it can be arranged into one.

Here’s an example:

from statistics import mean, median

def is_valid_arithmetic_seq(seq):
    return mean(seq) == median(seq)

print(is_valid_arithmetic_seq([1, 5, 3]))

Output: True

In this code, the is_valid_arithmetic_seq() function compares the mean and median of the sequence. If these two values are equal, the function returns True, suggesting the sequence can indeed be arranged to form an arithmetic progression.

Method 4: Recursive Checking

This sophisticated method recursively checks whether an arithmetic progression can be created by systematically attempting to construct it. It is a brute-force approach that works well with short sequences but is inefficient for longer ones.

Here’s an example:

from itertools import permutations 

def is_progression(seq):
    for perm in permutations(seq):
        if all(perm[i] - perm[i - 1] == perm[1] - perm[0] for i in range(2, len(perm))):
            return True
    return False

print(is_progression([1, 5, 3]))

Output: True

The is_progression() function generates all permutations of the sequence and for each checks whether they are in arithmetic progression. It returns True for the first successful instance and defaults to False if none are found.

Bonus One-Liner Method 5: Using numpy

For those who appreciate elegant one-liners, numpy’s array manipulation abilities can come in handy to succinctly express the arithmetic progression problem.

Here’s an example:

import numpy as np

can_form_ap = lambda seq: np.all(np.diff(sorted(seq)) == (max(seq) - min(seq)) / (len(seq) - 1))

print(can_form_ap([1, 5, 3]))

Output: True

The lambda function can_form_ap sorts the sequence, computes differences between consecutive elements using numpy’s np.diff, and checks if these differences are all equal to the expected difference. It’s a concise and performant one-liner with the power of numpy.

Summary/Discussion

  • Method 1: Sorting and Validating. Strengths: Simple and straightforward. Weaknesses: Requires the sequence to be sorted, which has a complexity of O(n log n).
  • Method 2: Using Set Mathematics. Strengths: More efficient as it eliminates the need for sorting. Weaknesses: Assumes distinct elements, fails if sequence contains repeats.
  • Method 3: Using Statistics. Strengths: Extremely simple and quick for small sequences. Weaknesses: Can give false positives in some edge cases with multiple identical elements.
  • Method 4: Recursive Checking. Strengths: Exhaustive. Weaknesses: Computationally expensive, not suitable for long sequences due to the factorial time complexity.
  • Bonus One-Liner Method 5: Using numpy. Strengths: Elegant and efficient, especially for those who are familiar with numpy. Weaknesses: External dependency on the numpy library.