Вектор v[] лишний, он же просто умножает свой индекс на 6, проще вместо выборки из вектора сразу и умножать.
Код:
good=1;
forprime(p=5,len, kraz=p-1;
for (ost=1,p-1,
for (i=2,len, if( (ost+pat[i])%p==0, kraz--; break ) );
); good=good*kraz; if(kraz==0, break);
);
if(good>0,
Вся эта конструкция по проверке допустимости паттерна заменяется на одну строку:
Код:
forprime(p=5,len, if(#setminus([1..p-1], Set(-pat%p))==0, next(2)); );
В итоге программа становится буквально из пяти строк (строка инициализации, строка цикла, строка заполнения паттерна, строка его проверки, ну и печать):
Код:
len=17; d=252;
pat=vector(len); pat[1]=0; pat[(len+1)/2]=d/2; pat[len]=d; kpat=0;
forsubset([d/12-1,(len-3)/2],s,
for(i=2,(len-1)/2, pat[i]=6*s[i-1]; ); for(i=(len+3)/2,len-1, pat[i]=d-pat[len+1-i]; );
forprime(p=5,len, if(#setminus([1..p-1],Set(-pat%p))==0, next(2)); );
print(kpat++,"\t",pat);
);
И вся хитрость таких программ - правильно организовать цикл перебора и правильно заполнить проверяемый паттерн.
В принципе здесь большой простор для ускорения перебора, но так как длины и диаметры паттернов небольшие, а нужно это редко (и в общем лишь один раз), то нет смысла заморачиваться.
-- 21.03.2025, 12:20 --Хотя я бы цикл сделал не forsubset, а forvec, причём у него есть параметр чтобы выдавались лишь вектора строго в порядке возрастания, достаточно будет перебрать лишь len\2-1 элементов и домножать их на 6 - это и будут внутренние числа паттерна:
Код:
len=21; d=360;
v=vector(len); v[1]=0; v[len\2+1]=d\2; v[len]=d; nv=0;
forvec(t=vector(len\2-1,i, [1,d\12-1]),
for(i=1,#t, v[i+1]=6*t[i]; v[len-i]=d-6*t[i]; );
forprime(p=5,len, if(#setminus([1..p-1], Set(-v%p))==0, next(2)); );
print(nv++,"\t",v);
,2);
Но быстрее не вышло, так же медленно.
-- 21.03.2025, 12:34 --Меня терзают смутные сомнения что аналогичную программу я уже где-то показывал ...