https://foro.gambas-es.org/viewtopic.php?f=15&t=4509&p=25837#p25837
-----------------------------------
jsbsan
Martes, 14 Abril 2015, 19:49

Re: Asado Entre Amigos
-----------------------------------
Osunaosuna:

Te adjunto mi solución. Lo que he hecho es "modelizar" la situación como si fuera real, y he pensado como se resolvería entre un grupo de amigos.

Osea:
La persona que no ha comprado nada de comida o bebida, tiene un saldo "positivo", que sabe que tiene que repartir entres las que tenga un saldo negativo.
Las personas que han comprado algo, pero tiene un valor de menos de 64 euros, tiene un saldo positivo (pero menor) y sabe que lo tiene que dar a las personas con saldo negativo.

Las personas que han comprado algo, pero su valor es mayor que 64 euros, tienen un saldo negativo, y solo pueden recibir dinero.

El objetivo es que el saldo de todas las personas quede a 0.


Para programar esto lo que uso es una clase persona, que incluye su nombre, dinero inicialmente gastado, comida que aporta y varias propiedades, entre ella el saldo.


Es saldo  para cada persona se calcula asi: 
  personaTemporal.saldo = cantidadRepartir - personaTemporal.PagadoInicialmente

Y el algoritmo que he hecho, se encarga de si la persona tiene saldo, lo reparte al que tenga un saldo negativo. (osea le debemos entre todos).
y va informando de como se va haciendo el reparto en un textarea.


 [img]http://foro.gambas-es.org/files/images/6/reparto_del_asado.png[/img] 

Como ves mi solución difere en la tuya, porque el sistema tiene varias soluciones de reparto.

He hecho que recorra dos veces el bucle, pero pienso que para optimizarlo, se debieran ordenar las personas, en orden decreciente de saldo, osea los que tengan dinero "a repartir" primero y los últimos los que tengan saldo negativo (dinero a recibir), así solo se recorrería el bucle una vez.


[code linenumbers=false syntax=gambas]Public Sub repiteReparto()

  Dim b As Integer
  Dim a As Integer
  Dim cantidad As Float
  Dim personaTemporal As Persona
  Dim personaTemporalArepartir As Persona

  For b = 0 To (ArrayPersonas.count - 1)

    personaTemporal = ArrayPersonas[b]

    For a = 0 To ArrayPersonas.count - 1
      personaTemporalArepartir = ArrayPersonas[a]

      'es distinta persona?
      If personaTemporal = personaTemporalArepartir Then
        Continue
      Else
        'si tiene saldo negativo, y tengo dinero en mi saldo
        If personaTemporalArepartir.saldo <0> 0 Then
          'le doy dinero
          'cuanto le doy?
          'lo que le puedo dar es la cantidad de mi saldo: personaTemporal.saldo
          If (personaTemporalArepartir.saldo + personaTemporal.saldo) < 0 Then
            cantidad = personaTemporalArepartir.saldo + personaTemporal.saldo
            personaTemporalArepartir.saldo = cantidad
            TextAreaInforme.Text &= personaTemporal.nombre & " le da a " & personaTemporalArepartir.nombre & " la cantidad de: $" & Str$(personaTemporal.saldo) & "\n"
            personaTemporal.saldo = 0 'lo doy todo
          Else
            If (personaTemporalArepartir.saldo + personaTemporal.saldo) > 0 Then
              cantidad = personaTemporalArepartir.saldo + personaTemporal.saldo

              TextAreaInforme.Text &= personaTemporal.nombre & " le da a " & personaTemporalArepartir.nombre & " la cantidad de: $" & Str$(- personaTemporalArepartir.saldo) & "\n"
              personaTemporalArepartir.saldo = 0
              personaTemporal.saldo = cantidad
            Else
              If personaTemporalArepartir.saldo + personaTemporal.saldo = 0 Then

                TextAreaInforme.Text &= personaTemporal.nombre & " le da a " & personaTemporalArepartir.nombre & " la cantidad de: $" & Str$(personaTemporal.saldo) & "\n"
                personaTemporalArepartir.saldo = 0
                personaTemporal.saldo = 0
              Endif

            Endif

          Endif
        Endif

      Endif
    Next

  Next

End[/code]


