@@ -18,18 +18,37 @@ class LearnParity(PuzzleGenerator):
1818 The vectors are encoded as binary integers for succinctness.
1919 """
2020
21+ # vecs below generated by vecs = LearnParity.rand_parity_problem(random.Random(28562407), d=63)
22+
2123 @staticmethod
22- def sat (inds : List [int ], vecs = [169 , 203 , 409 , 50 , 37 , 479 , 370 , 133 , 53 , 159 , 161 , 367 , 474 , 107 , 82 , 447 , 385 ]):
24+ def sat (inds : List [int ], vecs = [8543342634111025532 , 8335192666369313368 , 2359039407982105779 , 4172548441791366513 ,
25+ 1256349095522986569 , 3754463859322679595 , 1562879970152915618 , 1933016518061876369 ,
26+ 5920060919607788629 , 8545759471656960221 , 2934241949774725291 , 559495833580308526 ,
27+ 5239436672544732707 , 5865707252111994906 , 8310678944230832071 , 4595527784831581592 ,
28+ 4348871153851862010 , 5198370132175169882 , 3748480974791545460 , 1215135748294622536 ,
29+ 4321487173746421746 , 9012812639700145153 , 588387599697000986 , 5003829835901037543 ,
30+ 7754881381173342129 , 2635789994388296837 , 3222773777603033590 , 5790284924977099989 ,
31+ 7540575369379211274 , 7898971930608516039 , 27260728996582582 , 1792453914477410383 ,
32+ 8726418386455953809 , 9193001185022172125 , 3515388340741601364 , 6217726337930929836 ,
33+ 1038687698871580494 , 1892601486162604802 , 3633356355444530940 , 108334555669330693 ,
34+ 1955821183884414243 , 5681081121990060330 , 5791800194327455183 , 8459367068223249929 ,
35+ 4271428016720060690 , 913733008909519396 , 2233236350093301187 , 6538503022239131288 ,
36+ 5292485269677307644 , 4615671355181378169 , 2605305508625596241 , 4954529961471509975 ,
37+ 2312963580097644831 , 888555840551788245 , 4152336321587083789 , 8978251650218883651 ,
38+ 2567641184250287470 , 2168893575221172018 , 4358821646257958779 , 3102433300308778243 ,
39+ 4185793889128296420 , 6687096428156463254 , 4143873353280484310 , 8454616559174688585 ,
40+ 6589014033410725016 , 5903549622062684554 , 2388718494916838667 , 8850145667696469408 ,
41+ 5068285804151890745 , 2981241929741282230 , 79408177335937724 , 1711542430102927280 ]):
2342 """
24- Parity learning: Given binary vectors in a subspace, find the secret set $S$ of indices such that:
25- $$ sum_{i \in S} x_i = 1 (mod 2)$ $
43+ Parity learning: Given binary vectors in a subspace, find the secret set S of indices such that:
44+ $\\ sum_{i \in S} x_i = 1 (mod 2)$
2645 """
2746 return all (sum ((v >> i ) & 1 for i in inds ) % 2 == 1 for v in vecs )
2847
2948 @staticmethod
3049 def sol (vecs ):
3150 # Gaussian elimination
32- d = 0 # decode vectors into arrays
51+ d = 0 # decode vectors into arrays
3352 m = max (vecs )
3453 while m :
3554 m >>= 1
@@ -55,16 +74,23 @@ def sol(vecs):
5574
5675 return [i for i in range (d ) if pool [i ][- 1 ]]
5776
58- def gen_random ( self ):
59- d = self . random . randrange ( 2 , self . random . choice ([ 5 , 10 , 20 , 100 ]))
77+ @ staticmethod
78+ def rand_parity_problem ( rand , d = 63 ):
6079 secret = None
6180 while not secret :
62- secret = [i for i in range (d ) if self . random .randrange (2 )]
63- num_vecs = self . random . randrange ( d , 5 * d )
64- vecs = [[self . random .randrange (2 ) for _ in range (d )] for i in range (num_vecs )]
81+ secret = [i for i in range (d ) if rand .randrange (2 )]
82+ num_vecs = d + 9
83+ vecs = [[rand .randrange (2 ) for _ in range (d )] for i in range (num_vecs )]
6584 for v in vecs :
6685 v [secret [0 ]] = (1 + sum ([v [i ] for i in secret [1 :]])) % 2
67- vecs = [sum (1 << i for i , b in enumerate (v ) if b ) for v in vecs ] # encode into ints
86+ vecs = [sum (1 << i for i , b in enumerate (v ) if b ) for v in vecs ] # encode into ints
87+ return vecs
88+
89+ def gen_random (self ):
90+ vecs = self .rand_parity_problem (
91+ self .random ,
92+ d = self .random .randrange (2 , self .random .choice ([5 , 10 , 20 , 100 ]))
93+ )
6894 self .add (dict (vecs = vecs ))
6995
7096
@@ -75,10 +101,44 @@ class LearnParityWithNoise(PuzzleGenerator):
75101 [Parity learning problem](https://en.wikipedia.org/w/index.php?title=Parity_learning)
76102 runs in time $2^(d/(log d))$"""
77103
104+ # vecs below generated by LearnParityWithNoise.rand_parity_problem(random.Random(852352407), d=63)
105+
78106 multiplier = 40 # hard puzzle, takes longer to test
79107
80108 @staticmethod
81- def sat (inds : List [int ], vecs = [26 , 5 , 32 , 3 , 15 , 18 , 31 , 13 , 24 , 25 , 34 , 5 , 15 , 24 , 16 , 13 , 0 , 27 , 37 ]):
109+ def sat (inds : List [int ], vecs = [2874444459419665109 , 3571416480966091062 , 3627516422625241827 , 2417762213996395207 ,
110+ 4371357242721531635 , 1396026910505373292 , 6671557086560014752 , 9066082518122683098 ,
111+ 5240053591369828114 , 8556210480838058892 , 7302977584273736381 , 8938278934736014411 ,
112+ 4398671200512032996 , 6147375266514044469 , 6609538006889421793 , 2297823643430705118 ,
113+ 7583979108118079257 , 2498392101379258437 , 7893501751515236283 , 2027235323873165116 ,
114+ 925357965000140266 , 9009345166609418406 , 5689450111800001849 , 2079746314404416253 ,
115+ 4228649029862868917 , 5819371323838727219 , 102386757609774316 , 5480808186035115654 ,
116+ 3001738569073502536 , 9059061077086189682 , 681271298018419415 , 5616731111115463763 ,
117+ 2722737236861682531 , 4918075690687573998 , 7125583379861998376 , 7968096465923567867 ,
118+ 898679944061110348 , 1140358409311167922 , 6077294650144352445 , 587776882127248609 ,
119+ 2018954969823094844 , 1618480274277140739 , 8884189689498565225 , 4084721521520724931 ,
120+ 4718438135662169666 , 8411612063174086200 , 8726374275365985960 , 3135872851883336005 ,
121+ 1091802941995014823 , 4944178741300545327 , 6970959994566965947 , 2911632933598497473 ,
122+ 8638215954009823387 , 7438975146059987571 , 3486356869336916018 , 4935404783245269300 ,
123+ 3492912640500734004 , 7903591215281799872 , 4616161610863395412 , 875020887047334808 ,
124+ 2721628497281503934 , 6882639287577667047 , 6274957618887284536 , 3575443754501116278 ,
125+ 2031604067526359716 , 4433373641914130623 , 6204772769819600658 , 8509292558066435714 ,
126+ 1857073904365563798 , 7875287918949902618 , 5205034693823928900 , 4943396962875355147 ,
127+ 2805601192218759148 , 8976171820624983460 , 5930936964665834653 , 949687393644726240 ,
128+ 6466615045398392331 , 423404729770342491 , 2720698610804800422 , 7479269416044676778 ,
129+ 7869290888646534505 , 6327163107872545492 , 476579447640475544 , 1218066186129904051 ,
130+ 7630726053076756205 , 7741086216563432736 , 5225376670650457287 , 7040078265943665053 ,
131+ 2162853338175426448 , 5633819254572300801 , 92334600849454176 , 9098183941628882647 ,
132+ 3481731752092062852 , 5473741255745389738 , 7266470290696653678 , 3090338455353169956 ,
133+ 4358343354422765853 , 3623553173494979282 , 8328390749513844747 , 2287762878756609646 ,
134+ 4126189061710502597 , 5829472669961813184 , 7342395882491704275 , 5030578088617810038 ,
135+ 2210525427289006508 , 6161187897225224000 , 5601573223749212224 , 6539026784581543793 ,
136+ 3571032801838391198 , 4813662449014287760 , 6577243754700968179 , 4401899289452367605 ,
137+ 305529480505303551 , 1548494450097231731 , 6926707725781258948 , 6357305518384676781 ,
138+ 6357665620505806556 , 1554358231697328409 , 7871587375269472810 , 2094942344314098945 ,
139+ 1452972368095860063 , 3210274450167364491 , 6901356410911155351 , 7609098874470545378 ,
140+ 6955802737127492446 , 6919896432783547538 , 5423154486785623318 , 3105394980859157674 ,
141+ 8438962979748731599 , 4110730383299136510 , 6718356757580670867 ]):
82142 """
83143 Learning parity with noise: Given binary vectors, find the secret set $S$ of indices such that, for at least
84144 3/4 of the vectors, $$sum_{i \in S} x_i = 1 (mod 2)$$
@@ -88,7 +148,7 @@ def sat(inds: List[int], vecs=[26, 5, 32, 3, 15, 18, 31, 13, 24, 25, 34, 5, 15,
88148 @staticmethod
89149 def sol (vecs ):
90150 # brute force
91- d = 0 # decode vectors into arrays
151+ d = 0 # decode vectors into arrays
92152 m = max (vecs )
93153 while m :
94154 m >>= 1
@@ -98,26 +158,38 @@ def sol(vecs):
98158 import random
99159 rand = random .Random (0 )
100160 target = (len (vecs ) * 3 ) // 4
101- while True :
161+ max_attempts = 10 ** 4
162+ for _ in range (max_attempts ):
102163 ans = [i for i in range (d ) if rand .randrange (2 )]
103164 if sum (sum (v [i ] for i in ans ) % 2 for v in vecs ) >= len (vecs ) * 3 / 4 :
104165 return ans
105166
106- def gen_random ( self ):
107- d = self . random . randrange ( 2 , self . random . choice ([ 11 , 100 ])) # number of dimensions
167+ @ staticmethod
168+ def rand_parity_problem ( rand , d = 63 ):
108169 secret = None
109170 while not secret :
110- secret = [i for i in range (d ) if self .random .randrange (2 )]
111- num_vecs = self .random .randrange (2 * d , 10 * d )
112- vecs = [[self .random .randrange (2 ) for _ in range (d )] for i in range (num_vecs )]
171+ secret = [i for i in range (d ) if rand .randrange (2 )]
172+ print (len (secret ))
173+ num_vecs = 2 * d + 5
174+ vecs = [[rand .randrange (2 ) for _ in range (d )] for i in range (num_vecs )]
113175 for v in vecs :
114176 v [secret [0 ]] = (1 + sum ([v [i ] for i in secret [1 :]])) % 2
115- mistakes = self . random . sample (vecs , int (len (vecs ) * self . random .random () * 1 / 4 ))
177+ mistakes = rand . sample (vecs , int (len (vecs ) * rand .random () * 1 / 4 ))
116178 for v in mistakes :
117179 v [secret [0 ]] ^= 1 # flip bit in mistakes
118- vecs = [sum (1 << i for i , b in enumerate (v ) if b ) for v in vecs ] # encode into ints
119- self .add (dict (vecs = vecs ), test = d < 19 )
180+ vecs = [sum (1 << i for i , b in enumerate (v ) if b ) for v in vecs ] # encode into ints
181+ return vecs
182+
183+ def testable (self , inp : dict ):
184+ return max (inp ["vecs" ]) < 2 ** 20
120185
186+ def gen_random (self ):
187+ d = self .random .randrange (2 , self .random .choice ([11 , 100 ])) # number of dimensions
188+ vecs = self .rand_parity_problem (
189+ self .random ,
190+ d = d
191+ )
192+ self .add (dict (vecs = vecs ), test = d < 19 )
121193
122194
123195if __name__ == "__main__" :
0 commit comments