File: algo.py

package info (click to toggle)
crazy-complete 0.3.7-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,528 kB
  • sloc: python: 13,342; sh: 995; makefile: 68
file content (88 lines) | stat: -rw-r--r-- 2,139 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright (C) 2025-2026 Benjamin Abendroth <braph93@gmx.de>

'''Algorithm functions.'''

from collections import OrderedDict


def flatten(iterable):
    '''Flatten a list of iterables into a single list.'''

    result = []
    for item in iterable:
        result.extend(item)
    return result


def uniq(iterable):
    '''Return list of unique items, preserving order.'''

    result = []
    seen = set()
    for item in iterable:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result


def partition(iterable, predicate):
    '''Split an iterable into two lists based on a predicate.

    Args:
        iterable:
            The input iterable to split.
        predicate (callable):
            A function returning True or False for each element.

    Returns:
        tuple: (matched, unmatched) where
            matched   -- list of items for which predicate(item) is True
            unmatched -- list of items for which predicate(item) is False
    '''

    a, b = [], []
    for item in iterable:
        if predicate(item):
            a.append(item)
        else:
            b.append(item)
    return (a, b)


def group_by(iterable, keyfunc):
    '''Group items from an iterable by a key function.

    Args:
        iterable:
            The input iterable of items to group.
        keyfunc (callable):
            Function applied to each item to determine its group key.

    Returns:
        OrderedDict:
            A mapping of key -> list of items with that key, preserving
            the order of first appearance of each key.
    '''
    result = OrderedDict()

    for item in iterable:
        val = keyfunc(item)

        if val in result:
            result[val].append(item)
        else:
            result[val] = [item]

    return result


def numbers_are_contiguous(numbers):
    '''Return True if the list of integers is contiguous (1, 2, 3, 4, ...)'''

    if not numbers:
        return False

    sorted_nums = sorted(numbers)
    return all(b - a == 1 for a, b in zip(sorted_nums, sorted_nums[1:]))