Имя: Пароль:
1C
1С v8
ГСЧ. Сгенерировать разные случайные числа.
0 yurikmellon2
 
20.07.22
16:10
Задачка: сгенерировать семь РАЗЛИЧНЫХ случайных чисел в диапазоне от 1 до 50.
Если использовать стандартный ГенераторСлучайныхЧисел() в цикле, то как проще и эффективнее проверять уникальность полученных чисел?
1 Fish
 
гуру
20.07.22
16:13
(0) Например, добавлять их в массив.
2 Kassern
 
20.07.22
16:13
Хранишь массив сгенерированных чисел, пока он не станет равен 7 генерируешь числа и добавляешь в массив если уникальные.
3 timurhv
 
20.07.22
16:15
(0) Не надо в цикле ГенераторСлучайныхЧисел использовать, он должен быть перед циклом. В цикле только ГенераторСлучайныхЧисел.СлучайноеЧисло.
Иначе выдаст 7 одинаковых чисел.
4 yurikmellon2
 
20.07.22
16:20
(3) это понятно.
самый простой код такой

ГСЧ = Новый ГенераторСлучайныхЧисел();
Для Счетчик = 1 По 7 Цикл
    Рэндом = ГСЧ.СлучайноеЧисло(1, 50);
    Сообщить(Рэндом);
КонецЦикла;    

в этом случае выборка может быть не уникальна, итерации то независимы и числа могут повторяться
5 yurikmellon2
 
20.07.22
16:21
(2) вот чёт не соображу как в массиве это организовать
6 Kassern
 
20.07.22
16:22
(5) Как создать массив не знаете, или как добавить в него число, или как проверить, а есть ли такое значение в массиве? Что именно сообразить не можете? Или вы не знаете как цикл организовать? Ведь помимо цикла Для, Для каждого, есть еще и Пока...
7 mikecool
 
20.07.22
16:24
Пока Массив..Количество() < 7
Если НайтиВМассиве тогда продолжить
...
8 lodger
 
20.07.22
16:27
ГСЧ = Новый ГенераторСлучайныхЧисел();
СемьСлучайных = Новый Соответствие;
    
Пока СемьСлучайных.Количество() < 7 Цикл
    Рэндом = ГСЧ.СлучайноеЧисло(1, 50);
    СемьСлучайных.Вставить(ЧислоПрописью(Рэндом),Рэндом);
КонецЦикла;    
    
Для Каждого КлючЗнач из СемьСлучайных Цикл
    Сообщить(КлючЗнач.Значение);
КонецЦикла;
9 Ненавижу 1С
 
гуру
20.07.22
16:27
Создаете массив на 50 элементов, заполненный числами от 1 до 50
На каждой итерации:
1. Получаете случайное число от 0 до верхнего индекса массива. Находим элемент с этим индексом
2. Добавляете этот элемент в результат
3. Удаляете элемент с этим индексом
10 Kassern
 
20.07.22
16:27
За 14 лет стажа в 1с подобные задачки, имхо, в уме должны решаться
11 Fish
 
гуру
20.07.22
16:28
(8) Забыл проверить на уникальность.
12 Конструктор1С
 
20.07.22
16:28
Сувай числа в ключ соответствия. Дергай ГСЧ пока в соответствии не будет 7 элементов. При инициализации пихай в ГСЧ число, полученное из ТекущаяУниверсальнаяДатаВМиллисекундах(). Так последовательность чисел будет всегда разная
13 mikecool
 
20.07.22
16:30
(12) инициализация без параметра от тек даты выполняется
14 lodger
 
20.07.22
16:32
+к(8) ЧислоПрописью можно выкинуть. соотв мягче чем структура относится к ключам
(11) не забыл. их просто не станет больше, когда будет добавлен повторный ключ.
15 lodger
 
20.07.22
16:33
(11) а лишняя проверка - отъем ресурсов.
16 Fish
 
гуру
20.07.22
16:34
(14) Хм, да. Ступил :)
17 Kassern
 
20.07.22
16:34
(8) (9) (12) Зачем соответствие то? Для чего 2 цикла, когда можно одним управиться? Байтите блин...

    МассивУникальныхЧисел=Новый Массив;
    ГСЧ = Новый ГенераторСлучайныхЧисел();
    Пока МассивУникальныхЧисел.Количество()<7 Цикл
        СлучайноеЧисло = ГСЧ.СлучайноеЧисло(1, 50);
        Если МассивУникальныхЧисел.Найти(СлучайноеЧисло)=Неопределено Тогда
            МассивУникальныхЧисел.Добавить(СлучайноеЧисло);
            Сообщить(СлучайноеЧисло);
        КонецЕсли;
    КонецЦикла;
