april_day_2026/1c/example.bsl

326 lines
14 KiB
Text
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/////////////////////////////////////////////////////////////////////////////
// ОБЩИЕ ПРОЦЕДУРЫ И ФУНКЦИИ
&НаСервере
Функция ВыполнитьВКонсолиЛинукс(Команда, ПараметрыКоманды)
СтруктураВозврата = Новый Структура("Ошибка, Результат");
ИмяФайла = ПолучитьИмяВременногоФайла("txt");
ВходнаяКоманда = Команда + " " + ИмяФайла + " "+ ПараметрыКоманды;
КодЗавершения = 0;
Попытка
ЗапуститьПриложение(ВходнаяКоманда,, Истина, КодЗавершения);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
СтруктураВозврата.Ошибка = КодЗавершения <> 0;
Если СтруктураВозврата.Ошибка Тогда
Возврат СтруктураВозврата;
КонецЕсли;
ТекДок = Новый ТекстовыйДокумент;
ТекДок.Прочитать(ИмяФайла);
ТекстДокумента = СокрЛП(ТекДок.ПолучитьТекст());
СтруктураВозврата.Результат = Прав(ТекстДокумента, СтрДлина(ТекстДокумента)-3);
КодОбработки = Лев(ТекстДокумента, 3);
Если КодОбработки <> "OK:" Тогда
СтруктураВозврата.Ошибка = Истина;
Возврат СтруктураВозврата;
КонецЕсли;
Файл = Новый Файл(ИмяФайла);
Если Файл.Существует() Тогда
Попытка
УдалитьФайлы(ИмяФайла);
Исключение
СтруктураВозврата.Ошибка = Истина;
СтруктураВозврата.Результат = ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Возврат СтруктураВозврата;
КонецФункции
&НаСервере
Функция ВыполнитьВКонсолиЛинуксПайп(Команда, ПараметрыКоманды)
СтруктураВозврата = Новый Структура("Ошибка, Результат");
ИмяФайла = ПолучитьИмяВременногоФайла("txt");
ВходнаяКоманда = Команда + " " + ПараметрыКоманды + " > " + ИмяФайла;
КодЗавершения = 0;
Попытка
ЗапуститьПриложение(ВходнаяКоманда,, Истина, КодЗавершения);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
СтруктураВозврата.Ошибка = КодЗавершения <> 0;
Если СтруктураВозврата.Ошибка Тогда
Возврат СтруктураВозврата;
КонецЕсли;
ТекДок = Новый ТекстовыйДокумент;
ТекДок.Прочитать(ИмяФайла);
ТекстДокумента = СокрЛП(ТекДок.ПолучитьТекст());
СтруктураВозврата.Результат = Прав(ТекстДокумента, СтрДлина(ТекстДокумента)-3);
КодОбработки = Лев(ТекстДокумента, 3);
Если КодОбработки <> "OK:" Тогда
СтруктураВозврата.Ошибка = Истина;
Возврат СтруктураВозврата;
КонецЕсли;
Файл = Новый Файл(ИмяФайла);
Если Файл.Существует() Тогда
Попытка
УдалитьФайлы(ИмяФайла);
Исключение
СтруктураВозврата.Ошибка = Истина;
СтруктураВозврата.Результат = ОписаниеОшибки();
КонецПопытки;
КонецЕсли;
Возврат СтруктураВозврата;
КонецФункции
s
&НаКлиенте
Функция ИсходныеДанныеДляРассчета(ВзятьРаз)
СтруктураВозврата = Новый Структура("Набор, Требуется", Новый Массив, ВзятьРаз*95510);
МассивСумм = Новый Массив;
Для й=0 По ВзятьРаз Цикл
СтруктураВозврата.Набор.Добавить(15800);
СтруктураВозврата.Набор.Добавить(1525);
СтруктураВозврата.Набор.Добавить(35300);
СтруктураВозврата.Набор.Добавить(19410);
СтруктураВозврата.Набор.Добавить(25000);
КонецЦикла;
Возврат СтруктураВозврата;
КонецФункции
/////////////////////////////////////////////////////////////////////////////
// Первый алгоритм
#Область ПервыйАлгоритм
&НаКлиенте
Функция ДесятичноеВДвоичное(Знач ИсхЧисло)
БулевыйМассив = Новый Массив;
Пока ИсхЧисло <> 0 Цикл
БулевыйМассив.Добавить(ИсхЧисло%2);
ИсхЧисло = Цел(ИсхЧисло/2);
КонецЦикла;
Возврат БулевыйМассив;
КонецФункции
&НаКлиенте
Функция ПолучитьСуммуПоДвоичному(МассивСумм, БулевыйМассив)
СуммаВозврата = 0;
Кол = БулевыйМассив.Количество()-1;
Для й=0 По Кол Цикл
Если БулевыйМассив[й] = 1 Тогда
СуммаВозврата = СуммаВозврата + МассивСумм[й];
КонецЕсли;
КонецЦикла;
Возврат СуммаВозврата;
КонецФункции
&НаКлиенте
Функция НайтиКомбинацию(МассивСумм, Искомое)
ВсегоЧисел = МассивСумм.Количество();
ВсегоКомбинаций = Pow(2,ВсегоЧисел)-1;
Для й=1 По ВсегоКомбинаций Цикл
БулевыйМассив = ДесятичноеВДвоичное(й);
Сумма = ПолучитьСуммуПоДвоичному(МассивСумм, БулевыйМассив);
Если Сумма = Искомое Тогда
Сообщить("Нашли");
Х = "";
Для каждого Бит Из БулевыйМассив Цикл
Х = Х + Строка(Бит);
КонецЦикла;
Сообщить(Х);
Прервать;
КонецЕсли;
КонецЦикла;
КонецФункции
&НаКлиенте
Процедура АлгоритмНомер1(Команда)
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
ДанныеДляРасчета = ИсходныеДанныеДляРассчета(4);
НайтиКомбинацию(ДанныеДляРасчета.Набор, ДанныеДляРасчета.Требуется);
Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт);
КонецПроцедуры
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////
// Второй алгоритм
#Область ВторойАлгоритм
&НаКлиенте
Функция НайтиКомбинациюОпт(МассивСумм, Искомое)
ВсегоЧисел = МассивСумм.Количество();
ВсегоКомбинаций = Pow(2,ВсегоЧисел)-1;
Для Маска=1 По ВсегоКомбинаций Цикл
ТекущаяСумма = 0;
// Проверяем биты маски
Для й = 0 По ВсегоЧисел - 1 Цикл
// Проверка i-го бита через битовое И
// БитовоеИ(Маска, 2^i) > 0 означает, что элемент включен
Если ПобитовоеИ(Маска, Pow(2, й)) <> 0 Тогда
ТекущаяСумма = ТекущаяСумма + МассивСумм[й];
КонецЕсли;
КонецЦикла;
Если ТекущаяСумма = Искомое Тогда
Сообщить("Нашли");
Х = "";
// Восстанавливаем результат (строка 0 и 1)
Для й = 0 По ВсегоЧисел - 1 Цикл
Х = Х + Строка(?(ПобитовоеИ(Маска, Pow(2, й)) <> 0, 1, 0));
КонецЦикла;
Сообщить(Х);
Прервать;
КонецЕсли;
КонецЦикла;
КонецФункции
&НаКлиенте
Функция НайтиКомбинациюОпт2(МассивСумм, Искомое)
ВсегоЧисел = МассивСумм.Количество();
ВсегоКомбинаций = Pow(2,ВсегоЧисел)-1;
// Мемоизация
Мемо = Новый Массив;
Для й = 0 По ВсегоЧисел - 1 Цикл
Мемо.Добавить(Pow(2, й));
КонецЦикла;
Для Маска=1 По ВсегоКомбинаций Цикл
ТекущаяСумма = 0;
// Проверяем биты маски
Для й = 0 По ВсегоЧисел - 1 Цикл
// Проверка i-го бита через битовое И
// БитовоеИ(Маска, 2^i) > 0 означает, что элемент включен
Если ПобитовоеИ(Маска, Мемо[й]) <> 0 Тогда
ТекущаяСумма = ТекущаяСумма + МассивСумм[й];
КонецЕсли;
КонецЦикла;
Если ТекущаяСумма = Искомое Тогда
Сообщить("Нашли");
Х = "";
// Восстанавливаем результат (строка 0 и 1)
Для й = 0 По ВсегоЧисел - 1 Цикл
Х = Х + Строка(?(ПобитовоеИ(Маска, Pow(2, й)) <> 0, 1, 0));
КонецЦикла;
Сообщить(Х);
Прервать;
КонецЕсли;
КонецЦикла;
КонецФункции
&НаКлиенте
Процедура АлгоритмНомер2(Команда)
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
ДанныеДляРасчета = ИсходныеДанныеДляРассчета(4);
НайтиКомбинациюОпт(ДанныеДляРасчета.Набор, ДанныеДляРасчета.Требуется);
Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт);
КонецПроцедуры
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////
// Третий алгоритм
#Область ТретийАлгоритм
&НаСервере
Функция НайтиКомбинациюВнешнийРасчет(МассивСумм, Искомое)
Команда = "~/opt/bin/solution";
СписокЧисел = "";
Для каждого ТекЧисло Из МассивСумм Цикл
СписокЧисел = СписокЧисел + " " + Формат(ТекЧисло, "ЧГ=0");
КонецЦикла;
Ответ = ВыполнитьВКонсолиЛинуксПайп(Команда, Формат(Искомое, "ЧГ=0") + " " + СписокЧисел);
Сообщить(СтрЗаменить(Ответ.Результат,"#*",""));
КонецФункции
&НаКлиенте
Процедура АлгоритмНомер3(Команда)
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
ДанныеДляРасчета = ИсходныеДанныеДляРассчета(4);
НайтиКомбинациюВнешнийРасчет(ДанныеДляРасчета.Набор, ДанныеДляРасчета.Требуется);
Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт);
КонецПроцедуры
#КонецОбласти
/////////////////////////////////////////////////////////////////////////////
// UNUX WAY
#Область СуммаВЦикле
&НаСервере
Процедура CуммаВЦиклеЛинуксНаСервере()
Команда = "~/opt/bin/addint_file";
ПовторитьРаз = 200;
Ответ = Новый Структура("Результат", "0");
Пока ПовторитьРаз > 0 Цикл
Ответ = ВыполнитьВКонсолиЛинукс(Команда, Строка(Ответ.Результат) + " 1");
Если Ответ.Ошибка Тогда
Сообщить(Ответ.Результат);
Прервать;
КонецЕсли;
ПовторитьРаз = ПовторитьРаз - 1;
КонецЦикла;
Сообщить(Ответ.Результат);
КонецПроцедуры
&НаКлиенте
Процедура CуммаВЦиклеЛинукс(Команда)
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
CуммаВЦиклеЛинуксНаСервере();
Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт);
КонецПроцедуры
#КонецОбласти
#Область СуммаВЦикле1C
&НаСервере
Процедура СуммаВЦикле1СНаСервере()
ПовторитьРаз = 1000000;
Результат = 0;
Пока ПовторитьРаз > 0 Цикл
Результат = Результат + 1;
ПовторитьРаз = ПовторитьРаз - 1;
КонецЦикла;
Сообщить(Результат);
КонецПроцедуры
&НаКлиенте
Процедура СуммаВЦикле1С(Команда)
Старт = ТекущаяУниверсальнаяДатаВМиллисекундах();
СуммаВЦикле1СНаСервере();
Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт);
КонецПроцедуры
#КонецОбласти