Что нового

Изменение значений массива с конца в начало

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Что - то я совсем запутался, имеется одномерный массив (его размер может быть разным)

Код:
$Array[6] = [0, 0, 0, 0, 0, 0]


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

Код:
$Array[6] = [0, 0, 0, 0, 0, 1]


и так допустим до максимального значения например 10, если последнее значение массива достигает заданного максимального числа, то при следующем вызове, оно должно обнулится, а предыдущее увеличится на 1

Код:
$Array[6] = [0, 0, 0, 0, 0, 10]
;~ После следующего вызова
$Array[6] = [0, 0, 0, 0, 1, 0]


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

Код:
$Array[6] = [10, 10, 10, 10, 10, 10]


Весь день просидел над этой задачкой, так и не смог решить :scratch:
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Задачка сгодилась бы как конкурс :whistle:

Код:
#include <Array.au3>

Global $aArray[6] = [0, 0, 0, 0, 0, 0]

For $i = 0 To UBound($aArray)-1
	For $j = 1 To 10
		_ArraySetLastElement($aArray)
		
		If ($i+1)*$j = 60 Then
			ExitLoop 2
		EndIf
	Next
	
	_ArrayDisplay($aArray)
Next

_ArrayDisplay($aArray)
_ArraySetLastElement($aArray)
_ArrayDisplay($aArray)

Func _ArraySetLastElement(ByRef $aArray, $iMaxVal = 10)
	For $i = UBound($aArray)-1 To 0 Step -1
		If $aArray[$i] < $iMaxVal Then
			If $aArray[$i] = 0 Then
				For $j = 0 To $i - 1
					If $aArray[$j] <> 0 Then
						ContinueLoop 2
					EndIf
				Next
			EndIf
			
			$aArray[$i] += 1
			ExitLoop
		Else
			$aArray[$i] = 0
		EndIf
	Next
EndFunc
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Да уж, тяжёлая задачка, но не совсем то, предположим в массиве 6 значений, когда 6-е значение доходит до максимального, то в 5-е прибавляется 1, а 6-е сбрасывается на ноль

Код:
$aArray[6] = [0, 0, 0, 0, 0, 10]
;~ Следующий вызов
$aArray[6] = [0, 0, 0, 0, 1, 0]
;~ Следующий вызов
$aArray[6] = [0, 0, 0, 0, 1, 1]
;~ Следующий вызов
$aArray[6] = [0, 0, 0, 0, 1, 2]
....
;~ Следующий вызов
$aArray[6] = [0, 0, 0, 0, 1, 10]
;~ Следующий вызов
$aArray[6] = [0, 0, 0, 0, 2, 0]
....
;~ Следующий вызов
$aArray[6] = [0, 0, 0, 3, 8, 4]
;~ Следующий вызов
$aArray[6] = [0, 0, 0, 3, 8, 5]


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

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Viktor1703 [?]
и так пока во всех ячейках не будет максимального значения, то есть идёт нарост с конца на перёд.
Что то не сходится. Если мы обнуляем предыдущее значение (достигнувшее макс.), то почему при следующем вызове оно должно увеличиться?
И как получается прыжок с «0, 2, 0» на «3, 8, 4»?
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Вообщем такая структура получается

Код:
000000
000001
000002
....
0000010
000010
000011
000012
....
0000110
000020
000021
000022
000023
....
0000210
000030
000031
...
...
000100
000101
000102

Если бы была такая структура

Код:
000001
000002
....
0000010
0000110
0000210
....
00001010
00011010

То я бы справился сам, а тут нужно всегда менять значение от 0 до 10 в зависимости от того что в следующем, если в следующем ещё не 10 то оно увеличивается на 1 предыдущее остаётся таким же, если же следующее достигло 10 то сбрасываем на 0 (ноль) а в предыдущее добавляем 1, мне кажется без особых извратов тут не обойтись...

И как получается прыжок с «0, 2, 0» на «3, 8, 4»?

Прыжок не получается, я там отметил "..." чтоб не писать всё полностью, могу полностью написать весь цикл работы, чтоб понятнее было как изменяются значения, получается что - то вроде часов где минутная стрелка увеличивается на 1 только тогда, когда секундная равна 60, а потом всё по новой.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Кажется понял...

Код:
#include <Array.au3>

Global $aArray[6] = [0, 0, 0, 0, 0, 0]