18 БигБаг
 
20.07.22
16:37
(17) что бы кто-нибудь (8) скопировал в продакшен...
19 lodger
 
20.07.22
16:37
(17) Зачем соответствие то? - поиск и вставка в одно движение. быстрее, легче, меньше кода.
второй цикл - можно и без второго, живите теперь с соответствием.
20 БигБаг
 
20.07.22
16:38
(19) ЧислоПрописью то зачем?
21 lodger
 
20.07.22
16:39
(20) можно выкинуть. отписал в (14)
22 БигБаг
 
20.07.22
16:39
соот.Вставить(Число, Истина) - все.
23 Конструктор1С
 
20.07.22
16:40
(13) раньше такого не было. Без начального числа последовательность СЧ всегда одинаковой получалась
24 yurikmellon2
 
20.07.22
16:41
(10) дык яж админю, 1С так постольку поскольку.
(17) спасибо, изящно и понятно

всем спасибо, всё свободны)
25 Конструктор1С
 
20.07.22
16:42
(17) соответствие лучше заточено для многократного поиска
26 Kassern
 
20.07.22
16:43
(25) да я понял уже эту идею, только в контексте данной задачи это имхо излишне.
27 lodger
 
20.07.22
16:44
(24) когда количество ключей дорастёт до сотен, а заходы до тысяч, изящное Массив.Найти - превратиться в черную дыру для процессорного времени.
28 yurikmellon2
 
20.07.22
16:47
(27) маловероятно, очень узкая конкретная задача, выбрать из списка семь неудачников для холодного обзвона. Кол-во строк в списке не превышает 50
29 Жан Пердежон
 
20.07.22
16:48
(24) (17) где там изящность-то увидел? как раз чтобы не искать в массиве соответствие и используют
30 yurikmellon2
 
20.07.22
16:50
(29) изящно в том смысле, что всё в одном цикле, для моей конкретной задачи этого более чем достаточно
31 Галахад
 
гуру
20.07.22
16:50
+ 1.

(8) лучше чем (17)
32 yurikmellon2
 
20.07.22
16:54
уговорили) через соответствие, так через соответствие. Глядишь, если кто нить из спецов увидит эту поделку, то не будет сильно ругаться на "говнокод"
33 Жан Пердежон
 
20.07.22
16:59
(32) в любом случае говнокод, попробуй этим же алгоритмом выбрать 45 из 50, или 190 из 200
34 6awkup_true
 
20.07.22
17:01
п-сссст. через ком цепляем vbs и через rnd получаем число, чуть допиливаем напильником до целого и вуаля)
35 Kassern
 
20.07.22
17:05
(33) Можно попробовать бить на отрезки, тогда числа повторяться числа не будут и 45 из 50 норм отработает
36 lodger
 
20.07.22
17:11
(33) такие крайние случаи надо обрабатывать перед и инвертировать смысл генерации. 45 из 50 - надо убрать 5 разных. 190 из 200 - убрать 10 разных.
37 Kassern
 
20.07.22
17:17
Если речь об холодном обзвоне, то можно попробовать разбить на равные доли предложить такой вариант. В данном случае будут 7/14/21/28../49 - 7 уникальных чисел.
38 Kassern
 
20.07.22
17:19
а самих клиентов для обзвона отсортировать по дате например. Тогда и старички и новые в равной степени попадут в обзвон. Рандомайз этого гарантировать не может
39 Fish
 
гуру
20.07.22
17:24
Спамеры.
40 БигБаг
 
20.07.22
19:45
Выборка с изъятием:

маИсх = новый Массив;
Для ном = 1 по 50 Цикл
    маИсх.Добавить(ном);
КонецЦикла;

ГСЧ = Новый ГенераторСлучайныхЧисел();
маРез = новый Массив;
Для ном = 1 по 7 Цикл
    индекс = ГСЧ.СлучайноеЧисло(0, маИсх.Количество()-1);
    маРез.Добавить(маИсх.Получить(индекс));
    маИсх.Удалить(индекс);
конецЦикла;

Для каждого рез из маРез Цикл
    сообщить(рез);
КонецЦикла;

Спамеры.
41 yurikmellon2
 
21.07.22
08:24
(38) это выборка за день
(39) да, есть такое. Но, с другой стороны, если раньше всем клиентом, кто прошел регистрацию, рассылали СМС, то теперь решили обзванивать семь случайных за день.
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший