Что нового

Работа с Массивом данных помогите построить логику

gergerger111

Новичок
Сообщения
17
Репутация
0
Есть 1 таблица с Именами, Очками которые должны быть, очки которые получилось заработать.

Разделено все табуляцией (есть как ТХТ формат так и EXCEL)

Имена Очки(Должны быть) Очки(По факту)

Ваня 10 5
Петя 6 10
Стёпа 4 6
Маша 4 3

По нашей таблице
Мы видим что Ваня заработал на 5 очков меньше чем должен был
И
Маша заработала на 2 очка меньше чем должна была
Нам нужно компенсировать это.
Поэтому мы берём очки у Стёпы который заработал на 1 очко больше чем должен был
И у Пети который заработал на 4 очка чем должен был
И у Стёпы который заработал на 2 очка больше чем должен был
Эти 6 очков распределяются между Ваней и Машей
Ваня получает 4 очка от Пети (У Пети остаётся 0 очков, но Ване нужно еще 1 очко)
Это 1 очко он берёт у Стёпы (У Стёпы остаётся 1 очко)
Маша получает оставшееся 1 очко у Стёпы.
Баланс восстановлен.
(Бывает что очков слишком много и они остаются, а бывает что очков будет не хватать на всех и их надо распределить поровну)

Думаю задачу описал полностью
Если, что то не донёс или не хватает вводных пишите
с AutoIT работаю (4 месяца), пока знаний не хватает для решения задачи.
Буду рад любой помощи.
 

hedji

Продвинутый
Сообщения
409
Репутация
94
OffTopic:
Если после всех манипуляций мы просто получаем левую колонку "должны быть" и пишем её в правую, то зачем вся движуха?
 
A

Alofa

Гость
gergerger111 сказал(а):
...
Ваня 10 5
Петя 6 10
...
... Логика будет такой
Ваня --->>> Пете 4 очка...
Странная логика :scratch: (или может моя страдает).
И потом, если отдавать, то отдавать в какую колонку?
 

joiner

Модератор
Локальный модератор
Сообщения
3,556
Репутация
628
OffTopic:
в стол заказов.
или изучать язык полностью
 

mr.Gbabak

Осваивающий
Сообщения
257
Репутация
23
gergerger111 [?]
Стёпа и Петя, должны отдать разницу тем кто по факту выиграл очков меньше,
не понятно почему тогда
1) Ваня отдает Пете и Маше ?
2) Почему Ваня отдает Пете именно 4 очка, а Маше 1
3) Почему если Петя и Степа заработали больше ожидаемого, то Петя получает очки, а Степа теряет?
 
Автор
G

gergerger111

Новичок
Сообщения
17
Репутация
0
mr.Gbabak сказал(а):
gergerger111 [?]
Стёпа и Петя, должны отдать разницу тем кто по факту выиграл очков меньше,
не понятно почему тогда
1) Ваня отдает Пете и Маше ?
2) Почему Ваня отдает Пете именно 4 очка, а Маше 1
3) Почему если Петя и Степа заработали больше ожидаемого, то Петя получает очки, а Степа теряет?

Прошу прощения ошибся в логике.

