Как получить список простых чисел в запросе

14.12.17

Разработка - Запросы

Поиск простых чисел с помощью запроса (решение тестового задания).

Что может быть проще простых чисел ?  По определению, целое число называется простым, если оно не может быть представлено, как произведение двух меньших чисел. Единственное четное простое число - 2. Все остальные простые числа нечетные. Самый древний алгоритм поиска простых чисел получил название "решето Эратосфена". Это известная история и  останавливаться на ней не будем. Сразу перейдем к заявленной теме, а именно, поиску простых чисел с помощью  запроса на встроенном языке платформы 1С:Предприятие.  Исходным объектом для поиска будет таблица натуральных чисел в диапазоне от 1 до заданного верхнего предела. Подобную таблицу, можно формировать в запросе , но мы упростим себе жизнь и заполним её с помощью операторов встроенного языка.

тз=новый таблицазначений;
тз.Колонки.Добавить("НатуральноеЧисло",новый ОписаниеТипов("Число"));
для н=1 по ВерхнийПредел цикл
  приемник=тз.Добавить();
  приемник.НатуральноеЧисло=н;
конеццикла;	

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

НатуральноеЧисло
1
2
3
4
5
6
7
8
9

Пары чисел, образованные при внутреннем соединении таблицы со своей копией при заданных ограничениях.

Левое Правое Произведение
1 1 1
1 2 2
2 2 4
1 3 3
2 3 6
3 3 9
1 4 4
2 4 8
1 5 5
1 6 6
1 7 7
1 8 8
1 9 9

Исходная таблица содержала 9 строк, итоговая 13. Среди чисел в колонке Произведение есть повторяющиеся. Это числа 4,6 и 9. Числа 1,2,3,5,7 встречаются только один раз. Единицу из этого ряда надо исключить. Оставшиеся четыре числа будут первыми в ряду простых чисел. Приведем текст запроса:

    запрос=новый запрос();
	запрос.МенеджерВременныхТаблиц=новый МенеджерВременныхТаблиц;
	запрос.Параметры.Вставить("Числа",тз);
	запрос.Параметры.Вставить("ВерхняяГраница",тз[тз.Количество()-1].НатуральноеЧисло);
	запрос.Текст="ВЫБРАТЬ
	             |	Числа.НатуральноеЧисло КАК НатурЧисло
	             |ПОМЕСТИТЬ ВТ
	             |ИЗ
	             |	&Числа КАК Числа
	             |;
	             |
	             |
	             |ВЫБРАТЬ
	             |	Левый.НатурЧисло * Правый.НатурЧисло КАК НатуральноеЧисло
	             |ПОМЕСТИТЬ мПростыеЧисла
	             |ИЗ
	             |	ВТ КАК Левый
	             |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК Правый
	             |		ПО (Левый.НатурЧисло * Правый.НатурЧисло <= &ВерхняяГраница)
	             |			И Левый.НатурЧисло <= Правый.НатурЧисло
	             |
	             |СГРУППИРОВАТЬ ПО
	             |	Левый.НатурЧисло * Правый.НатурЧисло
	             |
	             |ИМЕЮЩИЕ
	             |	Количество(*) = 1
	             |;
	             |
	             |
	             |ВЫБРАТЬ
	             |	КОЛИЧЕСТВО(мПростыеЧисла.НатуральноеЧисло) - 1 КАК НатуральноеЧисло
	             |ИЗ
	             |	мПростыеЧисла КАК мПростыеЧисла";

Запрос возвращает количество простых чисел в первоначальном диапазоне.Приведенный алгоритм отличается простотой, но увы, слишком медленный. Постараемся придумать, что-то быстрее.

Как проверить, что число А делится без остатка на число Б. Во встроенном языке есть оператор %, который возвращает остаток от деления. В языке запросов такая опция отсутствует. Поэтому воспользуемся следующим приемом :

ВЫРАЗИТЬ(A/Б КАК ЧИСЛО(19,0))*Б = A

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

Сформируем таблицу с квадратами наших исходных чисел.Теперь соединим данную таблицу с исходной. Полученную набор сгруппируем по исходным числам, а для квадратов применим функцию МИНИМУМ(). Текст запроса приведен ниже:

                 ВЫБРАТЬ
	             |	Числа.НатуральноеЧисло КАК Н
	             |ПОМЕСТИТЬ ВТ
	             |ИЗ
	             |	&Числа КАК Числа
	             |;
	             |
	             |///////////
	             |ВЫБРАТЬ
	             |	ВТ.Н * ВТ.Н КАК Квадрат,
	             |	ВТ.Н КАК Н
	             |ПОМЕСТИТЬ мКвадраты
	             |ИЗ
	             |	ВТ КАК ВТ
	             |ГДЕ
	             |	ВТ.Н * ВТ.Н <= &ВерхняяГраница
	             |;
	             |
	             |//////////
	             |ВЫБРАТЬ
	             |	ВТ.Н КАК Н,
	             |	ВЫБОР
	             |		КОГДА ВТ.Н = 1
	             |			ТОГДА 0
	             |		КОГДА ВТ.Н = 2
	             |			ТОГДА 1
	             |		ИНАЧЕ МИНИМУМ(мКвадраты.Н)
	             |	КОНЕЦ КАК Корень
	             |ПОМЕСТИТЬ мКорни
	             |ИЗ
	             |	ВТ КАК ВТ
	             |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ мКвадраты КАК мКвадраты
	             |		ПО ВТ.Н <= мКвадраты.Квадрат
	             |
	             |СГРУППИРОВАТЬ ПО
	             |	ВТ.Н
	             |;

