| 
				
				
								
			 | 
			
				
				
					
											Вы последовательность множеств остатков, как я понял, по некоторым паттернам (правилам перехода к новым комбинациям) строите. Думаю, что угадать паттерн легче, чем угадывание больших степеней в представлении (это то, что использовал я). Вам стоит попробовать жадный алгоритм рандома, если какой-то паттерн за некоторое не очень большое время не даёт результат, сбрасывать его и запускать с новым. Хотя, я не очень вникал, возможно, что правила перехода Вы руками задаёте, а рандом по начальным данным. Да-да, в эту сторону я ходил: с некоторой долей случайности выбираются паттерны при каждом переходе, и сброс, если поиск слишком затянулся. Подробнее: 0. Делаем сколько-то независимых попыток, пока не надоест; я обычно двухсот не дожидался. В каждой попытке: 1. Начинаем с упорядоченной по возрастанию последовательности остатков   , добавляем к ней еще два числа   , где   2. При каждом переходе для каждого    вычисляем четыре (или меньше) разности    и вставляем их обратно в упорядоченную последовательность; проверяя отсутствие полных дубликатов и "запрещенных" комбинаций с коэффициентом по модулю большим единицы при какой-нибудь степени пятерки; при этом, для каждого перехода в рамках попытки, четыре числа    выбираются псевдослучайно из диапазонов   3. Повторяем предыдущий шаг в цикле    раз; если решение еще не найдено, а размер последовательности не увеличился или превысил    членов - сброс попытки. Если найдено - успех, стоп. Константы подобраны эмпирически, исходя из физиологии моего нотика и ряда шаманских предположений о пространстве решений задачи. Код (все константы забиты в строках 42, 47, 57, 81): 
- f52isnice(a,b)={return(bitand(real(a),imag(b))==0 && bitand(real(b),imag(a))==0)}; 
 -  
 - f52diff(a,b)={my([L1,R1]=[real(a),imag(a)],[L2,R2]=[real(b),imag(b)],G); 
 - G=bitxor(bitand(L1,L2),bitand(R1,R2)); 
 - return(bitxor(G,bitor(L1,R2))+I*bitxor(G,bitor(L2,R1))) 
 - }; 
 -  
 - f52dec(s,n)={my( 
 - L=binary(real(s)), 
 - R=binary(imag(s)), 
 - L1=select(x->x,L,1), 
 - R1=select(x->x,R,1), 
 - L2=vector(#L1,i,#L-L1[i]), 
 - R2=vector(#R1,i,#R-R1[i]), 
 - r=(sum(i=1,#L2,5^L2[i])-sum(i=1,#R2,5^R2[i]))/(2^n-1); 
 - ); 
 - return([L2;R2;r]); 
 - }; 
 -  
 - f52nb(n)={ 
 - \\try to find a multiple of N=2^n-1 as a sum of b[i]*5^i, i=0,1,...,n-1, b[i]=-1,0,1 
 - t0=getabstime(); 
 - N=2^n-1; 
 - a=vector(n,i,lift(Mod(5^(i-1),N))); 
 - k=floor(vecsum(a)/N); print(k); if(k<2,k=2); 
 - a=vector(n+1,i,if(i<n+1,a[i],N)); \\dunno a nice way for concating two vectors 
 - a=vector(n+2,i,if(i<n+2,a[i],k*N)); 
 -  
 - s=vector(n,i,2^(i-1)); 
 - s=vector(n+2,i,if(i<n+1,s[i],0)); 
 -  
 - \\pack b[i] into bits of a complex number: 5+2i => [101, 10] => 5^2+5^0-5^1 
 - aind=vecsort(a,,1); 
 - a0=vecextract(a,aind); 
 - s0=vecextract(s,aind); 
 - \\print(a); 
 - \\print(s); 
 -  
 - \\DD=7; \\max search depth 
 - \\DD=#combo; 
 -  
 - for(gcnt=1,10000, 
 - print([gcnt,getabstime()-t0,#a]); 
 - a=a0; 
 - s=s0; 
 -  
 - for(ecnt=1,max(30,k+45),\\basically while(1) 
 - wa=#a; 
 - anew=a; 
 - snew=s; 
 - wanew=wa; 
 - waold=wa; 
 -  
 - \\DDgen=random([1,127]); 
 - \\DDgen=binary(DDgen); 
 - \\combo=select(x->x,DDgen,1); 
 - combo=vecsort([random([1,3]),random([1,6]),random([1,9]),random([1,12])],,8); 
 - DD=#combo; 
 -  
 - \\main job 
 - for(dcnt=1,DD, 
 - dep=combo[dcnt]; 
 - da=vector(wa-dep,i,if(f52isnice(s[i+dep],s[i]),a[i+dep]-a[i],-1)); 
 - ds=vector(wa-dep,i,if(f52isnice(s[i+dep],s[i]),f52diff(s[i+dep],s[i]),-1)); 
 - wda=#da; 
 -  
 - anew=vector(wanew+wda,i,if(i<=wanew,anew[i],da[i-wanew])); 
 - snew=vector(wanew+wda,i,if(i<=wanew,snew[i],ds[i-wanew])); 
 - wanew=#anew; 
 - ); \\end for dep 
 -  
 - g=matconcat([anew,snew]~); 
 - aind=vecsort(g,,9); \\remove full duplicates 
 - a=vecextract(anew,aind); 
 - s=vecextract(snew,aind); 
 - if(a[1]==-1,wa=#a;a=a[2..wa];s=s[2..wa]); \\remove one last bad combo s 
 - \\print(["===>",ecnt,#a,combo]); 
 -  
 - if(a[1]==0,print(getabstime()-t0," ms");return(f52dec(s[1],n))); \\success 
 -  
 - if(#a>1900000 || #a==waold, break()); 
 -  
 - ); \\end for ecnt 
 - ); \\end for gcnt 
 - print(getabstime()-t0," ms"); 
 - return([]); \\failure 
 - }; 
  
  Код по-прежнему не экономен к памяти (для размера последовательности    при переходе я пложу несколько объектов размера   , чтобы иметь возможность пользоваться быстрыми операциями с векторами).  
					 					 | 
				 
				 
			 |