1+
2+ # "Do what rachel riley does on countdown"
3+ # - target number (generate?)
4+ # - Get prime factors of target
5+ # - generate set of digits: inputset
6+ # - see if prime factors are in inputset
7+ # + fudge input set to find said primes
8+ # - solve (?)
9+
10+ import random
11+ from typing import Any , Literal
12+
13+ _PRIMES = [2 ,3 ,5 ,7 ,11 ,13 ,17 ,19 ,23 ,29 ,31 ,37 ,41 ,43 ,47 ,53 ,59 ,61 ,67 ,71 ,73 ,79 ,83 ,89 ,97 ,101 ,103 ,107 ,109 ,113 ,
14+ 127 ,131 ,137 ,139 ,149 ,151 ,157 ,163 ,167 ,173 ,
15+ 179 ,181 ,191 ,193 ,197 ,199 ,211 ,223 ,227 ,229 ,
16+ 233 ,239 ,241 ,251 ,257 ,263 ,269 ,271 ,277 ,281 ,
17+ 283 ,293 ,307 ,311 ,313 ,317 ,331 ,337 ,347 ,349 ,
18+ 353 ,359 ,367 ,373 ,379 ,383 ,389 ,397 ,401 ,409 ,
19+ 419 ,421 ,431 ,433 ,439 ,443 ,449 ,457 ,461 ,463 ,
20+ 467 ,479 ,487 ,491 ,499 ,503
21+ ]
22+ def get_prime_factors (number :int ) -> list [int ]:
23+ print (f"{ number = } " )
24+ prime_factors = []
25+ if number == 1 : return []
26+ for prime in _PRIMES [::- 1 ]:
27+ if number % prime == 0 :
28+ prime_factors .append (prime )
29+ return prime_factors + get_prime_factors (number / prime )
30+
31+ return prime_factors
32+
33+
34+ def too_many_primes (target_primes :list [int ], input_set :list [int ]) -> Literal [False ]| str :
35+ """
36+ times two primes togeather because #primes > #inputs
37+ call fudge with smaller targets
38+ """
39+ # Shorten length of target and recurse
40+ for i in range (len (target_primes )):
41+ new_target = target_primes
42+ i_num = new_target .pop (i )
43+ for j in range (len (new_target )):
44+ if i == j : continue
45+ # only ever mult (prime factors)
46+ new_item = i_num * new_target .pop (j )
47+ new_target = new_target .append (new_item )
48+ if (result := fudge_to_find (new_target , input_set )):
49+ return result
50+
51+ def is_trivial (target_primes :list [int ], input_set :list [int ]) -> bool :
52+ for input in input_set :
53+ if input not in target_primes :
54+ return False
55+ return True
56+
57+ def return_smaller_list (a :list [int ], b :list [int ]) -> tuple [list [int ], list [int ]]:
58+ if len (a ) < len (b ):
59+ return (a , b )
60+ return (b , a )
61+
62+ def fudge_to_find (target_primes :list [int ], input_set :list [int ]) -> Literal [False ]| str :
63+ """
64+ fudge (e.g. (100 x 2) -1) them
65+ return remaining numbers
66+ retrun
67+ """
68+ # if everything in target is in input set return target to string (no fuding required)
69+ if is_trivial (input_set , target_primes ):
70+ # print(type(target_primes))
71+ return "," .join (target_primes )
72+
73+ if len (target_primes ) >= len (input_set ):
74+ return too_many_primes (target_primes , input_set )
75+
76+ used = []
77+ # if a target number
78+ # have target number(s) and some input numbers - find combo of input numbers that makes the target nos
79+
80+ smaller_list , bigger_list = return_smaller_list (input_set , target_primes )
81+ new_smaller = [i for i in smaller_list if i not in bigger_list ]
82+ new_bigger = [i for i in smaller_list if i not in bigger_list ]
83+ i
84+ while :
85+ value = smaller_list [i ]
86+ if smaller_list [i ] in bigger_list :
87+ smaller_list .pop (i )
88+ bigger_list .pop (bigger_list .index (i ))
89+
90+
91+
92+ # just pick out the intersection
93+
94+ for inp_idx , input_no in enumerate (input_set ):
95+ if input_no in target_primes :
96+ target_primes .remove (input_no ) # check remove uses val not idx
97+ input_set .pop (inp_idx )
98+ used .append (input_no )
99+ if not target_primes :
100+ # got them all wooo
101+ return '*' .join (used )
102+
103+ # now have the dregs - what to do
104+ # try pairs to get some action
105+ for inp_idx1 , input_no1 in enumerate (input_set ):
106+ for inp_idx2 , input_no2 in enumerate (input_set ):
107+ if inp_idx1 == inp_idx2 :
108+ continue
109+ for op in [
110+ lambda x ,y : x + y ,
111+ lambda x ,y : abs (x - y ),
112+ lambda x ,y : x / y if x % y == 0 else None ,
113+ lambda x ,y : y / x if y % x == 0 else None ,
114+ lambda x ,y : x * y ,
115+ ]:
116+ value = op (input_no1 , input_no2 )
117+ if value is None :
118+ continue
119+
120+
121+
122+
123+ def generate_set_of_digits (number_of_large :int ) -> list [int ]:
124+ """
125+ generates a fixed amount of digits
126+ if number_of_large > 4: raise
127+ """
128+ if number_of_large > 4 :
129+ raise ValueError ("Number of large numbers must be 4 or fewer" )
130+
131+ large_nums = random .sample ([25 , 50 , 75 , 100 ], number_of_large )
132+
133+ number_of_small = 6 - number_of_large
134+ small_nums_list = 2 * list (range (1 , 11 ))
135+ small_nums = random .sample (small_nums_list , number_of_small )
136+
137+ return large_nums + small_nums
138+
139+
140+ def generate_target_number () -> int :
141+ """ generates a number between 100 - 999 """
142+ return int ((random .random () * 899 ) + 100 )
143+
144+
145+ if __name__ == "__main__" :
146+ print (
147+
148+ f"""
149+ { get_prime_factors (12 )= }
150+ { get_prime_factors (6 )= }
151+ { get_prime_factors (2 )= }
152+ { get_prime_factors (2 )= }
153+ """
154+ )
155+ # input_set = generate_set_of_digits(1)
156+ # target_number = generate_target_number()
157+ # print(input_set)
158+ # print(target_number)
159+ # prime_factors = get_prime_factors(target_number)
160+ # print(f"prime factors of {target_number}, were {prime_factors}")
161+ # found = fudge_to_find(prime_factors, input_set)
162+ # if found:
163+ # print(found)
164+ # print("sucess")
165+ # exit(0) # success
166+ # print("failed")
0 commit comments