Во временной таблице мКорни в колонке Н содержится число из исходного набора, а в колонке Корень, минимальное число,квадрат которого больше или равен Н. А теперь соберем все вместе:

    запрос=новый запрос();
	запрос.МенеджерВременныхТаблиц=новый МенеджерВременныхТаблиц;
	запрос.Параметры.Вставить("Числа",тз);

	
	запрос.Текст="ВЫБРАТЬ
	             |	Числа.НатуральноеЧисло КАК Н
	             |ПОМЕСТИТЬ ВТ
	             |ИЗ
	             |	&Числа КАК Числа
	             |;
	             |
	             |/////////////////
	             |ВЫБРАТЬ
	             |	ВТ.Н * ВТ.Н КАК Квадрат,
	             |	ВТ.Н КАК Н
	             |ПОМЕСТИТЬ мКвадраты
	             |ИЗ
	             |	ВТ КАК ВТ
	             |;
	             |
	             |///////////////
	             |ВЫБРАТЬ
	             |	ВТ.Н КАК Н,
	             |	ВЫБОР
	             |		КОГДА ВТ.Н = 1
	             |			ТОГДА 0
	             |		КОГДА ВТ.Н = 2
	             |			ТОГДА 1
	             |		ИНАЧЕ МИНИМУМ(мКвадраты.Н)
	             |	КОНЕЦ КАК Корень
	             |ПОМЕСТИТЬ мКорни
	             |ИЗ
	             |	ВТ КАК ВТ
	             |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ мКвадраты КАК мКвадраты
	             |		ПО ВТ.Н <= мКвадраты.Квадрат
	             |
	             |СГРУППИРОВАТЬ ПО
	             |	ВТ.Н
	             |;
	             |
	             |/////////////
	             |ВЫБРАТЬ
	             |	мКорни.Н КАК Н,
	             |	КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Делители.Н) КАК КолВоДелителей
	             |ПОМЕСТИТЬ мТаблицаПростыхЧисел
	             |ИЗ
	             |	мКорни КАК мКорни
	             |		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК Делители
	             |		ПО мКорни.Корень >= Делители.Н
	             |			И ((ВЫРАЗИТЬ(мКорни.Н / Делители.Н КАК ЧИСЛО(19, 0))) * Делители.Н = мКорни.Н)
	             |
	             |СГРУППИРОВАТЬ ПО
	             |	мКорни.Н
	             |
	             |ИМЕЮЩИЕ
	             |	КОЛИЧЕСТВО(Делители.Н) = 1
	             |;
	             |
	             |//////////
	             |ВЫБРАТЬ
	             |	КОЛИЧЕСТВО(мТаблицаПростыхЧисел.Н) КАК НатуральноеЧисло
	             |ИЗ
	             |	мТаблицаПростыхЧисел КАК мТаблицаПростыхЧисел";

Любопытно проверить, как различаются скорость выполнения первого и второго запроса (время в миллисекундах):

Верхняя граница 1000 2000 3000 4000 5000
Вариант 1 492 795 1229 2314 3061
Вариант 2 651 954 1644 2955 4364

Видим, что первый вариант запроса отрабатывает быстрее. Для второго  можно "проредить" исходные данные, а именно убрать все четные числа кроме двойки (это уже элемент алгоритма "решето Эратосфена"). 

          тз=новый таблицазначений;
	      тз.Колонки.Добавить("НатуральноеЧисло",новый ОписаниеТипов("Число"));
		  приемник=тз.Добавить();
		  приемник.НатуральноеЧисло=1;
		  приемник=тз.Добавить();
		  приемник.НатуральноеЧисло=2;
		  для н=3 по ЭтотОбъект.UpLimit цикл
			  приемник=тз.Добавить();
			  приемник.НатуральноеЧисло=н;
			  н=н+1;
		  конеццикла;	

Очевидно, что после такой операции скорость должна увеличиться, что и показывают замеры (время в миллисекундах):

Верхняя граница 1000 2000 3000 4000 5000
Вариант 1 492 795 1229 2314 3061
Вариант 2 (ускоренный) 268 842 1163 1373 1587

 

Посмотрев решения от  Сергея (ildarovich) , решил добавить экзотику в виде решета Аткина. Максимальное значение верхней границы в приведенном примере -  100 000. Параметры запроса - Граница и КореньИзГраницы. Все простые числа <= 100 000 программа находит за 3 сек.  Результат хуже чем у Сергея (ildarovich), но тоже неплохой.

ВЫБРАТЬ
	0 КАК Х