For $i = 1 To (10 * 10 * 8)
	_ArraySetLastElement($aArray)
	If @error Then ExitLoop
	
	If Mod($i, 80) = 0 Then _ArrayDisplay($aArray)
Next

Func _ArraySetLastElement(ByRef $aArray, $iMaxVal = 10)
	If $aArray[0] = $iMaxVal And $aArray[UBound($aArray)-1] = $iMaxVal Then
		Return SetError(1)
	EndIf
	
    For $i = UBound($aArray)-1 To 0 Step -1
		If $aArray[$i] = $iMaxVal Then
			$aArray[$i] = 0
			
			Do
				$i -= 1
				If $i < 0 Then ExitLoop 2
			Until $aArray[$i] <> $iMaxVal
		EndIf
		
		$aArray[$i] += 1
		ExitLoop
    Next
EndFunc
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Да, почти :smile: только в Вашем примере получается что когда последняя ячейка достигает 10 то 5-я увеличивается на 1 - это правильно, но когда 5-я достигает 10 и 4-я увеличивается на 1 то в 5-й не сбрасывается на ноль, то есть у Вас получается так

Код:
$aArray[6] = [0, 0, 0, 2, 10, 1]


а должно быть

Код:
$aArray[6] = [0, 0, 0, 2, 0, 1]


Как часы, возьмём массив размером 3 (тройка)

Код:
$aArray[6] = [0, 0, 0]


1я ячейка - это часовая стрелка
2я минутная
3я секундная

что бы получить 1 минуту, нужно 60 секунд, потом секунды сбрасываются на ноль
что бы получить 1 часовую, нужно 60 минутных, потом минуты сбрасываются на ноль

а конец времени - это наше максимальное значение, возьмём например 24

массив не будет полным если в 1й < 24, во 2й = 24 и в 3й = 24
массив не будет полным если в 1й = 24, во 2й < 24 и в 3й < 24
массив не будет полным если в 1й = 24, во 2й = 24 и в 3й < 24
массив будет полным если в 1й = 24, во 2й = 24 и в 3й = 24
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
Viktor1703 [?]
Ну это уже другая постановка задачи, ведь было сказано:
[?]
И так должно тикать пока все значения массива не достигнут максимального числа

[?]
Проще сделать так:
Код:
#include <Array.au3>

Global $aArray[6] = [0, 0, 0, 3, 9, 5]

For $i = 1 To 6
	_ArrayIncreaseTicks($aArray)
	_ArrayDisplay($aArray)
Next

Func _ArrayIncreaseTicks(ByRef $aArray, $iMaxVal = 10)
	$sVal = ''
	
	For $i = 0 To UBound($aArray)-1
		$sVal &= $aArray[$i]
    Next
	
	$iVal = ($sVal+1)
	$sVal = StringFormat('%0' & (UBound($aArray)) & 'i', $iVal)
	$aArray = StringRegExp($sVal, '(.)', 3)
EndFunc


но это только для 10-тичных значений, как сделать меньше пока не разобрался, мозг уже вскипел :stars:.
 

CreatoR

Must AutoIt!
Команда форума
Администратор
Сообщения
8,671
Репутация
2,481
«Все гениальное — просто!» :laugh:

Код:
#include <Array.au3>

Global $aArray[3] = [3, 5, 4]

For $i = 1 To 50
	_ArrayIncreaseTicks($aArray, 6)
	_ArrayDisplayToConsole($aArray)
	If Mod($i, 5) = 0 Then _ArrayDisplay($aArray)
Next

Func _ArrayIncreaseTicks(ByRef $aArray, $iMaxVal = 10)
	For $i = UBound($aArray)-1 To 0 Step -1
		$aArray[$i] += 1
		
		If $aArray[$i] >= $iMaxVal Then
			$aArray[$i] = 0
		Else
			ExitLoop
		EndIf
    Next
EndFunc

Func _ArrayDisplayToConsole($aArray)
	Local $sData = ''
	
	For $i = 0 To UBound($aArray)-1
		$sData &= $aArray[$i] & '|'
	Next
	
	ConsoleWrite(StringTrimRight($sData, 1) & @LF)
EndFunc
 
Автор
V

Viktor1703

AutoIT Гуру
Сообщения
1,535
Репутация
413
Спасибо, что - то сильно просто получилось ;D я думал извраты точно будут.
 
Верх