И в таблице так же ошибся =(

Вот:

Имена Очки(Должны быть) Очки(По факту)

Ваня 10 5
Петя 6 10
Стёпа 4 6
Маша 4 3

По нашей таблице
Мы видим что Ваня заработал на 5 очков меньше чем должен был
И
Маша заработала на 2 очка меньше чем должна была
Нам нужно компенсировать это.
Поэтому мы берём очки у Стёпы который заработал на 1 очко больше чем должен был
И у Пети который заработал на 4 очка чем должен был
И у Стёпы который заработал на 2 очка больше чем должен был
Эти 6 очков распределяются между Ваней и Машей
Ваня получает 4 очка от Пети (У Пети остаётся 0 очков, но Ване нужно еще 1 очко)
Это 1 очко он берёт у Стёпы (У Стёпы остаётся 1 очко)
Маша получает оставшееся 1 очко у Стёпы.
Баланс восстановлен.
(Бывает что очков слишком много и они остаются, а бывает что очков будет не хватать на всех и их надо распределить поровну)


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

hedji сказал(а):
OffTopic:
Если после всех манипуляций мы просто получаем левую колонку "должны быть" и пишем её в правую, то зачем вся движуха?

Мы должны получить таблицу кто кому должен отправить Очки
В Любом формате хоть в тхт:
Стёпа --->>> 1 очко Ване
Стёпа --->>> 1 очко Маше


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

Alofa сказал(а):
gergerger111 сказал(а):
...
Ваня 10 5
Петя 6 10
...
... Логика будет такой
Ваня --->>> Пете 4 очка...
Странная логика :scratch: (или может моя страдает).
И потом, если отдавать, то отдавать в какую колонку?

Это хороший вопрос я думаю для наглядности можно создать 3 колонку (массив)
В котором будет результирующее кол-во очков у каждого человека
В нашем случае это будет выглядеть так :

Имена Очки(Должны быть) Очки(По факту) Очков(после оптимизации)
Ваня 10 5 10
Петя 6 10 6
Стёпа 4 6 4
Маша 4 3 4

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

gunter123

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

Local $aValues = [['Ваня', 10, 5], _
				  ['Петя', 6, 10], _
				  ['Стёпа', 4, 6], _
				  ['Маша', 4, 3]]	; Двумерный массив с данными

Local $iMore = -1, $iLess = -1 ; Переменные: $iMore - слишком много, $iLess - слишком мало
_ArrayDisplay($aValues)

For $i = 0 To UBound($aValues) -1
   If $aValues[$i][1] = $aValues[$i][2] Then
	  ContinueLoop
   ElseIf ($aValues[$i][1] < $aValues[$i][2] AND $iMore = -1) Then	; Если набрано слишком много очков и такой участник еще не был найден, запоминаем индекс в переменную $iMore
	  $iMore = $i
	  ConsoleWrite($aValues[$i][0] & ' - слишком много, ')
   ElseIf ($iLess = -1) Then										; Если слишком мало - в переменную $iLess
	  $iLess = $i
	  ConsoleWrite($aValues[$i][0] & ' - слишком мало, ')
   EndIf

   If $iMore <> -1 AND $iLess <> -1 Then			; Если есть участники у которых слишком много и слишком мало очков...
	  If ($aValues[$iLess][1] - $aValues[$iLess][2]) >= ($aValues[$iMore][2]) Then	; Проверяем, может ли тот у кого больше отдать все очки тому у кого меньше
		 $iTemp = $aValues[$iLess][1] - $aValues[$iLess][2]
	  Else																			; Если не может, тогда просто пусть отдаст излишек
		 $iTemp = $aValues[$iMore][2] - $aValues[$iMore][1]
	  EndIf
	  $aValues[$iMore][2] -= $iTemp													; Отдаем очки тому кому надо
	  $aValues[$iLess][2] += $iTemp
	  ConsoleWrite($aValues[$iMore][0] & ' --> ' & $aValues[$iLess][0] & ' ' & $iTemp & @CRLF)
	  $i = -1																		; Начинаем весь цикл сначала
	  $iMore = -1
	  $iLess = -1
   EndIf
Next

_ArrayDisplay($aValues)
 
Автор
G

gergerger111

Новичок
Сообщения
17
Репутация
0
gunter123 сказал(а):
Вот:
Код:
#include <Array.au3>

Local $aValues = [['Ваня', 10, 5], _
				  ['Петя', 6, 10], _
				  ['Стёпа', 4, 6], _
				  ['Маша', 4, 3]]	; Двумерный массив с данными

Local $iMore = -1, $iLess = -1 ; Переменные: $iMore - слишком много, $iLess - слишком мало
_ArrayDisplay($aValues)

For $i = 0 To UBound($aValues) -1
   If $aValues[$i][1] = $aValues[$i][2] Then
	  ContinueLoop
   ElseIf ($aValues[$i][1] < $aValues[$i][2] AND $iMore = -1) Then	; Если набрано слишком много очков и такой участник еще не был найден, запоминаем индекс в переменную $iMore
	  $iMore = $i
	  ConsoleWrite($aValues[$i][0] & ' - слишком много, ')
   ElseIf ($iLess = -1) Then										; Если слишком мало - в переменную $iLess
	  $iLess = $i
	  ConsoleWrite($aValues[$i][0] & ' - слишком мало, ')
   EndIf

   If $iMore <> -1 AND $iLess <> -1 Then			; Если есть участники у которых слишком много и слишком мало очков...
	  If ($aValues[$iLess][1] - $aValues[$iLess][2]) >= ($aValues[$iMore][2]) Then	; Проверяем, может ли тот у кого больше отдать все очки тому у кого меньше
		 $iTemp = $aValues[$iLess][1] - $aValues[$iLess][2]
	  Else																			; Если не может, тогда просто пусть отдаст излишек
		 $iTemp = $aValues[$iMore][2] - $aValues[$iMore][1]
	  EndIf
	  $aValues[$iMore][2] -= $iTemp													; Отдаем очки тому кому надо
	  $aValues[$iLess][2] += $iTemp
	  ConsoleWrite($aValues[$iMore][0] & ' --> ' & $aValues[$iLess][0] & ' ' & $iTemp & @CRLF)
	  $i = -1																		; Начинаем весь цикл сначала
	  $iMore = -1
	  $iLess = -1
   EndIf
Next

_ArrayDisplay($aValues)

Отличная работа, спасибо больше, но не хватает 1 условия
Стёпа отдаёт Ване сразу 2 очка хотя Ване нужно только 1 очко
В связи с чем далее Ваня отдаёт не нужное ему очко Маше.

Можно ли сделать так, что те кому очки необходимы не участвовали в отдаче очков, а только принимали их.
 

gunter123

Продвинутый
Сообщения
159
Репутация
69
Да, как-то не заметил этого. Вот, теперь будет отдаваться меньшее из двух: сколько надо отдать или сколько возможно отдать. Насчет равномерного распределения пока не знаю, может позже напишу :smile:
Код:
#include <Array.au3>

Local $aValues = [['Ваня', 10, 5], _
                  ['Петя', 6, 10], _
                  ['Стёпа', 4, 6], _
                  ['Маша', 4, 3]]   ; Двумерный массив с данными

Local $iMore = -1, $iLess = -1 ; Переменные: $iMore - слишком много, $iLess - слишком мало
_ArrayDisplay($aValues)

For $i = 0 To UBound($aValues) -1
   If ($aValues[$i][1] < $aValues[$i][2] AND $iMore = -1) Then  ; Если набрано слишком много очков и такой участник еще не был найден, запоминаем индекс в переменную $iMore
      $iMore = $i
      ConsoleWrite($aValues[$i][0] & ' - слишком много, ')
   ElseIf ($aValues[$i][1] > $aValues[$i][2] AND $iLess = -1) Then  ; Если слишком мало - в переменную $iLess
      $iLess = $i
      ConsoleWrite($aValues[$i][0] & ' - слишком мало, ')
   EndIf

   If $iMore <> -1 AND $iLess <> -1 Then            ; Если есть участники у которых слишком много и слишком мало очков...
      If ($aValues[$iLess][1] - $aValues[$iLess][2]) < ($aValues[$iMore][2] - $aValues[$iMore][1]) Then
		 $iTemp = $aValues[$iLess][1] - $aValues[$iLess][2]
	  Else
		 $iTemp = $aValues[$iMore][2] - $aValues[$iMore][1]
	  EndIf
	  $aValues[$iMore][2] -= $iTemp                                                 ; Отдаем очки тому кому надо
      $aValues[$iLess][2] += $iTemp
      ConsoleWrite($aValues[$iMore][0] & ' --> ' & $aValues[$iLess][0] & ' ' & $iTemp & @CRLF)
      $i = -1                                                                       ; Начинаем весь цикл сначала
      $iMore = -1
      $iLess = -1
   EndIf
Next

_ArrayDisplay($aValues)

Упростил условие в начале цикла, заодно исправил ошибку в нём.
 
Автор
G

gergerger111

Новичок
Сообщения
17
Репутация
0
gunter123 сказал(а):
Да, как-то не заметил этого. Вот, теперь будет отдаваться меньшее из двух: сколько надо отдать или сколько возможно отдать. Насчет равномерного распределения пока не знаю, может позже напишу :smile:
Код:
#include <Array.au3>

Local $aValues = [['Ваня', 10, 5], _
                  ['Петя', 6, 10], _
                  ['Стёпа', 4, 6], _
                  ['Маша', 4, 3]]   ; Двумерный массив с данными

Local $iMore = -1, $iLess = -1 ; Переменные: $iMore - слишком много, $iLess - слишком мало
_ArrayDisplay($aValues)

For $i = 0 To UBound($aValues) -1
   If $aValues[$i][1] = $aValues[$i][2] Then
      ContinueLoop
   ElseIf ($aValues[$i][1] < $aValues[$i][2] AND $iMore = -1) Then  ; Если набрано слишком много очков и такой участник еще не был найден, запоминаем индекс в переменную $iMore
      $iMore = $i
      ConsoleWrite($aValues[$i][0] & ' - слишком много, ')
   ElseIf ($iLess = -1) Then                                        ; Если слишком мало - в переменную $iLess
      $iLess = $i
      ConsoleWrite($aValues[$i][0] & ' - слишком мало, ')
   EndIf

   If $iMore <> -1 AND $iLess <> -1 Then            ; Если есть участники у которых слишком много и слишком мало очков...
      If ($aValues[$iLess][1] - $aValues[$iLess][2]) < ($aValues[$iMore][2] - $aValues[$iMore][1]) Then
		 $iTemp = $aValues[$iLess][1] - $aValues[$iLess][2]
	  Else
		 $iTemp = $aValues[$iMore][2] - $aValues[$iMore][1]
	  EndIf
	  $aValues[$iMore][2] -= $iTemp                                                 ; Отдаем очки тому кому надо
      $aValues[$iLess][2] += $iTemp
      ConsoleWrite($aValues[$iMore][0] & ' --> ' & $aValues[$iLess][0] & ' ' & $iTemp & @CRLF)
      $i = -1                                                                       ; Начинаем весь цикл сначала
      $iMore = -1
      $iLess = -1
   EndIf
Next

_ArrayDisplay($aValues)

Спасибо большое. Умный человек вы гений !
 
Верх