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 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118
| #!/usr/bin/env python
import functools
import timeit
datas = [
[5, 9, 0, 1, 1, 0, 1, 0, 1, 1, 1],
[1, 0, 8, 1, 0, 2, 0, 1, 1, 1, 1],
[1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1],
[0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0],
[0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 0],
]
ok = [
[1, 1, 0, 2, 2, 0, 0, 0, 3, 3, 3],
[0, 0, 1, 1, 0, 0, 0, 2, 2, 2, 2],
[0, 0, 1, 1, 0, 0, 0, 2, 2, 0, 0],
[0, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0],
[0, 1, 1, 0, 0, 0, 0, 2, 2, 2, 0],
]
def split_at_indices(lst, indices):
results = []
prev_index = 0
for index in indices:
results.append(lst[prev_index:index])
prev_index = index + 1
results.append(lst[prev_index:])
return results
def pat(data: list) -> list:
# sauve les index
paired = list(zip(range(len(data)), data))
indices = [x[0] for x in paired if x[1] == 0]
# split et supprime les sequences trop courtes
results = [x for x in split_at_indices(paired, indices) if len(x) > 1]
# formate la sortie fonction du besoin
values = [0] * len(data)
for key, sequence in enumerate(results, start=1):
for value in sequence:
values[value[0]] = key
return values
def fred(data_: list) -> list:
out = []
counter = 0
previous = 0
for current, next_item in zip(data_, data_[1:] + [0]):
# Condition pour savoir si l'élément fait partie d'un bloc connecté (adjacent à un autre élément non nul)
is_in_block = current and (previous or next_item)
# Incrémentation du compteur uniquement au début d'un nouveau bloc connecté
counter += int(is_in_block and not previous)
out.append(counter if is_in_block else 0)
previous = current
return out
def jos(data_: list) -> list:
out = [0] * len(data_)
cmpt = 0
flag = False
# b = [1 if x else 0 for x in data_] + [0]
b = data_[:] + [0]
for i in range(len(out)):
t = b[i] and (b[i - 1] or b[i + 1])
cmpt += t and not flag
flag = t
out[i] = cmpt * t
return out
def wiz(data_: list) -> list:
out = [0] * len(data_)
cmpt = 0
# b = [1 if x else 0 for x in data_] + [0]
b = data_[:] + [0]
for i in range(len(out)):
t = b[i] and (b[i - 1] or b[i + 1])
# cmpt += t and not flag
# flag = t
cmpt += t and not b[i - 1] and b[i]
out[i] = cmpt * t
return out
if __name__ == "__main__":
print()
for name, func in {
"patrick": pat,
"fred": fred,
"wiz": wiz,
"jos": jos,
}.items():
print(name, "---" * 12)
for y, line in enumerate(datas):
results = func(line)
print("> ", line)
print(" ", results, ok[y] == results)
if ok[y] != results:
print("# ", ok[y])
print()
print()
for name, func in {
"patrick": pat,
"fred": fred,
"wiz": wiz,
"jos": jos,
}.items():
t = timeit.Timer(functools.partial(func, datas[3]))
print(f"{name:10} {t.timeit(10_000)}") |
Partager