Ой здорово, сколько статистики!
Она вся есть в ww[] в моей программе, я просто её вывожу на экран, но не сохраняю. Чтобы получить вот эти строки просто к показу vc[] добавляете показ чисел #ww[k=1..31] (именно длин массивов с данным k) и всё.
Ну вот какие 6 вариантов загрязнить 19-ку 30 числами ?
Ну вот меняете в моей программе v[] на 19-252, предел цикла forprime(p=3,nextprime(v[#v]/2), на forprime(p=3,23, и после отработки (за тысячные доли секунды) выводите содержимое ww[31]:
Код:
print(ww[31]);
foreach(ww[31],m, print(vecextract(a,m[1][1])); );
Map([21235740289049400480450941027461, 1; 21235741497975220094530359919749, 1; 26306342087823698032410568955013, 1; 204250691690199630442929422664456, 1; 204250691690494778348108641272584, 1; 204290151029246999840041455387432, 1])
[2, 8, 20, 26, 32, 48, 56, 60, 68, 78, 86, 92, 98, 102, 110, 116, 138, 146, 158, 168, 170, 176, 182, 198, 200, 212, 228, 230, 236, 242]
[10, 22, 24, 40, 52, 54, 64, 66, 70, 76, 82, 94, 100, 106, 114, 136, 142, 150, 154, 166, 174, 184, 192, 196, 202, 204, 226, 232, 244, 250]
[10, 16, 22, 24, 40, 52, 54, 70, 76, 82, 84, 94, 106, 114, 136, 142, 150, 154, 160, 166, 174, 184, 192, 196, 204, 220, 226, 232, 244, 250]
[10, 22, 24, 40, 52, 54, 66, 70, 76, 82, 94, 100, 106, 114, 136, 142, 150, 154, 160, 166, 174, 184, 192, 196, 202, 204, 226, 232, 244, 250]
[2, 8, 20, 26, 48, 50, 56, 60, 68, 78, 86, 92, 98, 102, 110, 116, 138, 146, 152, 158, 170, 176, 182, 186, 198, 200, 212, 228, 230, 242]
[2, 8, 20, 26, 48, 50, 56, 60, 68, 78, 86, 98, 102, 110, 116, 138, 146, 152, 158, 170, 176, 182, 186, 188, 198, 200, 212, 228, 230, 242]
Здесь единицы это значит что каждая комбинация загрязнения встретилась один раз, а сами комбинации это длинное число, двоичный код которого является маской элементов a[] (если 1 то элемент остаётся в a[]). Если честно уже не помню надо ли показывать результат в обратном порядке Vecrev(vecextract()) или нет, т.е. откуда начинается нумерация, для количества единиц в числе (считается ведь только оно) это без разницы. А может вообще все эти списки загрязнений симметричны (между собой) и смена порядка ничего не изменит ...
Пример бы...
ОК, давайте разберём как обработается остаток 24 по модулю 29 для всех вот этих 6-ти вариантов грязных цепочек.
В строке с am=... остатку m[11]=24 соответствует число/маска am[11]=324517315718368994658257656078335, в котором нулевых битов всего 4шт: 13, 39, 64, 90, что соответствует числам 34, 92, 150, 208 в a[], именно эти числа могут вырезаться (если они там ещё оставались) из массива a[] при обработке остатка 24. Выше привёл содержимое ww[31] до обработки 29, а вот что будет в ww[31] если в foreach(am,x, для p=29 обработать только один остаток m[11]=24 с единственной маской x=324517315718368994658257656078335:
Код:
[2, 8, 20, 26, 48, 50, 56, 60, 68, 78, 86, 98, 102, 110, 116, 138, 146, 152, 158, 170, 176, 182, 186, 188, 198, 200, 212, 228, 230, 242]
От 6 грязных вариантов остался только один. Проверяем.
Из первого исключилось число 92 и у него k уменьшилось с 31 до 30.
Из второго исключилось число 150 и у него k уменьшилось с 31 до 30.
Из третьего исключилось число 150 и у него k уменьшилось с 31 до 30.
Из четвёртого исключилось число 150 и у него k уменьшилось с 31 до 30.
Из пятого исключилось число 92 и у него k уменьшилось с 31 до 30.
Из шестого ни одно из 4-х чисел не исключилось и потому k не изменилось.
Таким образом при обработке одного остатка по модулю 29 из 6-ти вариантов загрязнения один остался с тем же k, а остальные 5 вариантов k уменьшили на 1.
Как получается число 324517315718368994658257656078335 для m[11]=24 видно в строке am=... - биты маски сбрасываются в 0 для тех позиций, в которые попадает число кратное 29 с учётом того что первое кратное ему будет смещено на 24 (или на 29-24, не помню). Ну это по идее. Реально там ещё и Vecrev потому что vecextract считает нулевой бит за маску первого элемента массива, а fromdigits наоборот.
После отработки всех 12 остатков по модулю 29 все 6 вариантов ww[31] сохраняются, но 2, 3, 4, 6 встречаются уже по два раза:
Код:
Map([21235740289049400480450941027461, 1; 21235741497975220094530359919749, 2; 26306342087823698032410568955013, 2; 204250691690199630442929422664456, 2; 204250691690494778348108641272584, 1; 204290151029246999840041455387432, 2])
И в #ww[31] по прежнему останется 6, а 10 (сумма всех повторов) пойдёт в vc[31] для 29#.
-- 20.04.2024, 20:16 --Структура ww[k]=Map() в PARI имеет хитрое внутреннее устройство и это не совсем массив, потому для него нельзя обратиться по индексу (например ко второму элементу ww[31][2]). Но можно запрашивать количество элементов #ww[k] и можно перебрать их все foreach(ww[k],m, (а вот цикл for(j=1,#ww[k], m=ww[k][j]; уже не сработает так как тут обращение по индексу j).
Выше показал содержимое ww[31] после 23#, а вот как оно в действительности:
Код:
foreach(ww[31],m, print(m));
[[26306342087823698032410568955013, 1], Vecsmall([5, 4, 3])]
[[204250691690199630442929422664456, 1], Vecsmall([0, 0, 1])]
[[204290151029246999840041455387432, 1], Vecsmall([0, 0, 1])]
[[204250691690494778348108641272584, 1], Vecsmall([2, 3, 2])]
[[21235740289049400480450941027461, 1], Vecsmall([0, 6, 2])]
[[21235741497975220094530359919749, 1], Vecsmall([0, 0, 1])]
Т.е. каждый элемент не просто массив из двух элементов что мы туда положили, а ещё и служебный массив указателей (два элемента которого нужны для построения двоичного дерева, а про третий не понял). И потому в программе приходится указывать лишний индекс в b=m[1][1]; qq=m[1][2]; чтобы обратиться лишь к нашим данным, а не к служебным.
Так же не работает vecsort на Map (да и многие остальные векторные функции), т.е. не получится пройтись по таблице в другом порядке кроме как выдаст foreach. В частности из-за этого пришлось единую таблицу ww делить на подтаблицы ww[k] по величине k равной количеству единиц (оставшихся чисел) в вариантах загрязнения (потому что перебор по k должен идти строго по возрастанию).
В общем далеко не любые операции с массивами применимы и к Map, это скорее исключения.
-- 20.04.2024, 20:27 --в котором нулевых битов всего 4шт: 13, 39, 64, 90, что соответствует числам 34, 92, 150, 208 в a[], именно эти числа могут вырезаться (если они там ещё оставались) из массива a[] при обработке остатка 24
Фактически это четырёхзубая вилка. Понятно что для меньших простых зубьев будет больше, для больших меньше.
Да, ещё, кажется выше невнятно сказал: в ww[k] для каждого k=len хранятся маски чисел из a[], которые пока ещё остались не вычеркнутыми/удалёнными. Списки чисел (вектора) хранить очень накладно и медленно, потому вместо них храню лишь маски какие элементы вектора ещё остались. И вычёркивание элемента из вектора делается командой bitand с правильной маской (где вычёркиваемым элементам соответствуют нулевой бит, а всем остальным 1). Ну а #a[] заменяется на hammingweight(x) (подсчитывающей количество единичек в числе x, т.е. оставшихся элементов в a[]).