ПОМЕСТИТЬ Регистр1

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	1

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	2

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	3

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	4

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	5

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	6

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	7

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	8

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	9
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	Младшие.Х + 10 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр2
ИЗ
	Регистр1 КАК Младшие,
	Регистр1 КАК Старшие
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	Младшие.Х + 100 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр4
ИЗ
	Регистр2 КАК Младшие,
	Регистр2 КАК Старшие
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	Младшие.Х + 10000 * Старшие.Х + 1 КАК Н
ПОМЕСТИТЬ Числа
ИЗ
	Регистр4 КАК Младшие,
	Регистр1 КАК Старшие
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	Числа.Н КАК Н,
	ВЫБОР
		КОГДА Числа.Н < &КореньИзГраницы
			ТОГДА Числа.Н * Числа.Н
		ИНАЧЕ 0
	КОНЕЦ КАК КвадратН
ПОМЕСТИТЬ ВТ
ИЗ
	Числа КАК Числа
ГДЕ
	Числа.Н <= &Граница

ИНДЕКСИРОВАТЬ ПО
	Н
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	4 * X.КвадратН + Y.КвадратН КАК Н,
	КОЛИЧЕСТВО(*) КАК КолВо
ПОМЕСТИТЬ Т1
ИЗ
	ВТ КАК X
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК Y
		ПО (X.КвадратН > 0)
			И (Y.КвадратН > 0)
			И (4 * X.КвадратН + Y.КвадратН <= &Граница)

СГРУППИРОВАТЬ ПО
	4 * X.КвадратН + Y.КвадратН

ИМЕЮЩИЕ
	КОЛИЧЕСТВО(*) В (1, 3, 5, 7, 9)

ИНДЕКСИРОВАТЬ ПО
	Н
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	3 * X.КвадратН + Y.КвадратН КАК Н,
	КОЛИЧЕСТВО(*) КАК КолВо
ПОМЕСТИТЬ Т2
ИЗ
	ВТ КАК X
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК Y
		ПО (X.КвадратН > 0)
			И (Y.КвадратН > 0)
			И (3 * X.КвадратН + Y.КвадратН <= &Граница)

СГРУППИРОВАТЬ ПО
	3 * X.КвадратН + Y.КвадратН

ИМЕЮЩИЕ
	КОЛИЧЕСТВО(*) В (1, 3, 5, 7, 9)

ИНДЕКСИРОВАТЬ ПО
	Н
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	3 * X.КвадратН - Y.КвадратН КАК Н,
	КОЛИЧЕСТВО(*) КАК КолВо
ПОМЕСТИТЬ Т3
ИЗ
	ВТ КАК X
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК Y
		ПО X.Н > Y.Н
			И (X.КвадратН > 0)
			И (Y.КвадратН > 0)
			И (3 * X.КвадратН - Y.КвадратН <= &Граница)

СГРУППИРОВАТЬ ПО
	3 * X.КвадратН - Y.КвадратН

ИМЕЮЩИЕ
	КОЛИЧЕСТВО(*) В (1, 3, 5, 7, 9)

ИНДЕКСИРОВАТЬ ПО
	Н
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	4 * ВТ.Н + 1 КАК Кандидат,
	Т1.КолВо КАК КолВо
ПОМЕСТИТЬ мКандидаты
ИЗ
	ВТ КАК ВТ
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Т1 КАК Т1
		ПО (4 * ВТ.Н + 1 <= &Граница)
			И (4 * ВТ.Н + 1 = Т1.Н)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	6 * ВТ.Н + 1,
	Т2.КолВо
ИЗ
	ВТ КАК ВТ
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Т2 КАК Т2
		ПО (6 * ВТ.Н + 1 <= &Граница)
			И (6 * ВТ.Н + 1 = Т2.Н)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	12 * ВТ.Н - 1,
	Т3.КолВо
ИЗ
	ВТ КАК ВТ
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ Т3 КАК Т3
		ПО (12 * ВТ.Н - 1 <= &Граница)
			И (12 * ВТ.Н - 1 = Т3.Н)

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	1,
	1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	2,
	1

ОБЪЕДИНИТЬ ВСЕ

ВЫБРАТЬ
	3,
	1
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	мКандидаты.Кандидат КАК НатуральноеЧисло
ПОМЕСТИТЬ мГруппировка
ИЗ
	мКандидаты КАК мКандидаты
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ РАЗЛИЧНЫЕ
	ВЫБОР
		КОГДА ВТ.КвадратН = 0
			ТОГДА &Граница
		ИНАЧЕ ВТ.КвадратН
	КОНЕЦ КАК КвадратН,
	ВТ.Н КАК Н
ПОМЕСТИТЬ мДляПроверки
ИЗ
	мГруппировка КАК мГруппировка
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК ВТ
		ПО мГруппировка.НатуральноеЧисло = ВТ.Н
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	мДляПроверки.Н
ПОМЕСТИТЬ мПростыеЧисла
ИЗ
	мДляПроверки КАК мДляПроверки
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ мДляПроверки КАК мДелители
		ПО (мДелители.КвадратН <= мДляПроверки.Н)
			И ((ВЫРАЗИТЬ(мДляПроверки.Н / мДелители.Н КАК ЧИСЛО(19, 0))) = мДляПроверки.Н / мДелители.Н)

СГРУППИРОВАТЬ ПО
	мДляПроверки.Н

ИМЕЮЩИЕ
	КОЛИЧЕСТВО(мДляПроверки.Н) = 1
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
	КОЛИЧЕСТВО(мПростыеЧисла.Н) - 1 КАК НатуральноеЧисло
