Что нового

Рандомные числа без совпадений

Isn

Новичок
Сообщения
119
Репутация
3
Приветствую всех пользователей форума, имеется следующий код:
Код:
;---------------------------------------------------------------------------------------------
Func _Random()
	For $i = 100 To 1 Step -1
		Sleep(100)
		_Func1()
	Next
EndFunc
;---------------------------------------------------------------------------------------------
Func _Func1()
	$sRandom1 = Random(16)
	$sRandom2 = StringMid($sRandom1, 1, 1)
	$sPlay1 = $sRandom2
	$sRandom1 = Random(16)
	$sRandom2 = StringMid($sRandom1, 1, 1)
	$sPlay2 = $sRandom2
	$sRandom1 = Random(16)
	$sRandom2 = StringMid($sRandom1, 1, 1)
	$sPlay3 = $sRandom2
	$sRandom1 = Random(16)
	$sRandom2 = StringMid($sRandom1, 1, 1)
	$sPlay4 = $sRandom2
	$sRandom1 = Random(16)
	$sRandom2 = StringMid($sRandom1, 1, 1)
	$sPlay5 = $sRandom2
	$sRandom1 = Random(16)
	$sRandom2 = StringMid($sRandom1, 1, 1)
	$sPlay6 = $sRandom2
	$sRandom1 = Random(16)
	$sRandom2 = StringMid($sRandom1, 1, 1)
	$sPlay7 = $sRandom2
	$sRandom1 = Random(16)
	$sRandom2 = StringMid($sRandom1, 1, 1)
	$sPlay8 = $sRandom2
EndFunc
;---------------------------------------------------------------------------------------------

При вызове функции _Random() запускается функция _Func1() 100 раз и каждой переменной $sPlay присваивается рандомное число от 0 до 16, но есть один минус: переменным $sPlay иногда присваивается одно и тоже число как мне написть функцию что бы переменным присваивалось рандомное число и не было совпадений. Сижу со вчерашнего дня в голову ни чего не приходит.
За ранее спасибо.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Код:
#include <Array.au3>

$aRet = _RandomUnique(10, 15)

_ArrayDisplay($aRet)

;$iGenerateNums - Total numbers to generate.
;$iMaxEachNum - Largest number to be generated.
;$iMinEachNum - Smallest number to be generated.
;Note: $iGenerateNums can not be grater than ($iMaxEachNum - $iMinEachNum) + 1
Func _RandomUnique($iGenerateNums, $iMaxEachNum, $iMinEachNum = 0)
	If $iGenerateNums > ($iMaxEachNum - $iMinEachNum) + 1 Then Return SetError(1, 0, 0)
	
	Local $aRandom[$iGenerateNums]
	
	For $i = 0 To $iGenerateNums-1
		While 1
			$aRandom[$i] = Random($iMinEachNum, $iMaxEachNum, 1)
			
			For $j = 0 To $iGenerateNums-1
				If $j = $i Then
					ContinueLoop
				EndIf
				
				If $aRandom[$j] = $aRandom[$i] Then
					ContinueLoop 2
				EndIf
			Next
			
			ExitLoop
		WEnd
	Next
	
	Return $aRandom
EndFunc
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
Код:
#include <Array.au3>

$Random = _XRandom (0, 16, 8)
_ArrayDisplay($Random, "$Random")

Func _XRandom ($Min, $Max, $Count)
    Local $avArray[1]

	If $Count >= $Max Then Return SetError(1)

    For $i = 0 To $Count-1
        $rdm = Random($Min, $Max, 1)
        While Not _ArrayFindAll($avArray, $rdm)
            $rdm = Random($Min, $Max, 1)
        WEnd
        _ArrayAdd($avArray, $rdm)
    Next
    $avArray[0] = $Count
    Return $avArray
EndFunc


PS: чуть-чуть исправил, т.к. Z_Lenar натолкнул на здравую мысль...
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Код:
#include <Array.au3>

ConsoleWrite(_Random(0,16,8))
; Или
$arr = StringSplit(_Random(0,16,8), ';', 2)
_ArrayDisplay($arr)

Func _Random($min, $max, $count)
	Local $i, $nums, $rnd

	If $count > $max - $min + 1 Then Return SetError(1,0,0)

	For $i = 0 To $count-1
		Do
			$rnd = Random($min, $max, 1)
		Until StringInStr($nums, $rnd & ';') = 0
		$nums = $nums & $rnd & ';'
	Next
	Return StringTrimRight($nums, 1)
EndFunc



Добавлено:
Сообщение автоматически объединено:

Эта вроде самая быстрая:
Код:
#include <Array.au3>
#include <String.au3>

ConsoleWrite(_Random2(0,1000,500))
; Или
$arr = StringSplit(_Random2(0,1000,500), ';', 2)
_ArrayDisplay($arr)

Func _Random2($min, $max, $count)
	Local $i, $nums, $rnd, $ret

	If $count > $max - $min + 1 Then Return SetError(1,0,0)

	$nums = _StringRepeat(' ', $max-$min+1)

	For $i = 0 To $count-1
		Do
			$rnd = Random($min, $max, 1)
		Until StringMid($nums, $rnd-$min+1, 1) = ' '
		$nums = StringLeft($nums, $rnd-$min) & '-' & StringMid($nums,$rnd-$min+2)
		$ret = $ret & $rnd & ';'
	Next

	Return StringTrimRight($ret, 1)
EndFunc


---Zak---
Спасибо, исправлено.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
2 Z_Lenar

