Последний раз редактировалось waxtep 19.08.2025, 00:55, всего редактировалось 2 раз(а).
Мне это не удалось, но было бы интересно увидеть такое вычислительное решение, если кто-то сумеет его построить. Вернулся к этой задаче: найти какое-либо разложение натурального  в сумму натуральных степеней пятерок с коэффициентами  . Добраться мне пока удалось до заметно более скромного  : Код: (21:33) gp > q1=5^92+5^89+5^84+5^79+5^59+5^57+5^56+5^49+5^44+5^43+5^42+5^38+5^19+5^17+5^14+5^13+5^12+5^9+5^6+5^3+1 %66 = 20356449602379062251578988040918723300273995846509953315675797001 (21:33) gp > q2=5^81+5^71+5^69+5^67+5^65+5^62+5^61+5^58+5^55+5^46+5^21+5^20+5^5+5^2+5 %63 = 413590350392726291695044835705630248412490463256835940655 (21:34) gp > q=q1-q2 %67 = 20356449188788711858852696345873887594643747434019490058839856346 (21:34) gp > q/(2^93-1) %68 = 2055476087571634518751370354306509606 При помощи такого рецепта: 1. берем упорядоченную по убыванию последовательность остатков  , добавляем к ней и само  ; 2. вычисляем разности соседей  и может быть какие-нибудь еще комбинации из  , и вставляем их обратно в упорядоченную последовательность; проверяя отсутствие полных дубликатов и "запрещенных" комбинаций с коэффициентом по модулю большим единицы при какой-нибудь степени пятерки; 3. повторяем предыдущий шаг в цикле; по наблюдениям, дюжины итераций хватает, чтобы алгоритм завершился успехом или поражением. Конкретно для  на шаге 2 беру разности  ; это считается минут 45 на древнем офисном нотике; наибольшее количество членов  - 48776 - получается на пятой итерации, а всего итераций десять штук. Для  можно не брать последнюю из комбинаций; а для  в районе  достаточно первых одной-двух комбинаций. В общем, есть ощущение, что необходимое количество комбинаций увеличивается с ростом  . На этом месте хочется остановиться, и обсудить пару вопросов, если кого-либо из участников заинтересует тема: 1. Почему это работает? Всего комбинаций для  порядка  , а перебрать достаточно сотню тысяч. Это просто везение, или есть какие-то правдоподобные соображения или даже теория? Да, мы на каждой итерации добавляем точки и сжимаем интервал, но разница в  десятичных порядков так сказать вопиет 2. Если соображения есть, можно ли как-то более интеллектуально подобрать вид комбинаций, чтобы обойтись их меньшим числом? От их количества время расчета зависит ощутимо. 3. Сколько времени этот код исполняется на нормальных машинах, и где бы его пооптимизировать. Это же просто задача вставки в отсортированный массив, ну в моем топорном исполнении. Код:
- f52n(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
- N=2^n-1;
- a=vector(n,i,lift(Mod(5^(n-i),N)));
- a=matconcat([N,a]);
- s=vector(n,i,[n-i+1]);
- s=matconcat([n+1,s]);
- \\each a[k]=g[2,k] is some sum of b[i]*5^i mod N, a building block for desirable multiple; ordered desc
- \\corresponding g[1,k] is a set of integers s[j] storing a formula for g[1,n]: g[1,n]=sum(sign(s[j])*5^(abs(s[j]-sign(s[j])))), where abs(s[j])<n+1
- \\s[j]=n+1 is reserved for g[1,k]=N and should be ignored in the output
- \\example: n=9, s=[-10, -2, 7, 9] => a=5^8+5^6-5^1
- g=matconcat([s,a]~);
- g[1,1]=Set(g[1,1]);
- g=vecsort(g,2,4);
-
- \\basically, while(1); commonly runs for no more than a dozen iterations
- for(ecnt=1,1000,
- w=#g-1;
- c=[];
- mnmax=0;
- for(cnt=1,w,
- c1=g[1,cnt];
-
- \\main job is done here; calculate "good" a[k]-a[k+1] and insert them back into ordered vector g[2,...]
- \\or return first suitable g[1,k] that yields a multiple of N
- \\need to check here that we are not trying to insert some 2*5^i here
- c2=g[1,cnt+1];
- if(setintersect(c1,vecsort(-c2))==[],cn=vecsort(setunion(setminus(c1,c2),-setminus(c2,c1)));
- mn=g[2,cnt]-g[2,cnt+1];
- \\also avoid inserting duplicate g[1,k]
- ndup=vecsearch(-g[2,1..w],-mn);
- if(ndup>0,if(g[1,ndup]!=cn && setintersect(vecsort(-cn),g[1,ndup])==[],return(matconcat([-cn,g[1,ndup]]))));
- if(ndup==0,
- if(c==[] && mn==0, return(cn));
- if(c==[],mnmax=mn;c=[cn;mn]);
- cdup==0;
- if(c!=[],cdup=vecsearch(-c[2,1..#c],-mn);if(cdup>0 && cn!=c[1,cdup] && setintersect(vecsort(-cn),c[1,cdup])==[],print("new");return(vecsort(setunion(setminus(cn,c[1,cdup]),-setminus(c[1,cdup],cn))))));
- if(cdup==0,
- if(mn>mnmax,mnmax=mn);
- if(c==[],c=[cn;mn],c=vecsort(matconcat([[cn;mn],c]),2,4)))));
-
- \\same as above for a[k]-a[k+2]
- if(cnt<w,
- c2=g[1,cnt+2];
- if(setintersect(c1,vecsort(-c2))==[],cn=vecsort(setunion(setminus(c1,c2),-setminus(c2,c1)));
- mn=g[2,cnt]-g[2,cnt+2];
- ndup=vecsearch(-g[2,1..w],-mn);
- if(ndup>0,if(g[1,ndup]!=cn && setintersect(vecsort(-cn),g[1,ndup])==[],return(matconcat([-cn,g[1,ndup]]))));
- if(ndup==0,
- if(c==[] && mn==0, return(cn));
- if(c==[],mnmax=mn;c=[cn;mn]);
- cdup==0;
- if(c!=[],cdup=vecsearch(-c[2,1..#c],-mn);if(cdup>0 && cn!=c[1,cdup] && setintersect(vecsort(-cn),c[1,cdup])==[],print("new1");return(vecsort(setunion(setminus(cn,c[1,cdup]),-setminus(c[1,cdup],cn))))));
- if(cdup==0,
- if(mn>mnmax,mnmax=mn);
- if(c==[],c=[cn;mn],c=vecsort(matconcat([[cn;mn],c]),2,4)))));
- );
-
- \\same as above for a[k]-a[k+3]
- if(cnt<w-1,
- c2=g[1,cnt+3];
- if(setintersect(c1,vecsort(-c2))==[],cn=vecsort(setunion(setminus(c1,c2),-setminus(c2,c1)));
- mn=g[2,cnt]-g[2,cnt+3];
- ndup=vecsearch(-g[2,1..w],-mn);
- if(ndup>0,if(g[1,ndup]!=cn && setintersect(vecsort(-cn),g[1,ndup])==[],return(matconcat([-cn,g[1,ndup]]))));
- if(ndup==0,
- if(c==[] && mn==0, return(cn));
- if(c==[],mnmax=mn;c=[cn;mn]);
- cdup==0;
- if(c!=[],cdup=vecsearch(-c[2,1..#c],-mn);if(cdup>0 && cn!=c[1,cdup] && setintersect(vecsort(-cn),c[1,cdup])==[],print("new2");return(vecsort(setunion(setminus(cn,c[1,cdup]),-setminus(c[1,cdup],cn))))));
- if(cdup==0,
- if(mn>mnmax,mnmax=mn);
- if(c==[],c=[cn;mn],c=vecsort(matconcat([[cn;mn],c]),2,4)))));
- );
-
- \\same as above for a[k]-a[k+4]
- if(cnt<w-2,
- c2=g[1,cnt+4];
- if(setintersect(c1,vecsort(-c2))==[],cn=vecsort(setunion(setminus(c1,c2),-setminus(c2,c1)));
- mn=g[2,cnt]-g[2,cnt+4];
- ndup=vecsearch(-g[2,1..w],-mn);
- if(ndup>0,if(g[1,ndup]!=cn && setintersect(vecsort(-cn),g[1,ndup])==[],return(matconcat([-cn,g[1,ndup]]))));
- if(ndup==0,
- if(c==[] && mn==0, return(cn));
- if(c==[],mnmax=mn;c=[cn;mn]);
- cdup==0;
- if(c!=[],cdup=vecsearch(-c[2,1..#c],-mn);if(cdup>0 && cn!=c[1,cdup] && setintersect(vecsort(-cn),c[1,cdup])==[],print("new3");return(vecsort(setunion(setminus(cn,c[1,cdup]),-setminus(c[1,cdup],cn))))));
- if(cdup==0,
- if(mn>mnmax,mnmax=mn);
- if(c==[],c=[cn;mn],c=vecsort(matconcat([[cn;mn],c]),2,4)))));
- );
-
- \\same as above for a[k]-a[k+5]
- if(cnt<w-3,
- c2=g[1,cnt+5];
- if(setintersect(c1,vecsort(-c2))==[],cn=vecsort(setunion(setminus(c1,c2),-setminus(c2,c1)));
- mn=g[2,cnt]-g[2,cnt+5];
- ndup=vecsearch(-g[2,1..w],-mn);
- if(ndup>0,if(g[1,ndup]!=cn && setintersect(vecsort(-cn),g[1,ndup])==[],return(matconcat([-cn,g[1,ndup]]))));
- if(ndup==0,
- if(c==[] && mn==0, return(cn));
- if(c==[],mnmax=mn;c=[cn;mn]);
- cdup==0;
- if(c!=[],cdup=vecsearch(-c[2,1..#c],-mn);if(cdup>0 && cn!=c[1,cdup] && setintersect(vecsort(-cn),c[1,cdup])==[],print("new4");return(vecsort(setunion(setminus(cn,c[1,cdup]),-setminus(c[1,cdup],cn))))));
- if(cdup==0,
- if(mn>mnmax,mnmax=mn);
- if(c==[],c=[cn;mn],c=vecsort(matconcat([[cn;mn],c]),2,4)))));
- );
-
-
- );
- \\failure: no more candidates for insert
- if(c==[],print(ecnt);return([]),g=matconcat([c,g]));
-
- \\remove too large a[k] - no new candidates here
- g=vecsort(g,2,4);
- w=#g;
- wcut=vecsearch(-g[2,1..w],-mnmax);
- g=g[1..2,wcut..w];
- print(#g);
- );
-
- };
Пример запуска и выдача (размер последовательности на каждой итерации и найденное разложение): Код: (20:33) gp > f52n(93) 502 1942 7589 25489 *** vecsort: Warning: increasing stack size to 128000000. 48776 47486 24041 5144 2066 1155 %61 = [93 90 85 80 60 58 57 50 45 44 43 39 20 18 15 14 13 10 7 -6 -21 -22 -47 -56 -59 -62 -63 -66 -68 -70 -72 -82 -94 -3 -2 1 4]
|