7 def __init__(self, nombre = ""):
8 # Nombre de la persona, solo con fines de representacion
11 # Lista de personas que prefiere, la primera de la lista es la
12 # que mejor posicionada esta
15 # Estado de la persona: puede ser 'soltero', 'declarado' o
17 self.estado = 'soltero'
19 # De estar declarado o comprometido, quien es su pareja
22 # Lista de la gente que se le declaro
25 # Lista de la gente que lo rechazo
34 pareja = self.pareja.nombre
35 return "<%s: %s - %s>" % (self.nombre, self.estado, pareja)
40 def cmp(self, p1, p2):
41 """Funcion de comparacion entre dos personas segun nuestras
43 if self.prefs.index(p1) < self.prefs.index(p2):
45 elif self.prefs.index(p1) == self.prefs.index(p2):
51 def ordenar_ofertas(self):
52 "Ordenamos las ofertas segun nuestras preferencias"
53 # este sort es in-place y estable
54 def cmp(x, y, obj = self):
56 self.ofertas.sort(cmp)
59 def declarar_a(self, p):
60 "Nos declaramos a la persona p"
61 self.estado = 'declarado'
63 p.ofertas.append(self)
66 def comprometer_con(self, p):
67 """Nos comprometemos con la persona p, quien se nos habia
68 declarado previamente"""
70 # XXX: podriamos usar los decorators de contract para esto
71 assert p.estado == 'declarado' and p.pareja == self
73 # rompemos el compromiso, si hay
74 if self.estado == 'comprometido':
75 self.pareja.estado = 'soltero'
76 self.pareja.pareja = None
77 self.pareja.rechazos.append(p)
80 self.estado = 'comprometido'
82 p.estado = 'comprometido'
85 # si tenemos ofertas, las rechazamos
86 for pretendiente in self.ofertas:
87 pretendiente.rechazos.append(p)
91 class Hombre (Persona):
95 class Mujer (Persona):
108 # Diccionario de gente, relaciona nombres con objetos
112 def add_persona(self, p):
113 assert not self.nombres.has_key(p.nombre)
115 self.nombres[p.nombre] = p
116 if isinstance(p, Hombre):
117 self.hombres.append(p)
118 elif isinstance(p, Mujer):
119 self.mujeres.append(p)
121 def get_persona(self, nombre):
123 return self.nombres[nombre]
128 def primera_ronda(self):
129 # "En la primera ronda cada hombre se le declara a la mujer que
130 # prefiere independientemente de que algun otro se le haya
132 # Entre todas las propuestas que recibio, cada mujer elige al
133 # hombre mejor posicionado en su ranking y se compromete con
134 # el. Si una mujer no recibe ninguna propuesta, espera hasta
136 for h in self.hombres:
140 for m in self.mujeres:
149 def nesima_ronda(self):
150 # "En cada ronda subsiguiente los hombres que ya estan
151 # comprometidos no hacen nada. Cada hombre no comprometido se
152 # le declara a la mujer mejor posicionada en su ranking que
153 # aun no lo rechazo, independientemente de que ella este
155 # Cuando le toca el turno a las mujeres, cada mujer acepta la
156 # propuesta del hombre mejor posicionado en su ranking
157 # (incluso puede llegar a romper un compromiso; tambien puede
158 # suceder que su novio actual este mejor posicionado que todos
159 # sus nuevos pretendientes, en cuyo caso se queda con el novio
160 # actual). Si una mujer no recibe ninguna propuesta, espera
161 # hasta la proxima ronda."
162 for h in self.hombres:
163 if h.estado == 'comprometido':
174 for m in self.mujeres:
180 if m.estado == 'comprometido':
181 if m.cmp(m.pareja, h) < 0:
182 # la oferta es mejor, rompemos el
186 # estamos mejor con nuestra pareja
187 # actual, asi que no hacemos mas que
188 # rechazar a todos (incluyendo el
190 for i in m.ofertas + [h]:
197 def todos_h_comprometidos(self):
198 "Se fija si todos los hombres estan comprometidos"
199 # FIXME: podemos ver de poner esto adentro de nesima_ronda()
200 for h in self.hombres:
201 if h.estado != 'comprometido':
206 def mostrar_estado(self):
207 for h in self.hombres:
210 for m in self.mujeres:
217 def casamentear(self):
219 while not self.todos_h_comprometidos():
225 def __init__(self, susanita):
229 def input(self, filename):
236 # la linea vacia alterna de sexo
242 # obtenemos el nombre y la lista
243 nombre, prefs = l.split(':')
244 prefs = prefs.split(',')
246 nombre = nombre.strip()
247 p = self.s.get_persona(nombre)
250 self.s.add_persona(p)
254 t = self.s.get_persona(i)
257 self.s.add_persona(t)
261 for h in self.s.hombres:
262 assert h.estado == 'comprometido'
263 print h.nombre, h.pareja.nombre
265 for m in self.s.mujeres:
266 assert m.estado == 'comprometido'
267 print m.nombre, m.pareja.nombre
271 if __name__ == '__main__':
272 if len(sys.argv) != 2:
273 print "El primer parametro debe ser el archivo de entrada"