Запусти свой скрипт:
Код:
ConsoleWrite(_Random2(0,2,4))


Код:
If $count > $max+1 Then Return SetError(1,0,0)
 
Автор
Isn

Isn

Новичок
Сообщения
119
Репутация
3
А как мне использовав данные примеры назанчтить каждой переменной $sPlay рандомное число.
 

---Zak---

Скриптер
Сообщения
455
Репутация
120
После ты получишь массив с рандомными числами...

Допустим взять последний пример Z_Lenar

Код:
$sPlay = StringSplit(_Random(0,16,8), ';', 2)

$sPlay - массив состоит из 8 элементов, в каждом по 1 числу.
Используй его и в дальнейшем:

Код:
ConsoleWrite($sPlay[0]&@CRLF)
ConsoleWrite($sPlay[1]&@CRLF)
...
ConsoleWrite($sPlay[7]&@CRLF)


Либо...

Код:
$arr = StringSplit(_Random(0,16,8), ';', 2)
$sPlay1 = $arr[0]
$sPlay2 = $arr[1]
...
$sPlay8 = $arr[7]
 

Z_Lenar

Продвинутый
Сообщения
209
Репутация
52
Isn

Код:
#include <String.au3>

Global $sPlay1,$sPlay2,$sPlay3,$sPlay4,$sPlay5,$sPlay6,$sPlay7,$sPlay8

$arr = StringSplit(_Random(0,16,8), ';', 2)
; присвоение значения переменным
For $i = 0 To UBound($arr)-1
	Assign("sPlay" & ($i+1), $arr[$i])
Next

; вывод на консоль значений переменнх
For $i = 0 To UBound($arr)-1
	ConsoleWrite('$sPlay' & ($i+1) & '=' & Eval('sPlay' & ($i+1)) & @CRLF)
Next

Func _Random($min, $max, $count)
	Local $i, $nums, $rnd, $ret

	If $count > $max - $min + 1 Then Return SetError(1,0,0)

	$nums = _StringRepeat(' ', $max-$min+1)

	For $i = 0 To $count-1
		Do
			$rnd = Random($min, $max, 1)
		Until StringMid($nums, $rnd-$min+1, 1) = ' '
		$nums = StringLeft($nums, $rnd-$min) & '-' & StringMid($nums,$rnd-$min+2)
		$ret = $ret & $rnd & ';'
	Next

	Return StringTrimRight($ret, 1)
EndFunc
 
Автор
Isn

Isn

Новичок
Сообщения
119
Репутация
3
Спасибо за ответы.
 

snoitaleR

AutoIT Гуру
Сообщения
855
Репутация
223
Ещё вариант:
Код:
#Include <Array.au3>

 Global $COUNT=1000
 Global $RND[$COUNT+1]
 For $J=1 To $COUNT
  $RND[$J]=$J
 Next
 $J=$COUNT-1
 While $J>1
  $U=Random(0,$J)
  $K=Floor($U)+1
  $T=$RND[$K]
  $RND[$K]=$RND[$J]
  $RND[$J]=$T
  $J-=1
 WEnd
 _ArrayDisplay($RND)
 

AZJIO

Меценат
Меценат
Сообщения
2,879
Репутация
1,194
Мой вариант
Код:
#include <Array.au3> ; для _ArrayDisplay

$aRnd = _RandList(16) ; Число элементов
_ArrayDisplay($aRnd) ; Просмотр

Func _RandList($iCount)
	Local $aRnd[$iCount + 1], $aRes[$iCount + 1], $j

	For $i = 0 To $iCount ; Формирование массива, из которого брать числа
		$aRnd[$i] = $i
	Next
	; $aRnd[16] = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16] ; Получаем такой вот массив

	For $i = 0 To $iCount ; Формирование результата
		$j = Random(0, $iCount, 1) ; Номер ячейки массива, от которой начинать поиск вниз
		Do ; Цикл должен быть выверенным чтобы не зависнуть в нём
			$j += 1
			If $j > $iCount Then $j = 0 ; Сбрасываем в 0 чтобы искать от начала
		Until $aRnd[$j] <> -1 ; Если ячейка не ноль, прекращаем поиск
		$aRes[$i] = $aRnd[$j] ; Записываем найденное врезультат
		$aRnd[$j] = -1 ; Сбрасываем значение, исключая его из поиска
	Next
	Return $aRes ; Возвращаем результат
EndFunc   ;==>_RandList


_Random()
;---------------------------------------------------------------------------------------------
Func _Random()
    For $i = 100 To 1 Step -1
        Sleep(100)
		$aRnd = _RandList(16)
        _Func1($aRnd)
    Next
EndFunc
;---------------------------------------------------------------------------------------------
Func _Func1($aRnd)
    $sPlay1 = $aRnd[0]
    $sPlay2 = $aRnd[1]
    $sPlay3 = $aRnd[2]
    $sPlay4 = $aRnd[3]
    $sPlay5 = $aRnd[4]
    $sPlay6 = $aRnd[5]
    $sPlay7 = $aRnd[6]
    $sPlay8 = $aRnd[7]
	MsgBox(0, 'Сообщение', _
	$sPlay1 & @LF & _
	$sPlay2 & @LF & _
	$sPlay3 & @LF & _
	$sPlay4 & @LF & _
	$sPlay5 & @LF & _
	$sPlay6 & @LF & _
	$sPlay7 & @LF & _
	$sPlay8)
EndFunc
;---------------------------------------------------------------------------------------------
 
Верх