ИЗ
	мПростыеЧисла КАК мПростыеЧисла

Во всех приведенных запросах  вычисляется количество простых чисел не превышающих заданную границу, это способ проверки правильности алгоритма. Найденные значения я сравниваю с результатами выполнения функции primepi на сайте http://www.wolframalpha.com.

Нам осталось сказать, где это можно использовать. Разумеется, ни в одной типовой конфигурации такие задачи не встречаются. Но подобный вопрос может встретиться на собеседовании при приеме на работу. Теперь вы знаете, как на него ответить.

Вступайте в нашу телеграмм-группу Инфостарт

Простые числа язык запросов

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С v8.3 Управляемые формы Запросы Система компоновки данных Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

15500 руб.

02.09.2020    213713    1173    413    

1050

Инструментарий разработчика Запросы Программист 1С v8.3 Сложные периодические расчеты Запросы 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

QueryConsole1C — расширение, включающее консоль запросов с поддержкой исполняемых представлений — аналогов виртуальных таблиц, основанных на методах программного интерфейса ЗУП. Оно позволяет выполнять запросы с учётом встроенной бизнес-логики, отлаживать алгоритмы получения данных и автоматически генерировать код на встроенном языке 1С.

1 стартмани

16.05.2025    5194    87    zup_dev    20    

68

Инструментарий разработчика Запросы Программист 1С v8.3 Управляемые формы Запросы 1С:ERP Управление предприятием 2 Абонемент ($m)

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

2 стартмани

05.03.2025    3833    15    XilDen    12    

25

Обновление 1С Запросы Программист 1С v8.3 1С:ERP Управление предприятием 2 Абонемент ($m)

Данный инструмент помогает анализировать доработанную конфигурацию после обновления на новый релиз и находить «битые» тексты запросов, в которых участвуют несуществующие в новом релизе метаданные.

3 стартмани

06.02.2025    3509    26    XilDen    26    

38

Запросы Программист 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

В статье приведена удобная возможность отладки исполняемого запроса динамического списка.

03.12.2024    8324    artemusII    11    

24

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

Увидел cheatsheet по SQL и захотелось нарисовать подобное, но про запросы.

18.10.2024    16796    sergey279    18    

70

Запросы Программист 1С v8.3 Запросы 1C:Бухгалтерия Бесплатно (free)

Столкнулся с интересной ситуацией, которую хотел бы разобрать, ввиду её неочевидности. Речь пойдёт про использование функции запроса АВТОНОМЕРЗАПИСИ() и проблемы, которые могут возникнуть.

11.10.2024    11443    XilDen    38    

103

СКД Механизмы типовых конфигураций Запросы Программист 1С v8.3 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Россия Бесплатно (free)

Работая с типовыми отчетами в конфигурациях «Зарплата и управление персоналом, редакция 3», «Зарплата и кадры государственного учреждения, редакция 3» и подобных, в схемах компоновки данных можно встретить конструкции запросов, которые обращаются к некоторым виртуальным таблицам.

20.08.2024    5402    PROSTO-1C    0    

28
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Filipp_Hardcorov 29.11.17 09:46 Сейчас в теме
Я бы все равно не взял программиста, который таким образом оформил код.
Vladimir Litvinenko; kuzyara; awk; purgin; Zeskord; CyberCerber; +6 1 Ответить
16. 🅵🅾️🆇 526 01.12.17 12:43 Сейчас в теме
(1) Что не так с оформлением?
18. Filipp_Hardcorov 01.12.17 16:35 Сейчас в теме
(16)
1С. Общие требования к построению конструкций встроенного языка:
1. В конструкциях встроенного языка ключевые слова пишутся канонически (как в документации или Синтакс-помощнике).
Правильно:

КонецЕсли

Неправильно:

конецЕсли, КОНЕЦЕСЛИ, конецесли, Конецесли.

2. При следовании друг за другом нескольких операторов присваивания, допускается выравнивать их следующим образом:

ДиалогВыбора.ПолноеИмяФайла = ИмяФайла;
ДиалогВыбора.Каталог = ИмяПути; (тут должно быть выровнено по "=", но пробелы стираются при добавлении коммента)


Если не соблюдать эти 2 простых правила, то код будет резать глаза.
SerVer1C; +1 Ответить
19. 🅵🅾️🆇 526 01.12.17 19:42 Сейчас в теме
(18) Глупости.
Возможно Вы один из тех людей, что следуют дзен-правилам 1с и дорожат сертификатами, но не все таковыми являются.
То что 1с хочет навязать PascalCase не делает людей использующих camelCase неполноценными.

1) Я, например, оформляю код так и не вижу в нем ничего плохого и нечитабельного:
ПОКА А ЦИКЛ // <== Корневой цикл/условие с вложенными циклами/условиями обозначаю строчными
	Для Каждого Б Из В Цикл
		Если Г Тогда
			мФруктов	= СтрРазделить("Яблоки,Апельсины,Мандарины", ",");
		КонецЕсли; // Если Г
	КонецЦикла; // Для Каждого Б Из В
КОНЕЦЦИКЛА; // ПОКА А
Показать
Если работодатель будет против - буду делать в соответсвии корпоративным нормативом (ну или уволюсь).

