]> git.llucax.com Git - z.facultad/75.29/susanita.git/blob - src/persona.cpp
Agrega script para hacer imprimible al código.
[z.facultad/75.29/susanita.git] / src / persona.cpp
1 #include "persona.h"
2 #include "heap.h"
3 #include <algorithm>
4 #include <cassert>
5
6 /// Constructor
7 Persona::
8 Persona(const std::string& nombre, sexo_type sexo, size_type cap):
9         nombre(nombre), prefs_hash(cap), estado(SOLTERO), sexo(sexo),
10         pareja(0), rechazos(cap)
11 {
12 }
13
14 /// Para representación
15 std::ostream&
16 operator<< (std::ostream& os, const Persona::estado_type e)
17 {
18         switch (e)
19         {
20                 case Persona::SOLTERO:
21                         return os << "soltero";
22                 case Persona::DECLARADO:
23                         return os << "declarado";
24                 case Persona::COMPROMETIDO:
25                         return os << "comprometido";
26                 default:
27                         assert("Estado de la persona desconocido");
28                         return os << "desconocido";
29         }
30 }
31
32 /// Para representación
33 std::ostream&
34 operator<< (std::ostream& os, const Persona::sexo_type s)
35 {
36         switch (s)
37         {
38                 case Persona::M:
39                         return os << "M";
40                 case Persona::F:
41                         return os << "F";
42                 default:
43                         assert("Sexo de la persona desconocido");
44                         return os << "desconocido";
45         }
46 }
47
48 /// Para representación
49 std::ostream&
50 operator<< (std::ostream& os, const Persona& p)
51 {
52         std::string pareja = "-";
53         if (p.pareja)
54         {
55                 pareja = p.pareja->nombre;
56         }
57         os << "<" << p.nombre << " (" << p.sexo << "): " << p.estado << " - "
58                 << pareja << ">";
59         return os;
60 }
61
62 /// Función de comparación entre dos personas según nuestras preferencias
63 int
64 Persona::
65 cmp(const Persona& p1, const Persona& p2) const // O(1)
66 {
67         int i1 = prefs_hash.get(p1.nombre); // O(1)
68         int i2 = prefs_hash.get(p2.nombre); // O(1)
69
70         if (i1 < i2)
71                 return 1;
72         if (i1 == i2)
73                 return 0;
74         return -1;
75 }
76
77 // Para que no se exporte el símbolo, es de uso interno de este módulo
78 namespace
79 {
80         /// Functor de ordenamiento auxiliar
81         struct PersonaCmp
82         {
83                 const Persona& p;
84                 PersonaCmp(Persona& p): p(p) {}
85                 /// devuelve true si p1 < p2
86                 bool operator ()(const Persona* const p1, const Persona* const p2) const
87                 {
88                         return p.cmp(*p1, *p2) > 0; // O(1)
89                 }
90         };
91 }
92
93 /// Inserta nueva oferta
94 void
95 Persona::
96 push_oferta(Persona* p) // O(log(N))
97 {
98         heap_push(ofertas, p, PersonaCmp(*this));
99 }
100
101 /// Obtiene mejor oferta (sin eliminar)
102 Persona*
103 Persona::
104 top_oferta() const // O(1)
105 {
106         return ofertas.back();
107 }
108
109 /// Obtiene y elimina mejor oferta
110 Persona*
111 Persona::
112 pop_oferta() // O(log(N))
113 {
114         return heap_pop(ofertas, PersonaCmp(*this));
115 }
116
117 /// Nos declaramos a la persona p
118 void
119 Persona::
120 declarar_a(Persona& p) // O(log(N))
121 {
122         estado = DECLARADO;
123         pareja = &p;
124         p.push_oferta(this); // O(log(N))
125 }
126
127 /// Nos comprometemos con la persona p, quien se nos habia declarado previamente
128 void
129 Persona::
130 comprometer_con(Persona& p) // O(N) ( es O(len(ofertas)) )
131 {
132         assert(p.estado == DECLARADO);
133         assert(p.pareja == this);
134
135         // rompemos el compromiso, si hay
136         if (estado == COMPROMETIDO)
137         {
138                 assert(pareja != 0);
139                 pareja->estado = SOLTERO;
140                 pareja->pareja = 0;
141                 pareja->rechazos[this->nombre] = this; // O(1)
142         }
143
144         // nos comprometemos
145         estado = COMPROMETIDO;
146         pareja = &p;
147         p.estado = COMPROMETIDO;
148         p.pareja = this;
149
150         // si tenemos ofertas, las rechazamos
151         for (ofertas_type::iterator pretendiente = ofertas.begin(); // O(N)
152                         pretendiente != ofertas.end(); ++pretendiente)
153         {
154                 (*pretendiente)->rechazos[this->nombre] = this; // O(1)
155         }
156         ofertas.clear(); // O(N)
157 }
158
159 // Nos comprometemos con la otra persona y a ella la comprometemos con nosotros
160 void
161 Persona::
162 comprometer_con_bt(Persona& p)
163 {
164         // nos comprometemos
165         estado = COMPROMETIDO;
166         pareja = &p;
167         p.estado = COMPROMETIDO;
168         p.pareja = this;
169 }
170
171 // Rompemos el compromiso existente
172 void
173 Persona::
174 romper_compromiso(Persona& p)
175 {
176         assert(pareja == &p);
177         assert(p.pareja == this);
178         
179         // rompemos el compromiso
180         estado = SOLTERO;
181         pareja = 0;
182         p.estado = SOLTERO;
183         p.pareja = 0;
184 }
185
186