Имя: Пароль:
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) да, есть такое. Но, с другой стороны, если раньше всем клиентом, кто прошел регистрацию, рассылали СМС, то теперь решили обзванивать семь случайных за день.
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.