2) Табуляции это, конечно, здорово, сам их использую на винде.
Только вот под линем они могут пойти по огромной такой [3,14]зде и выглядеть будет крайне отвратно.
Вы же доподлино не знаете под какой платформой сидит человек для подобных суждений, верно?
Алсо, на инфостарте табуляции в кодбоксе также отображаются криво, оценить можете в сниппетах под спойлерами всю плачевность ситуации: ТЫК

ВЫВОД: не стоит быть столь категоричным и плясать под дудку 1с.
Все же главное читабельность. А агрессивные работодатели с еб@нутыми требованиями/придирками получат соответсвующих специалистов.

БОНУС: В школах-институтах нас по рукам за GOTO били, так может теперь и Перейти (GOTO) не использовать?
Давненько не видел в чужих публикациях этого оператора, хотя его можно очень толково применять.
23. Filipp_Hardcorov 02.12.17 01:51 Сейчас в теме
(19)
Я не следую всем правилам, просто когда все в едином стиле - это воспринимается лучше зрительно и говорит о том, что программист писал не на отъе***, а старался.
Зачем вы тогда по-русски пишете сейчас без ошибок, со знаками препинания, и предложения начинаете с большой буквы?
22. boln 1042 02.12.17 00:02 Сейчас в теме
(18)
ДиалогВыбора.ПолноеИмяФайла = ИмяФайла;
ДиалогВыбора.Каталог = ИмяПути; (тут должно быть выровнено по "=", но пробелы стираются при добавлении коммента)
Отнюдь не "должно", хотя и красиво выглядит. И есть довольно много противников такого выравнивания (я лично к ним не отношусь).

А вот по первому пункту согласен.
24. Filipp_Hardcorov 02.12.17 01:53 Сейчас в теме
(22)
Во-первых выглядит симпатичнее, а во-вторых сразу понятно, что это блок заполнения какой-то структуры.
Т.е. если тебе нужно что-то исправить, не относящееся к этому, можно много строк просто пропустить глазами, что ускоряет восприятие "чужого" кода, да и своего тоже.
25. 🅵🅾️🆇 526 02.12.17 11:14 Сейчас в теме
(24)
Только вот под линем они могут пойти по огромной такой [3,14]зде и выглядеть будет крайне отвратно.
Алсо, на инфостарте табуляции в кодбоксе также отображаются криво
26. boln 1042 02.12.17 11:18 Сейчас в теме
(24)
Во-первых выглядит симпатичнее, а во-вторых сразу понятно, что это блок заполнения какой-то структуры.
Т.е. если тебе нужно что-то исправить, не относящееся к этому, можно много строк просто пропустить глазами, что ускоряет восприятие "чужого" кода, да и своего тоже.
Угу, я тоже так свой код оформляю. Сделал даже программый "выравниватель" - и для EDT:
https://infostart.ru/public/569440/
и для Конфигуратора:
https://www.youtube.com/watch?v=R8WB-Y24w_A&feature=youtu.be

Но есть жесткие противники этого. На партнерке даже мини-холивар был по поводу "выравнивания". Раньше в Рекомендациях 1С по оформлению кода был этот пункт, а сейчас убрали вроде.
2. Boneman 302 29.11.17 09:53 Сейчас в теме
А я бы сам не пошел в такую контору, которая дала-бы мне такую тестовую задачу
BurlakovIvan; shard; DarkUser; Saint13; uri1978; tsukanov; boln; 🅵🅾️🆇; AlexGroovy; CyberCerber; SP2000; ALagutin; purgin; zqzq; fancy; papami; el-gamberro; Zeskord; 7fortune; madonov; rybusha; bulpi; +22 Ответить
3. Filipp_Hardcorov 29.11.17 10:18 Сейчас в теме
upd.
Не, неправ я оказался)

И, возможно, я ошибаюсь, но нам необходимо проверить делится ли число на 2, 3, 5 или 7.
Если не делится, значит оно - простое.
Соответственно, как то так:

На вход пусть подается ТЗ ТаблицаЧисел
Функция КоличествоПростыхВТаблице(ТаблицаЧисел)

	Запрос = Новый Запрос;
	Запрос.Текст = 
	"ВЫБРАТЬ
	|	Числа.Число
	|ПОМЕСТИТЬ вт_Числа
	|ИЗ
	|	&Числа КАК Числа
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	вт_Числа.Число,
	|	ВЫРАЗИТЬ(вт_Числа.Число / 2 КАК ЧИСЛО(15, 0)) КАК ДелениеНа2,
	|	вт_Числа.Число / 2 КАК ДелениеНа2СОстатком,
	|	ВЫРАЗИТЬ(вт_Числа.Число / 3 КАК ЧИСЛО(15, 0)) КАК ДелениеНа3,
	|	вт_Числа.Число / 3 КАК ДелениеНа3СОстатком,
	|	ВЫРАЗИТЬ(вт_Числа.Число / 5 КАК ЧИСЛО(15, 0)) КАК ДелениеНа5,
	|	вт_Числа.Число / 5 КАК ДелениеНа5СОстатком,
	|	ВЫРАЗИТЬ(вт_Числа.Число / 7 КАК ЧИСЛО(15, 0)) КАК ДелениеНа7,
	|	вт_Числа.Число / 7 КАК ДелениеНа7СОстатком
	|ИЗ
	|	вт_Числа КАК вт_Числа
	|ГДЕ
	|	(ВЫРАЗИТЬ(вт_Числа.Число / 2 КАК ЧИСЛО(15, 0))) <> вт_Числа.Число / 2
	|	И (ВЫРАЗИТЬ(вт_Числа.Число / 3 КАК ЧИСЛО(15, 0))) <> вт_Числа.Число / 3
	|	И (ВЫРАЗИТЬ(вт_Числа.Число / 5 КАК ЧИСЛО(15, 0))) <> вт_Числа.Число / 5
	|	И (ВЫРАЗИТЬ(вт_Числа.Число / 7 КАК ЧИСЛО(15, 0))) <> вт_Числа.Число / 7";

	Запрос.УстановитьПараметр("Числа", ТаблицаЧисел);
	Выборка = Запрос.Выполнить().Выбрать();

	Возврат Выборка.Количество();

