///////////////////////////////////////////////////////////////////////////// // ОБЩИЕ ПРОЦЕДУРЫ И ФУНКЦИИ &НаСервере Функция ВыполнитьВКонсолиЛинукс(Команда, ПараметрыКоманды) СтруктураВозврата = Новый Структура("Ошибка, Результат"); ИмяФайла = ПолучитьИмяВременногоФайла("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СНаСервере(); Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт); КонецПроцедуры #КонецОбласти