328 lines
14 KiB
Text
328 lines
14 KiB
Text
/////////////////////////////////////////////////////////////////////////////
|
||
// ОБЩИЕ ПРОЦЕДУРЫ И ФУНКЦИИ
|
||
|
||
&НаСервере
|
||
Функция ВыполнитьВКонсолиЛинукс(Команда, ПараметрыКоманды)
|
||
СтруктураВозврата = Новый Структура("Ошибка, Результат");
|
||
ИмяФайла = ПолучитьИмяВременногоФайла("txt");
|
||
ВходнаяКоманда = Команда + " " + ИмяФайла + " "+ ПараметрыКоманды;
|
||
КодЗавершения = 0;
|
||
|
||
Попытка
|
||
ЗапуститьПриложение(ВходнаяКоманда,, Истина, КодЗавершения);
|
||
Исключение
|
||
Сообщить(ОписаниеОшибки());
|
||
КонецПопытки;
|
||
|
||
СтруктураВозврата.Ошибка = КодЗавершения <> 0;
|
||
Если СтруктураВозврата.Ошибка Тогда
|
||
Возврат СтруктураВозврата;
|
||
КонецЕсли;
|
||
|
||
ТекДок = Новый ТекстовыйДокумент;
|
||
ТекДок.Прочитать(ИмяФайла);
|
||
|
||
ТекстДокумента = СокрЛП(ТекДок.ПолучитьТекст());
|
||
СтруктураВозврата.Результат = Прав(ТекстДокумента, СтрДлина(ТекстДокумента)-3);
|
||
КодОбработки = Лев(ТекстДокумента, 3);
|
||
|
||
Если КодОбработки <> "OK:" Тогда
|
||
СтруктураВозврата.Ошибка = Истина;
|
||
Возврат СтруктураВозврата;
|
||
КонецЕсли;
|
||
|
||
Файл = Новый Файл(ИмяФайла);
|
||
Если Файл.Существует() Тогда
|
||
Попытка
|
||
УдалитьФайлы(ИмяФайла);
|
||
Исключение
|
||
СтруктураВозврата.Ошибка = Истина;
|
||
СтруктураВозврата.Результат = ОписаниеОшибки();
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
|
||
Возврат СтруктураВозврата;
|
||
КонецФункции
|
||
|
||
&НаСервере
|
||
Функция ВыполнитьВКонсолиЛинуксПайп(Команда, ПараметрыКоманды)
|
||
СтруктураВозврата = Новый Структура("Ошибка, Результат");
|
||
ИмяФайла = ПолучитьИмяВременногоФайла("txt");
|
||
ВходнаяКоманда = Команда + " " + ПараметрыКоманды + " > " + ИмяФайла;
|
||
КодЗавершения = 0;
|
||
|
||
Попытка
|
||
ЗапуститьПриложение(ВходнаяКоманда,, Истина, КодЗавершения);
|
||
Исключение
|
||
Сообщить(ОписаниеОшибки());
|
||
КонецПопытки;
|
||
|
||
СтруктураВозврата.Ошибка = КодЗавершения <> 0;
|
||
Если СтруктураВозврата.Ошибка Тогда
|
||
Возврат СтруктураВозврата;
|
||
КонецЕсли;
|
||
|
||
ТекДок = Новый ТекстовыйДокумент;
|
||
ТекДок.Прочитать(ИмяФайла);
|
||
|
||
ТекстДокумента = СокрЛП(ТекДок.ПолучитьТекст());
|
||
СтруктураВозврата.Результат = Прав(ТекстДокумента, СтрДлина(ТекстДокумента)-3);
|
||
КодОбработки = Лев(ТекстДокумента, 3);
|
||
|
||
Если КодОбработки <> "OK:" Тогда
|
||
СтруктураВозврата.Ошибка = Истина;
|
||
Возврат СтруктураВозврата;
|
||
КонецЕсли;
|
||
|
||
Файл = Новый Файл(ИмяФайла);
|
||
Если Файл.Существует() Тогда
|
||
Попытка
|
||
УдалитьФайлы(ИмяФайла);
|
||
Исключение
|
||
СтруктураВозврата.Ошибка = Истина;
|
||
СтруктураВозврата.Результат = ОписаниеОшибки();
|
||
КонецПопытки;
|
||
КонецЕсли;
|
||
|
||
Возврат СтруктураВозврата;
|
||
КонецФункции
|
||
|
||
|
||
|
||
&НаКлиенте
|
||
Функция ИсходныеДанныеДляРассчета(ВзятьРаз)
|
||
СтруктураВозврата = Новый Структура("Набор, Требуется", Новый Массив, ВзятьРаз*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СНаСервере();
|
||
Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт);
|
||
КонецПроцедуры
|
||
|
||
|
||
#КонецОбласти
|