Практическое применение операции копирования массива

13.08.21

Разработка - Математика и алгоритмы

Решение задачи https://projecteuler.net/problem=250 из Project Euler средствами 1C.

При обсуждении методов копирования массива возник вопрос о примере практического применения такого механизма. Я использовал данную возможность при решении некоторых задач Project Euler. Так как  участники обсуждения проявили интерес к данной теме, то я счел возможным привести свой алгоритм. Условие задачи следующее. Дан ряд чисел и нужно найти количество подмножеств исходного множества, для которых выполняется условие, что сумма чисел из подмножества делится на заданное число. Во всех задачах на делимость нужно оперировать не с числом, а с остатком от деления. Потому первый шаг решения состоит в поиске остатков от деления исходных чисел на заданное. Все остатки от деления на число n лежат в диапазоне [0,...,n-1]. Поэтому создадим массив размерностью n, индекс массива - остаток от деления, значение - количество  чисел из первоначального множества, которые дают при делении такой остаток. Исходные числа имеют вид x^y поэтому нам понадобится функция для быстрого возведения в степень по модулю.

Функция БыстраяСтепень(знач x,знач y, знач mode=1) экспорт
	остаток=y;произведение=1;
	пока (остаток<>0) цикл
		цифра=остаток%2;
		если  цифра=1 тогда
			если mode=1 тогда
			 произведение=произведение*x
		    иначе 
			 произведение=(произведение*x)%mode
			конецесли; 
		конецесли;;	
		если mode=1 тогда
		 x=x*x;
	    иначе
		 x=(x*x)%mode;  
		конецесли;; 
		остаток=(остаток-цифра)/2
	enddo;	
	
	возврат произведение;
КонецФункции

Теперь мы можем заполнить массив с информацией о количестве остатков исходного множества.

массив=новый  массив(n);
для i=1 по верх цикл
		j=БыстраяСтепень(i%n,i,n);
		если массив[j]=неопределено тогда
			массив[j]=1;
		иначе	
			массив[j]=массив[j]+1;
		конецесли;	
конеццикла;	

И наконец сама функция для поиска решения.  У нас есть массив счетчик, в котором мы собираем количество подмножеств исходного множества, для которых сумма равна индексу массива. При переходе к следующему числу из исходного множества мы сохраняем счетчик в буфер и на этом шаге используем копирование массива.

Функция ПроектЭйлер250(верх,n) экспорт
	
		
	массив=новый  массив(n+1);
	для i=1 по верх цикл
		j=БыстраяСтепень(i%n,i,n);
		если массив[j]=неопределено тогда
			массив[j]=1;
		иначе	
			массив[j]=массив[j]+1;
		конецесли;;	
	конеццикла;	
	
	mode=БыстраяСтепень(10,16);
	
	
	счетчик=новый  массив(n);
	для  i=0 по n-1 цикл
		счетчик[i]=0;
    конеццикла;
	
	
	для остаток=0 to n-1 do
		если массив[остаток]<>неопределено then
			для k=1 по массив[остаток] цикл
				//здесь мы копируем массив счетчик в массив буфер
			    буфер=новый массив(новый  ФиксированныйМассив(счетчик));	
				для j=0 по n-1 цикл
					если счетчик[j]<>0 тогда
						остаток_суммы=(остаток+j)%n;	
						буфер[остаток_суммы]=(буфер[остаток_суммы]+счетчик[j])%mode;
					конецесли;   
				конеццикла;
				буфер[остаток]=(буфер[остаток]+1)%mode;
				счетчик=буфер ;
			конеццикла;	
		конецесли;
	конеццикла;		
	
	возврат  счетчик[0];
КонецФункции	

Приведенный алгоритм подходит для решения задачи 249. В ней требуется определить количество простых чисел, которые можно образовать из исходного набора. На первом шаге нам нужно получить список простых чисел, которые используются в условии задачи, на втором - список простых чисел кандидатов. Набор простых чисел проще всего сформировать с помощью решета Эратосфена. Данный алгоритм уже встречался в публикациях. Поэтому ограничусь своим кодом.

В 1С можно, оказывается, разработать процедуру для такой, на первый взгляд, экзотической задачи, как конструирование белковых цепочек. Правда скорость перебора будет слишком низкой. По крайней мере, у моего варианта решения.

Функция РешетоЭратосфена(граница) экспорт
	
	решето=новый массив(граница+1);
	
	простые_числа=новый массив;
	для н=2 по граница цикл
		если решето[н]=неопределено тогда
			простые_числа.Добавить(н);
			для к=н по граница цикл
				если решето[к]=неопределено тогда
				 решето[к]=1;	
				иначе	
				 решето[к]=решето[к]+1;
				конецесли; 
				к=к+н-1;
	        конеццикла;
		конецесли;
	конеццикла;	
	
	возврат простые_числа;