КонецФункции;

Показать
4. tori131313 29.11.17 10:34 Сейчас в теме
(3) Ошибаетесь. Возьмите 11*11=121. Не делится нацело по данному алгоритму, но и простым уже не является.
5. kiruha 389 29.11.17 11:07 Сейчас в теме
8. scientes 296 29.11.17 12:42 Сейчас в теме
6. vadim1011985 102 29.11.17 11:54 Сейчас в теме
Среди чисел в колонке Произведение есть повторяющиеся. Это числа 4,6 и 9.
Не нашел повторения числа 4 в приведенной таблице , но есть повторения числа 8 Проверьте - возможно опечатка
7. scientes 296 29.11.17 12:32 Сейчас в теме
(6) Да, это ошибка. Таблица была неполная. 1*4=4: 2*2=4
9. bulpi 217 29.11.17 13:42 Сейчас в теме
"ВЫРАЗИТЬ(A/Б КАК ЧИСЛО(19,2))*Б = Б

Если это выражение истинно, то Б является делителем числа А."

Это ошибка, исправьте на
ВЫРАЗИТЬ(A/Б КАК ЧИСЛО(19,0))*Б = А
10. scientes 296 29.11.17 14:02 Сейчас в теме
(9) Да Вы правы, это ошибка. Исправил. Благодарю за замечание.
11. ildarovich 8035 29.11.17 15:46 Сейчас в теме
Вот такой запрос находит все нечетные простые числа на отрезке [1 ... 131073] за 1,308 сек. Используется решето Сундарама. Параметрами является N, которое задает интервал поиска как [1 ... 2N+1] и заранее вычисленное значение (SQRT(2N+1)-1)/2.
ВЫБРАТЬ
	0 КАК Х
ПОМЕСТИТЬ Регистр1
ОБЪЕДИНИТЬ
ВЫБРАТЬ
	1
;
ВЫБРАТЬ
	Младшие.Х + 2 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр2
ИЗ
	Регистр1 КАК Младшие,
	Регистр1 КАК Старшие
;
ВЫБРАТЬ
	Младшие.Х + 4 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр4
ИЗ
	Регистр2 КАК Младшие,
	Регистр2 КАК Старшие
;
ВЫБРАТЬ
	Младшие.Х + 16 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр8
ИЗ
	Регистр4 КАК Младшие,
	Регистр4 КАК Старшие
;
ВЫБРАТЬ
	Младшие.Х + 256 * Старшие.Х + 1 КАК Х
ПОМЕСТИТЬ Регистр16
ИЗ
	Регистр8 КАК Младшие,
	Регистр8 КАК Старшие
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	2 * ВложенныйЗапрос.Х + 1 КАК ПростоеЧисло
ИЗ
	(ВЫБРАТЬ
		А.Х + Б.Х + 2 * А.Х * Б.Х КАК Х
	ИЗ
		Регистр16 КАК А
			ВНУТРЕННЕЕ СОЕДИНЕНИЕ Регистр16 КАК Б
			ПО (Б.Х МЕЖДУ А.Х И (&Эн - А.Х) / (2 * А.Х + 1))
	ГДЕ
		А.Х <= &КореньИз_ДваЭнПлюс1_Минус1_РазделитьНа2
	
	ОБЪЕДИНИТЬ ВСЕ
	
	ВЫБРАТЬ
		А.Х
	ИЗ
		Регистр16 КАК А
	ГДЕ
		А.Х <= &Эн) КАК ВложенныйЗапрос

СГРУППИРОВАТЬ ПО
	ВложенныйЗапрос.Х

ИМЕЮЩИЕ
	КОЛИЧЕСТВО(*) = 1

УПОРЯДОЧИТЬ ПО
	ПростоеЧисло
Показать
Первая часть запроса, формирующая ряд чисел, взята отсюда: Порождающий запрос. "Все нечетные простые числа" означает, что к результату (к полученному множеству простых чисел) нужно добавить единственное простое четное число 2.
mevgenym; ValentinGushchin; 🅵🅾️🆇; kiruha; NeviD; +5 Ответить
12. scientes 296 29.11.17 18:07 Сейчас в теме
(11) Классно, все работает ! Сундарама молодец !
13. ildarovich 8035 29.11.17 19:27 Сейчас в теме
(0) Понял, наконец, что меня смущает в варианте 2. Вся эта возня с квадратами ни к чему. Достаточно добавить поле ХХ (квадрат) к таблице чисел, что можно сделать (кажется) прямо при чтении таблицы в запрос. Тогда весь необходимый код уложится в минимум строк:
ВЫБРАТЬ
	Числа.НатуральноеЧисло КАК Х,
	Числа.НатуральноеЧисло * Числа.НатуральноеЧисло КАК ХХ
ПОМЕСТИТЬ ВТ
ИЗ
	&Числа КАК Числа
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Делимое.Х КАК ПростоеЧисло
ИЗ
	ВТ КАК Делимое
		ВНУТРЕННЕЕ СОЕДИНЕНИЕ ВТ КАК Делитель
		ПО Делимое.Х >= Делитель.ХХ
			И ((ВЫРАЗИТЬ(Делимое.Х / Делитель.Х КАК ЧИСЛО(19, 0))) = Делимое.Х / Делитель.Х)

СГРУППИРОВАТЬ ПО
	Делимое.Х

ИМЕЮЩИЕ
	КОЛИЧЕСТВО(*) = 1
Показать
Условие делимости так написано нарочно, в надежде на то, что Делимое.Х / Делитель.Х будет вычисляться один раз.
mevgenym; starik-2005; 🅵🅾️🆇; NeviD; fancy; EMelihoff; Serj1C; +7 Ответить
14. scientes 296 29.11.17 19:57 Сейчас в теме
(13) Да, все правильно. так быстрее.
15. Кадош 30.11.17 13:53 Сейчас в теме
У вас ошибка в заголовке. Правильно - "Как получить список простых чисел в запросе и самое главное зачем?"
alex-l19041; Mr.Rm; 7fortune; olegmedvedev; +4 Ответить
17. 🅵🅾️🆇 526 01.12.17 12:45 Сейчас в теме
27. Кадош 02.12.17 18:39 Сейчас в теме
(17)Показ лаборатории иностранному гостю. "А вот тут мы вырастили биллиардный шар с волосами."
"Зачем?" - "Не знаю, но было очень трудно"
20. starik-2005 3188 01.12.17 23:00 Сейчас в теме
Интересное упражнение. Поколдовал в конфегураторе и что-то такое получилось:
	Запрос = Новый Запрос(
	"ВЫБРАТЬ
	|	0 КАК Поле1
	|ПОМЕСТИТЬ ВТ1
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	1
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	2
	|
	|ОБЪЕДИНИТЬ ВСЕ
	|
	|ВЫБРАТЬ
	|	3
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	ВТ.Поле1 + ВТ1.Поле1 * 4 + ВТ2.Поле1 * 16 + ВТ3.Поле1 * 64 + ВТ4.Поле1 * 256 + 2 КАК Число
	|ПОМЕСТИТЬ ВТСт
	|ИЗ
	|	ВТ1 КАК ВТ,
	|	ВТ1 КАК ВТ1,
	|	ВТ1 КАК ВТ2,
	|	ВТ1 КАК ВТ3,
	|	ВТ1 КАК ВТ4
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ РАЗЛИЧНЫЕ
	|	ВТК.Число * ВТСт.Число КАК Число
	|ПОМЕСТИТЬ ВТНеПростые
	|ИЗ
	|	ВТСт КАК ВТСт,
	|	ВТСт КАК ВТК
	|ГДЕ
	|	ВТК.Число * ВТСт.Число < &Предел
	|;
	|
	|////////////////////////////////////////////////////////////­////////////////////
	|ВЫБРАТЬ
	|	ВТСт.Число КАК Число
	|ИЗ
	|	ВТСт КАК ВТСт
	|ГДЕ
	|	ВТСт.Число < &Предел И НЕ ВТСт.Число В
	|				(ВЫБРАТЬ
	|					ВТНеПростые.Число
	|				ИЗ
	|					ВТНеПростые)
	|	
	|
	|УПОРЯДОЧИТЬ ПО
	|	ВТСт.Число");
	Запрос.УстановитьПараметр("Предел", Предел);
	Таблица.Загрузить(
		Запрос.Выполнить().Выгрузить()
		);

Показать

Кстати, этот запрос легко модицифировать и получить все натуральные делители для нужного числа, а кто-то тут не так давно отказывался от решения подобной задачи на собеседовании )))
21. ildarovich 8035 01.12.17 23:37 Сейчас в теме
У меня тоже решето Аткина проигрывает решету Сундарама. Вот моя реализация:
ВЫБРАТЬ
	0 КАК Х
ПОМЕСТИТЬ Регистр1

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	1
;
ВЫБРАТЬ
	Младшие.Х + 2 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр2
ИЗ
	Регистр1 КАК Младшие,
	Регистр1 КАК Старшие
;
ВЫБРАТЬ
	Младшие.Х + 4 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр4
ИЗ
	Регистр2 КАК Младшие,
	Регистр2 КАК Старшие
;
ВЫБРАТЬ
	Младшие.Х + 16 * Старшие.Х КАК Х
ПОМЕСТИТЬ Регистр8
ИЗ
	Регистр4 КАК Младшие,
	Регистр4 КАК Старшие
