Isso é apenas um truque, mas você fica perto
Apenas 3 refeições
Você basicamente fracassa nas refeições se isso aproxima os dois dias da média de C #
Uma abordagem melhor seria retornar um boolen no Flop e iterar até a conclusão.
Flop pode ficar mais esperto. Você pode não tomar café da manhã no almoço e jantar. Talvez haja permutações de código rígido. Isso é mais como uma classificação em que os valores de flop, em vez de classificação.
public static void MealEven()
{
List<Day> Days = new List<Day>();
Random rnd = new Random();
decimal sum = 0;
for(int i = 0; i<7; i ++)
{
int b = rnd.Next(100) + 40;
int l = rnd.Next(100) + 60;
int d = rnd.Next(100) + 80;
Meal br = new Meal(enumMeal.b, b);
Meal lu = new Meal(enumMeal.l, l);
Meal di = new Meal(enumMeal.d, d);
Day day = new Day(br, lu, di);
Days.Add(day);
sum += day.Calories;
}
decimal avg = sum / 7;
foreach (Day d in Days.OrderBy(x => x.Calories))
System.Diagnostics.Debug.WriteLine(d.Calories);
System.Diagnostics.Debug.WriteLine("");
Day low;
Day high;
Day lowLast = null;
Day highLast = null;
int count = 0;
while (true)
{ // first do high and low
low = Days.OrderBy(x => x.Calories).FirstOrDefault();
high = Days.OrderByDescending(x => x.Calories).FirstOrDefault();
if (lowLast != null && lowLast == low && highLast == high)
break;
if (count > 1000)
break;
lowLast = low;
highLast = high;
count++;
Flop(ref high, ref low);
}
foreach (Day d in Days.OrderBy(x => x.Calories))
System.Diagnostics.Debug.WriteLine("{0} {1} {2} {3}", d.Calories, d.B.Calories, d.L.Calories, d.D.Calories);
System.Diagnostics.Debug.WriteLine("");
// day a one on one pass
for (int i = 0; i < 7; i ++)
{
for (int j = 0; j < 7; j++)
{
if (i == j)
continue;
Day d1 = Days[i];
Day d2 = Days[j];
Flop(ref d1, ref d2);
}
}
foreach (Day d in Days.OrderBy(x => x.Calories))
System.Diagnostics.Debug.WriteLine("{0} {1} {2} {3}", d.Calories, d.B.Calories, d.L.Calories, d.D.Calories);
System.Diagnostics.Debug.WriteLine("");
}
public static void Flop (ref Day high, ref Day low)
{
if(low.Calories > high.Calories)
{
int hold = low.B.Calories;
low.B.Calories = high.B.Calories;
high.B.Calories = hold;
hold = low.L.Calories;
low.L.Calories = high.L.Calories;
high.L.Calories = hold;
hold = low.D.Calories;
low.D.Calories = high.D.Calories;
high.D.Calories = hold;
}
decimal avg = (low.Calories + high.Calories) / (decimal)2;
int bDiff = (high.B.Calories - low.B.Calories) < 0 ? 0 : (high.B.Calories - low.B.Calories);
int lDiff = high.L.Calories - low.L.Calories < 0 ? 0 : (high.L.Calories - low.L.Calories);
int dDiff = high.D.Calories - low.D.Calories < 0 ? 0 : (high.D.Calories - low.D.Calories);
// only flop is one does not go past the average
if (bDiff > 0 && ((low.Calories + bDiff) < avg || (high.Calories - bDiff) > avg))
{
int hold = low.B.Calories;
low.B.Calories = high.B.Calories;
high.B.Calories = hold;
}
if (lDiff > 0 && ((low.Calories + lDiff) < avg || (high.Calories - lDiff) > avg))
{
int hold = low.L.Calories;
low.L.Calories = high.L.Calories;
high.L.Calories = hold;
}
if (dDiff > 0 && ((low.Calories + dDiff) < avg || (high.Calories - dDiff) > avg))
{
int hold = low.D.Calories;
low.D.Calories = high.D.Calories;
high.D.Calories = hold;
}
}
public enum enumMeal {b, l, d};
public class Day
{
public Meal B { get; set; }
public Meal L { get; set; }
public Meal D { get; set; }
public Decimal Calories { get { return (Decimal)(B.Calories + L.Calories + D.Calories); } }
public Day (Meal b, Meal l, Meal d )
{
B = b;
L = l;
D = d;
}
}
public class Meal
{
public enumMeal Type { get; set; }
public int Calories { get; set; }
public Meal (enumMeal meal, int calories)
{
Type = meal;
Calories = calories;
}
}