КонецФункции	

Поскольку платформа 1С не предназначена для решения вычислительных задач , то сильно проигрывает в быстродействии таким языкам программирования, как C и Python, но наличие механизма фоновых заданий, в некоторых случаях, позволяет распараллелить  процесс расчетов и уложиться в приемлемое время.  Например, в этой задаче.

Хочу заранее ответить на вопрос: "Зачем решать такие задачи?". Разумеется, практического смысла в данной деятельности нет никакого. Как нет смысла в  том, чтобы пить вино, курить табак, играть в шахматы и подниматься на Эверест.  Тем не менее, люди занимаются этим веками.

Спортивное программирование

См. также

Математика и алгоритмы Программист Платформа 1C v8.2 Конфигурации 1cv8 Россия Абонемент ($m)

На написание данной работы меня вдохновила работа @glassman «Переход на ClickHouse для анализа метрик». Автор анализирует большой объем данных, много миллионов строк, и убедительно доказывает, что ClickHouse справляется лучше PostgreSQL. Я же покажу как можно сократить объем данных в 49.9 раз при этом: 1. Сохранить значения локальных экстремумов 2. Отклонения от реальных значений имеют наперед заданную допустимую погрешность.

1 стартмани

30.01.2024    3459    stopa85    12    

38

Математика и алгоритмы Бесплатно (free)

Разработка алгоритма, построенного на модели симплекс-метода, для нахождения оптимального раскроя.

19.10.2023    7954    user1959478    52    

36

Математика и алгоритмы Разное Платформа 1С v8.3 Конфигурации 1cv8 Россия Абонемент ($m)

Расширение (+ обработка) представляют собою математический тренажер. Ваш ребенок сможет проверить свои знание на математические вычисление до 100.

2 стартмани

29.09.2023    3397    maksa2005    8    

26

Математика и алгоритмы Инструментарий разработчика Программист Платформа 1С v8.3 Мобильная платформа Россия Абонемент ($m)

Что ж... лучше поздно, чем никогда. Подсистема 1С для работы с регулярными выражениями: разбор выражения, проверка на соответствие шаблону, поиск вхождений в тексте.

1 стартмани

09.06.2023    11151    8    SpaceOfMyHead    19    

61

Математика и алгоритмы Программист Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Три задачи - три идеи - три решения. Мало кода, много смысла. Мини-статья.

03.04.2023    4652    RustIG    9    

25

Механизмы платформы 1С Математика и алгоритмы Программист Платформа 1С v8.3 Россия Бесплатно (free)

В статье анализируются средства платформы для решения системы линейных уравнений в 1С. Приводятся доводы в пользу некорректной работы встроенных алгоритмов, а значит потенциально некорректного расчета себестоимости в типовых конфигурациях.

23.11.2022    3809    gzharkoj    14    

25

Математика и алгоритмы Программист Платформа 1С v8.3 Россия Абонемент ($m)

Обычно под распределением понимают определение сумм пропорционально коэффициентам. Предлагаю включить сюда также распределение по порядку (FIFO, LIFO) и повысить уровень размерности до 2-х. 1-ое означает, что распределение может быть не только пропорциональным, но и по порядку, а 2-ое - это вариант реализации матричного распределения: по строкам и столбцам. Возможно вас заинтересует также необычное решение этой задачи через создание DSL на базе реализации текучего интерфейса

1 стартмани

21.03.2022    9093    7    kalyaka    11    

44
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. starik-2005 3090 02.08.21 11:17 Сейчас в теме
пить вино, курить табак, играть в шахматы и подниматься на Эверест
Как-то ассиметрично. Пить вино и курить табак - это бесполезные вещи. До 15-го века о табаке никто ничего не знал (кроме индейцев), а вино пили хоть и давно, но пьяниц никто не уважал - они сами себя загоняли на дно. А те, кто вроде как культурно пили, тоже часто заканчивают не очень хорошо (даже не буду говорить, о ком речь).
3. _Sasha_ 14.08.23 04:50 Сейчас в теме
(1) С бесполезностью вина не все так однозначно. Во времена когда о гигиене и микробах ничего не было известно - разбавленное вино пили взамен кипяченной воды - это снижало в походах смертность от кишечных инфекций
2. scientes 295 02.08.21 11:30 Сейчас в теме
Согласен, но положительное отношение общества к какой-то деятельности, не делает ее осмысленной. И очень трудно найти ответ на вопрос "Зачем?". В качестве примера можно привести достижения Федора Конюхова.
Оставьте свое сообщение