;
ВЫБРАТЬ
	1 + Младшие.Х + 256 * Старшие.Х КАК Х
ПОМЕСТИТЬ Ряд
ИЗ
	Регистр8 КАК Младшие,
	Регистр2 КАК Старшие
ГДЕ
	1 + Младшие.Х + 256 * Старшие.Х <= &КореньИзГраницы
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	КвадратичныеФормы.Х,
	КвадратичныеФормы.Х * КвадратичныеФормы.Х КАК ХХ
ПОМЕСТИТЬ Кандидаты
ИЗ
	(ВЫБРАТЬ
		Случай1.Х КАК Х
	ИЗ
		(ВЫБРАТЬ
			4 * А.Х * А.Х + Б.Х * Б.Х КАК Х
		ИЗ
			Ряд КАК А,
			Ряд КАК Б) КАК Случай1
	ГДЕ
		СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Случай1.Х * 5)) В (5, 25)
	
	ОБЪЕДИНИТЬ ВСЕ
	
	ВЫБРАТЬ
		Случай2.Х
	ИЗ
		(ВЫБРАТЬ
			3 * А.Х * А.Х + Б.Х * Б.Х КАК Х
		ИЗ
			Ряд КАК А,
			Ряд КАК Б) КАК Случай2
	ГДЕ
		СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Случай2.Х * 5)) = 35
	
	ОБЪЕДИНИТЬ ВСЕ
	
	ВЫБРАТЬ
		Случай3.Х
	ИЗ
		(ВЫБРАТЬ
			3 * А.Х * А.Х - Б.Х * Б.Х КАК Х
		ИЗ
			Ряд КАК А
				ВНУТРЕННЕЕ СОЕДИНЕНИЕ Ряд КАК Б
				ПО А.Х > Б.Х) КАК Случай3
	ГДЕ
		СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, Случай3.Х * 5)) = 55) КАК КвадратичныеФормы
ГДЕ
	СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, КвадратичныеФормы.Х * 12)) > 0
	И КвадратичныеФормы.Х <= &Граница

СГРУППИРОВАТЬ ПО
	КвадратичныеФормы.Х

ИМЕЮЩИЕ
	СЕКУНДА(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 1, 1), СЕКУНДА, КОЛИЧЕСТВО(*) * 30)) = 30
;

////////////////////////////////////////////////////////////­////////////////////
ВЫБРАТЬ
	Делимое.Х КАК Х
ИЗ
	Кандидаты КАК Делимое
		ЛЕВОЕ СОЕДИНЕНИЕ Кандидаты КАК Делитель
		ПО (Делитель.ХХ <= Делимое.Х)
			И ((ВЫРАЗИТЬ(Делимое.Х / Делитель.Х КАК ЧИСЛО(15, 0))) = Делимое.Х / Делитель.Х)
ГДЕ
	Делитель.Х ЕСТЬ NULL

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	2

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	3

ОБЪЕДИНИТЬ

ВЫБРАТЬ
	5

УПОРЯДОЧИТЬ ПО
	Делимое.Х
Показать
для сравнения. Тут вроде бы нечего дальше оптимизировать, а работает примерно в 1,6 раза дольше, чем Сундарама, который еще можно чуть-чуть "подкрутить" в плане оптимизации (за счет проверки пустых мест рядом с четными, а не соединением с таблицей чисел). Это странно. Алгоритм Аткина вообще-то считается более быстрым.
mevgenym; +1 Ответить
28. scientes 296 03.12.17 17:27 Сейчас в теме
(21) Можно немного увеличить скорость выполнения запроса использованием конструкций
29. ildarovich 8035 03.12.17 23:40 Сейчас в теме
(28) "конструкций ..." - что-то здесь пропущено
31. scientes 296 04.12.17 12:34 Сейчас в теме
(29)
МЕСЯЦ(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 12, 1), МЕСЯЦ, Случай1.Х )) В (1,5)

МЕСЯЦ(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 12, 1), МЕСЯЦ, Случай2.Х )) = 7

МЕСЯЦ(ДОБАВИТЬКДАТЕ(ДАТАВРЕМЯ(1, 12, 1), МЕСЯЦ, Случай3.Х )) = 11


Правда, для больших чисел программа начинает ругаться на переполнение. Я так понял, поэтому и применяется вариант с секундами.
32. ildarovich 8035 04.12.17 13:26 Сейчас в теме
(31) Да, но и с секундами будет когда-нибудь ругаться. Там предел 2^32 - 1 или 2^31 - 1. Это примерно миллиард. Надеюсь, никто не додумается из миллиарда простые числа в запросе определять. Так как будет уже не с временем (оно почти линейно растет, поэтому миллиард за 16000 секунд должен посчитаться), а с памятью проблемы.
30. Saint13 04.12.17 05:46 Сейчас в теме
Возникает вопрос:
В реальной жизни есть боевая задача по данной теме?
(для 1С)
alex-l19041; +1 Ответить
33. Eret1k 27.04.19 23:23 Сейчас в теме
+ за
Разумеется, ни в одной типовой конфигурации такие задачи не встречаются. Но подобный вопрос может встретиться на собеседовании при приеме на работу.
34. user1119853 02.01.20 15:16 Сейчас в теме
Для отправки сообщения требуется регистрация/авторизация