Fajne zadanie, wczoraj wieczor mi zniszczylo ;)
Na razie robie to tak ze upycham na statek rodziny dopóki starcza miejsca dla calej, potem szukam algorytmu ktory w skrocie zobaczy ile jeszcze jest miejsc wolnych i posprawdza czy mozna popodmieniac rodziny.
np. zostalo 1 miejsce, wiec wypatruje z zapakowanych rodzine np.5osobowa i szukam czy w tych pozostawionych jest jakas 6osobowa ewentualnie czy są wsrod pozostawionych jakies rodziny ktorych suma daje 6osob. jezeli tak podmieniam
i ten algorytm mnie juz wczoraj wieczorem wymeczyl ;) moze ktos cos podpowie jak to zrobic na petlach - tak slowami. /ten swoj algorytm podmieniajacy wycialem, tu go nie ma - dla lepszej czytelnosci/
Do tej pory mam to:
Kod okna:
public partial class Form1 : Form
{
private Random rnd = new Random();
private Upychacz pakowacz;
private int zadanaPojemnoscStatku;
private int zadanaLiczbaRodzin;
private List<Rodzina> listaRodzinDoWejscia;
private List<Rodzina> listaRodzinNaPokladzie;
private List<Rodzina> listaRodzinaPozostawionych;
private BindingSource bs_RodzinWej = new BindingSource();
private BindingSource bs_RodzinNaPokladzie = new BindingSource();
private BindingSource bs_RodzinPozostawionych = new BindingSource();
public Form1()
{
InitializeComponent();
listaRodzinDoWejscia = new List<Rodzina>();
listaRodzinNaPokladzie = new List<Rodzina>();
listaRodzinaPozostawionych = new List<Rodzina>();
bs_RodzinWej.DataSource = listaRodzinDoWejscia;
}
private void btn_GenerujRodziny_Click(object sender, EventArgs e)
{
WyczyscStanAplikacji();
int.TryParse(txtB_rodzinDoWejscia.Text, out zadanaLiczbaRodzin);
for (int i = 0; i < zadanaLiczbaRodzin; i++)
listaRodzinDoWejscia.Add(new Rodzina(rnd.Next(2,9)));
WyswietlPodsumowanieRodzinNaWejsciu();
}
private void WyswietlPodsumowanieRodzinNaWejsciu()
{
lBox_RodzinyWPorcie.DataSource = bs_RodzinWej;
bs_RodzinWej.ResetBindings(false);
int liczbaOsob = 0;
foreach (var item in listaRodzinDoWejscia)
liczbaOsob += item.LiczbaOsobWRodzinie;
lbl_OsobDoWejscia.Text = $"Łącznie {liczbaOsob} osób.";
}
private void btn_UstalPojemnoscstatku_Click(object sender, EventArgs e)
{
int.TryParse(txtB_PojemnoscStatku.Text, out zadanaPojemnoscStatku);
label1.Text = $"Pojemnosc Statku: {zadanaPojemnoscStatku}osób";
}
private void btn_ZapakujNaStatek_Click(object sender, EventArgs e)
{
pakowacz = new Upychacz(zadanaPojemnoscStatku, listaRodzinDoWejscia);
listaRodzinNaPokladzie = pakowacz.Zapakowani.OrderBy((x) => x.Nazwa).ToList();
listaRodzinaPozostawionych = pakowacz.Pozostawieni.OrderBy((x) => x.Nazwa).ToList();
WyswietlPodsumowanieZapakowania();
}
private void WyswietlPodsumowanieZapakowania()
{
bs_RodzinNaPokladzie.DataSource = listaRodzinNaPokladzie;
lBox_RodzinyNaStatku.DataSource = bs_RodzinNaPokladzie;
bs_RodzinNaPokladzie.ResetBindings(false);
int osobNaPokladzie = 0;
foreach (var item in listaRodzinNaPokladzie)
osobNaPokladzie += item.LiczbaOsobWRodzinie;
lbl_OsobNaStatku.Text = $"Łącznie {osobNaPokladzie} osob na statku.";
bs_RodzinPozostawionych.DataSource = listaRodzinaPozostawionych;
lBox_RodzinyKtoreNieWeszly.DataSource = bs_RodzinPozostawionych;
bs_RodzinPozostawionych.ResetBindings(false);
int osobPozostawionych = 0;
foreach (var item in listaRodzinaPozostawionych)
osobPozostawionych += item.LiczbaOsobWRodzinie;
lbl_OsobPozostawionych.Text = $"Nie weszło łącznie {osobPozostawionych} osób.";
}
private void WyczyscStanAplikacji()
{
listaRodzinDoWejscia.Clear();
lbl_OsobDoWejscia.Text = $"Łącznie X osób.";
listaRodzinaPozostawionych.Clear();
lbl_OsobPozostawionych.Text = $"Nie weszło łącznie X osób.";
listaRodzinNaPokladzie.Clear();
lbl_OsobNaStatku.Text = $"Łącznie X osob na statku.";
WyswietlPodsumowanieZapakowania();
}
obiekt "Rodzina": implementacja "IComparable" jest po to bo juz podchodzilem do linq ;)
public class Rodzina : IComparable
{
public string Nazwa { get; private set; }
public int LiczbaOsobWRodzinie { get; private set; }
public Rodzina(int liczbaOsob)
{
LiczbaOsobWRodzinie = liczbaOsob;
Nazwa = NazywaczRodzin.NazwijRodzine(liczbaOsob);
}
public Rodzina(string nazwisko, int liczba)
{
this.Nazwa = nazwisko;
this.LiczbaOsobWRodzinie = liczba;
}
public override string ToString()
{
return Nazwa;
}
public int CompareTo(object obj)
{
Rodzina rodz = obj as Rodzina;
if (rodz!=null)
return this.LiczbaOsobWRodzinie.CompareTo(rodz.LiczbaOsobWRodzinie);
else
throw new Exception("Błąd Rodzina: linia: 31");
}
}
obiekt "Upychacz": tutaj robie kopie rodziny do upchania, bo z niej podbieram, docelowo bede z niej korzystal jako buforu do zamieniania miejscami rodzin
public class Upychacz
{
private int dostepnaPojemnosc;
private List<Rodzina> rodzinyDoZapakowania = new List<Rodzina>();
public Upychacz(int zadanaPojemnosc, List<Rodzina> rodzinyDoUpchania)
{
dostepnaPojemnosc = zadanaPojemnosc;
foreach (var item in rodzinyDoUpchania)
{
rodzinyDoZapakowania.Add(new Rodzina(item.Nazwa, item.LiczbaOsobWRodzinie));
}
Zapakowani = new List<Rodzina>();
Pozostawieni = new List<Rodzina>();
PakujTowarzystwo();
}
public List<Rodzina> Zapakowani { get; private set; }
public List<Rodzina> Pozostawieni { get; set; }
public void PakujTowarzystwo()
{
//To miejsce na osadzenie algorytmu pakujacego
//rodzinyDoZapakowania.Sort();
for (int i = rodzinyDoZapakowania.Count - 1; i >= 0; i--)
{
if (PoliczLudziW(Zapakowani) + rodzinyDoZapakowania[i].LiczbaOsobWRodzinie < dostepnaPojemnosc)
{
Zapakowani.Add(rodzinyDoZapakowania[i]);
rodzinyDoZapakowania.RemoveAt(i);
}
else
{
Pozostawieni.Add(rodzinyDoZapakowania[i]);
rodzinyDoZapakowania.RemoveAt(i);
}
}
}
private int LiczbaWolnychMiejscNaStatku()
{
return dostepnaPojemnosc - PoliczLudziW(Zapakowani);
}
private int PoliczLudziW(List<Rodzina> kolekcjaRodzin)
{
int wynik = 0;
foreach (Rodzina item in kolekcjaRodzin)
wynik += item.LiczbaOsobWRodzinie;
return wynik;
}
}
i "nazywacz rodzin":
public static class NazywaczRodzin
{
private static int licznikNazw = 0;
private static int surfiks = 1;
private static char[] literki = new char[] { 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J',
'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T',
'U', 'W', 'X', 'Y', 'Z' };
public static string NazwijRodzine(int licznosc)
{
string nazwiskoRodziny =
$"Rodzina-{literki[licznikNazw].ToString()}{((surfiks != 1) ? surfiks.ToString() : "" )}__{licznosc}osobowa";
if (licznikNazw % 24 == 0 && licznikNazw != 0)
{
surfiks++;
licznikNazw = -1;
}
licznikNazw++;
return nazwiskoRodziny;
}
}