Skip to content

Commit 843b6d1

Browse files
committed
Improved performance of 2017-15
1 parent d3a46fd commit 843b6d1

File tree

2 files changed

+140
-41
lines changed

2 files changed

+140
-41
lines changed

2017/15-Dueling Generators.py

Lines changed: 45 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,90 +4,94 @@
44
test_data = {}
55

66
test = 1
7-
test_data[test] = {"input": """Generator A starts with 65
7+
test_data[test] = {
8+
"input": """Generator A starts with 65
89
Generator B starts with 8921""",
9-
"expected": ['588', 'Unknown'],
10-
}
11-
12-
test = 'real'
13-
input_file = os.path.join(os.path.dirname(__file__), 'Inputs', os.path.basename(__file__).replace('.py', '.txt'))
14-
test_data[test] = {"input": open(input_file, "r+").read().strip(),
15-
"expected": ['597', '303'],
16-
}
10+
"expected": ["588", "Unknown"],
11+
}
12+
13+
test = "real"
14+
input_file = os.path.join(
15+
os.path.dirname(__file__),
16+
"Inputs",
17+
os.path.basename(__file__).replace(".py", ".txt"),
18+
)
19+
test_data[test] = {
20+
"input": open(input_file, "r+").read().strip(),
21+
"expected": ["597", "303"],
22+
}
1723

1824
# -------------------------------- Control program execution -------------------------------- #
1925

20-
case_to_test = 'real'
21-
part_to_test = 2
26+
case_to_test = "real"
27+
part_to_test = 2
2228
verbose_level = 1
2329

2430
# -------------------------------- Initialize some variables -------------------------------- #
2531

26-
puzzle_input = test_data[case_to_test]['input']
27-
puzzle_expected_result = test_data[case_to_test]['expected'][part_to_test-1]
28-
puzzle_actual_result = 'Unknown'
32+
puzzle_input = test_data[case_to_test]["input"]
33+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
34+
puzzle_actual_result = "Unknown"
2935

3036

3137
# -------------------------------- Actual code execution -------------------------------- #
3238

3339
divisor = 2147483647
34-
factors = {'A': 16807, 'B': 48271}
35-
value = {'A': 0, 'B': 0}
40+
factors = {"A": 16807, "B": 48271}
41+
value = {"A": 0, "B": 0}
3642

3743

38-
def gen_a ():
44+
def gen_a():
45+
x = value["A"]
3946
while True:
40-
value['A'] *= factors['A']
41-
value['A'] %= divisor
42-
if value['A'] % 4 == 0:
43-
yield value['A']
47+
x *= 16807
48+
x %= 2147483647
49+
if x % 4 == 0:
50+
yield x
51+
4452

45-
def gen_b ():
53+
def gen_b():
54+
x = value["B"]
4655
while True:
47-
value['B'] *= factors['B']
48-
value['B'] %= divisor
49-
if value['B'] % 8 == 0:
50-
yield value['B']
56+
x *= 48271
57+
x %= 2147483647
58+
if x % 8 == 0:
59+
yield x
60+
5161

5262
if part_to_test == 1:
53-
for string in puzzle_input.split('\n'):
63+
for string in puzzle_input.split("\n"):
5464
_, generator, _, _, start_value = string.split()
5565
value[generator] = int(start_value)
5666

5767
nb_matches = 0
58-
for i in range (40 * 10 ** 6):
68+
for i in range(40 * 10 ** 6):
5969
value = {gen: value[gen] * factors[gen] % divisor for gen in value}
60-
if '{0:b}'.format(value['A'])[-16:] == '{0:b}'.format(value['B'])[-16:]:
70+
if "{0:b}".format(value["A"])[-16:] == "{0:b}".format(value["B"])[-16:]:
6171
nb_matches += 1
6272

6373
puzzle_actual_result = nb_matches
6474

6575

6676
else:
67-
for string in puzzle_input.split('\n'):
77+
for string in puzzle_input.split("\n"):
6878
_, generator, _, _, start_value = string.split()
6979
value[generator] = int(start_value)
7080

7181
nb_matches = 0
7282
A = gen_a()
7383
B = gen_b()
74-
for count_pairs in range (5 * 10**6):
84+
for count_pairs in range(5 * 10 ** 6):
7585
a, b = next(A), next(B)
76-
if '{0:b}'.format(a)[-16:] == '{0:b}'.format(b)[-16:]:
86+
if a & 0xFFFF == b & 0xFFFF:
7787
nb_matches += 1
7888

79-
8089
puzzle_actual_result = nb_matches
8190

8291

83-
8492
# -------------------------------- Outputs / results -------------------------------- #
8593

8694
if verbose_level >= 3:
87-
print ('Input : ' + puzzle_input)
88-
print ('Expected result : ' + str(puzzle_expected_result))
89-
print ('Actual result : ' + str(puzzle_actual_result))
90-
91-
92-
93-
95+
print("Input : " + puzzle_input)
96+
print("Expected result : " + str(puzzle_expected_result))
97+
print("Actual result : " + str(puzzle_actual_result))

2017/15-Dueling Generators.v1.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# -------------------------------- Input data -------------------------------- #
2+
import os
3+
4+
test_data = {}
5+
6+
test = 1
7+
test_data[test] = {
8+
"input": """Generator A starts with 65
9+
Generator B starts with 8921""",
10+
"expected": ["588", "Unknown"],
11+
}
12+
13+
test = "real"
14+
input_file = os.path.join(
15+
os.path.dirname(__file__),
16+
"Inputs",
17+
os.path.basename(__file__).replace(".py", ".txt"),
18+
)
19+
test_data[test] = {
20+
"input": open(input_file, "r+").read().strip(),
21+
"expected": ["597", "303"],
22+
}
23+
24+
# -------------------------------- Control program execution -------------------------------- #
25+
26+
case_to_test = "real"
27+
part_to_test = 2
28+
verbose_level = 1
29+
30+
# -------------------------------- Initialize some variables -------------------------------- #
31+
32+
puzzle_input = test_data[case_to_test]["input"]
33+
puzzle_expected_result = test_data[case_to_test]["expected"][part_to_test - 1]
34+
puzzle_actual_result = "Unknown"
35+
36+
37+
# -------------------------------- Actual code execution -------------------------------- #
38+
39+
divisor = 2147483647
40+
factors = {"A": 16807, "B": 48271}
41+
value = {"A": 0, "B": 0}
42+
43+
44+
def gen_a():
45+
while True:
46+
value["A"] *= factors["A"]
47+
value["A"] %= divisor
48+
if value["A"] % 4 == 0:
49+
yield value["A"]
50+
51+
52+
def gen_b():
53+
while True:
54+
value["B"] *= factors["B"]
55+
value["B"] %= divisor
56+
if value["B"] % 8 == 0:
57+
yield value["B"]
58+
59+
60+
if part_to_test == 1:
61+
for string in puzzle_input.split("\n"):
62+
_, generator, _, _, start_value = string.split()
63+
value[generator] = int(start_value)
64+
65+
nb_matches = 0
66+
for i in range(40 * 10 ** 6):
67+
value = {gen: value[gen] * factors[gen] % divisor for gen in value}
68+
if "{0:b}".format(value["A"])[-16:] == "{0:b}".format(value["B"])[-16:]:
69+
nb_matches += 1
70+
71+
puzzle_actual_result = nb_matches
72+
73+
74+
else:
75+
for string in puzzle_input.split("\n"):
76+
_, generator, _, _, start_value = string.split()
77+
value[generator] = int(start_value)
78+
79+
nb_matches = 0
80+
A = gen_a()
81+
B = gen_b()
82+
for count_pairs in range(5 * 10 ** 6):
83+
a, b = next(A), next(B)
84+
if "{0:b}".format(a)[-16:] == "{0:b}".format(b)[-16:]:
85+
nb_matches += 1
86+
87+
puzzle_actual_result = nb_matches
88+
89+
90+
# -------------------------------- Outputs / results -------------------------------- #
91+
92+
if verbose_level >= 3:
93+
print("Input : " + puzzle_input)
94+
print("Expected result : " + str(puzzle_expected_result))
95+
print("Actual result : " + str(puzzle_actual_result))

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy