diff --git a/1c/example.bsl b/1c/example.bsl new file mode 100644 index 0000000..703156f --- /dev/null +++ b/1c/example.bsl @@ -0,0 +1,328 @@ +///////////////////////////////////////////////////////////////////////////// +// ОБЩИЕ ПРОЦЕДУРЫ И ФУНКЦИИ + +&НаСервере +Функция ВыполнитьВКонсолиЛинукс(Команда, ПараметрыКоманды) + СтруктураВозврата = Новый Структура("Ошибка, Результат"); + ИмяФайла = ПолучитьИмяВременногоФайла("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СНаСервере(); + Сообщить(ТекущаяУниверсальнаяДатаВМиллисекундах() - Старт); +КонецПроцедуры + + +#КонецОбласти