Passed
Push — master ( 8edc1f...ae5669 )
by Ken M.
01:14
created

life_counter.translate_state()   A

Complexity

Conditions 4

Size

Total Lines 7
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
from collections import defaultdict
2
3
4
def count_neighbours(state, row, col):
5
    neighbors = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)]
6
    return sum([1 for i in neighbors if (row + i[0], col + i[1]) in state])
7
8
9
def cell_changes(state):
10
    changes = defaultdict(int)
11
    if not state:
12
        return changes
13
    coordinates = state.keys()
14
    min_row = min(map(lambda x: x[0], coordinates))
15
    max_row = max(map(lambda x: x[0], coordinates))
16
    min_col = min(map(lambda x: x[1], coordinates))
17
    max_col = max(map(lambda x: x[1], coordinates))
18
    for i in range(min_row - 1, max_row + 2):
19
        for j in range(min_col - 1, max_col + 2):
20
            neighbors = count_neighbours(state, i, j)
21
            if (i, j) in state and neighbors not in [2, 3]:
22
                changes[(i, j)] = 0
23
            elif (i, j) not in state and neighbors == 3:
24
                changes[(i, j)] = 1
25
    return changes
26
27
28
def translate_state(state):
29
    translated_state = defaultdict(int)
30
    for i in range(len(state)):
31
        for j in range(len(state[0])):
32
            if state[i][j] == 1:
33
                translated_state[(i, j)] = 1
34
    return translated_state
35
36
37
def life_counter(state, tick_n):
38
    new_state = translate_state(state)
39
    for _ in range(tick_n):
40
        changes = cell_changes(new_state)
41
        for i in changes:
42
            if changes[i] == 0:
43
                try:
44
                    del new_state[i]
45
                except KeyError:
46
                    pass
47
            else:
48
                new_state[i] = 1
49
    return sum(new_state.values())
50
51
52
if __name__ == '__main__':
53
    # These "asserts" using only for self-checking and not necessary for
54
    # auto-testing
55
    assert (
56
        life_counter(
57
            (
58
                (0, 1, 0, 0, 0, 0, 0),
59
                (0, 0, 1, 0, 0, 0, 0),
60
                (1, 1, 1, 0, 0, 0, 0),
61
                (0, 0, 0, 0, 0, 1, 1),
62
                (0, 0, 0, 0, 0, 1, 1),
63
                (0, 0, 0, 0, 0, 0, 0),
64
                (1, 1, 1, 0, 0, 0, 0),
65
            ),
66
            4,
67
        )
68
        == 15
69
    ), "Example"
70
    assert (
71
        life_counter(
72
            (
73
                (0, 1, 0, 0, 0, 0, 0),
74
                (0, 0, 1, 0, 0, 0, 0),
75
                (1, 1, 1, 0, 0, 0, 0),
76
                (0, 0, 0, 0, 0, 1, 1),
77
                (0, 0, 0, 0, 0, 1, 1),
78
                (0, 0, 0, 0, 0, 0, 0),
79
                (1, 1, 1, 0, 0, 0, 0),
80
            ),
81
            15,
82
        )
83
        == 14
84
    ), "Little later"
85
    assert life_counter(((0, 1, 0), (0, 0, 1), (1, 1, 1)), 50) == 5, "Glider"
86
    assert (
87
        life_counter(
88
            (
89
                (1, 1, 0, 1, 1),
90
                (1, 1, 0, 1, 1),
91
                (0, 0, 0, 0, 0),
92
                (1, 1, 0, 1, 1),
93
                (1, 1, 0, 1, 1),
94
            ),
95
            100,
96
        )
97
        == 16
98
    ), "Stones"
99