def sumar_pilas(pila1, pila2): """ DOC: Completar """ pila1_invertida = Pila() pila2_invertida = Pila() pila_final = Pila() while not pila1.esta_vacia() or not pila2.esta_vacia(): n1 = pila1.desapilar() if not pila1.esta_vacia() else 0 n2 = pila2.desapilar() if not pila2.esta_vacia() else 0 pila1_invertida.apilar(n1) if not n1 == 0 else None pila2_invertida.apilar(n2) if not n2 == 0 else None while not pila1_invertida.esta_vacia or not pila2_invertida.esta_vacia(): numero_anterior = pila_final.desapilar( ) if not pila_final.esta_vacia() else 0 n1 = pila1_invertida.desapilar( ) if not pila1_invertida.esta_vacia() else 0 n2 = pila2_invertida.desapilar( ) if not pila2_invertida.esta_vacia() else 0 print(n1, n2) suma = n1 + n2 suma += numero_anterior proximo_numero = suma // 10 suma = suma % 10 pila_final.apilar(suma) pila_final.apilar(proximo_numero) if not proximo_numero == 0 else None return pila_final
def calculadora_polaca(elementos): """ Dada una lista de elementos que representan las componentes de una expresion en notacion polaca inversa, evalua dicha expresion. Si la expresion esta mal formada, levanta ValueError """ p = Pila() for elemento in elementos: print(f"\nDEBUG: entra {elemento}") # Intenta convertirlo a numero try: numero = float(elemento) p.apilar(numero) print(f"DEBUG: apila {numero}") # si no se puede convertir, deberia ser un operando except ValueError: if elemento not in ('+', '-', '/', '*'): raise ValueError("Operando inválido") # Si es un operando válido, intenta desapilar y operar try: a1 = p.desapilar() print(f"\nDEBUG: desapila {a1}") a2 = p.desapilar() print(f"\nDEBUG: desapila {a2}") except IndexError: raise ValueError("Faltan operandos..") if elemento == "+": resultado = a2 + a1 if elemento == "-": resultado = a2 - a1 if elemento == "/": resultado = a2 / a1 if elemento == "*": resultado = a2 * a1 print(f"\nDEBUG: apila {resultado}") p.apilar(resultado) # Al final el resultado debe ser lo unico en la pila resultado = p.desapilar() if not p.esta_vacia(): raise ValueError("Sobran operandos") return resultado
def _min_seguimientos(grafo, origen, destino): distancia, padre = biblioteca.camino_minimo_bfs(grafo, origen, destino) if destino not in distancia: return None p = Pila() aux = destino while aux != origen: p.apilar(aux) aux = padre[aux] p.apilar(origen) camino = [] while not p.esta_vacia(): camino.append(p.desapilar()) return camino
def main(): niveles = cargar_niveles() nivel = 1 teclas = cargar_teclas() juego = setear_juego(niveles, nivel) movimientos = Pila() soluciones = Pila() mensaje = "" while gamelib.is_alive(): gamelib.draw_begin() dibujar(juego) gamelib.draw_end() gamelib.draw_text(mensaje,15,15,anchor="w") ev = gamelib.wait(gamelib.EventType.KeyPress) if not ev: break tecla = ev.key if tecla in teclas: if teclas[tecla] == "REINICIAR": juego = reiniciar(juego, niveles, nivel, soluciones) elif teclas[tecla] == "SALIR": break elif teclas[tecla] == "DESHACER": if movimientos.tope: juego = deshacer(movimientos, juego) elif teclas[tecla] == "AYUDA": if soluciones.esta_vacia(): gamelib.draw_text("Pensando...", 15, 15, anchor="w") gamelib.get_events() #Utilizo .get_events() como una especie de mutex para evitar que el usuario interactúe solucion_encontrada, soluciones = solver.buscar_solucion(juego, DIRECCIONES) gamelib.get_events() if solucion_encontrada: mensaje = "Hay pista disponible" else: mensaje = "No hay chance" else: movimientos.apilar(juego) juego = soko.mover(juego, soluciones.desapilar()) else: movimientos.apilar(juego) juego = soko.mover(juego, DIRECCIONES[teclas[tecla]]) if tecla and not teclas[tecla] == "AYUDA": soluciones = Pila() mensaje = "" if soko.juego_ganado(juego): nivel = nivel + 1 juego = setear_juego(niveles, nivel) movimientos = Pila()
def reemplazar(pila, valor_nuevo, valor_viejo): pila_aux = Pila() while not pila.esta_vacia(): elemento = pila.desapilar() if elemento == valor_viejo: elemento = valor_nuevo pila_aux.apilar(elemento) while not pila_aux.esta_vacia(): pila.apilar(pila_aux.desapilar())
def main(): # Inicializar el estado del juego niveles = archivos.cargar_niveles('niveles.txt') acciones = archivos.cargar_accion_de_tecla('teclas.txt') estados = Pila() pistas = None grilla, nivel = juego_inicializar(niveles) x, y = soko.dimensiones(grilla) gamelib.resize(x * PIXELES_GIF, y * PIXELES_GIF) while gamelib.is_alive(): gamelib.draw_begin() mostrar_interfaz(grilla) if pistas != None: gamelib.draw_text('Pista encontrada', PIXELES_GIF, PIXELES_GIF // 2, size=12, fill='#00FF00') gamelib.draw_end() ev = gamelib.wait(gamelib.EventType.KeyPress) if not ev: break tecla = ev.key accion = procesar_tecla_presionada(tecla, acciones) grilla, estados, pistas = juego_actualizar(grilla, nivel, niveles, accion, estados, pistas) if not grilla: break if soko.juego_ganado(grilla): while not estados.esta_vacia(): estados.desapilar() pistas = None nivel, grilla = juego_pasar_nivel(nivel, niveles) if not grilla: break
class _IteradorListaEnlazada: """ Modela el iterador para la clase ListaEnlazada. """ def __init__(self, elemento): """ Inicializa el iterador a partir del nodo parametrizado. """ self.actual = elemento self.anteriores = Pila() def __next__(self): """ Devuelve el próximo elemento de la lista (la información del nodo siguiente). Si el nodo es el último, termina con la iteración. """ if not self.actual: raise StopIteration() dato = self.actual.dato self.anteriores.apilar(self.actual) self.actual = self.actual.prox return dato def anterior(self): """ Devuelve el anterior elemento de la lista (la información del nodo anterior). Si el nodo es el primero, termina con la iteración. """ if self.anteriores.esta_vacia(): raise StopIteration() nodo = self.anteriores.desapilar() self.actual = nodo return nodo.dato
def eliminar_repetidos_consecutivos(pila): if pila.esta_vacia(): return pila_aux = Pila() dato1 = pila.desapilar() pila_aux.apilar(dato1) while not pila.esta_vacia(): dato2 = pila.desapilar() if dato1 != dato2: pila_aux.apilar(dato2) dato1 = dato2 while not pila_aux.esta_vacia(): pila.apilar(pila_aux.desapilar())
def invertir(self): pila = Pila() if self.prim is None: return nodo = self.pop() #utilizo self.pop porque el enunciado no indica que se necesite recorrer la lista una sola vez. while nodo is not None: pila.apilar(nodo) nodo = self.pop() proximo = None while not pila.esta_vacia(): nodo_nuevo = _Nodo() nodo_nuevo.dato = pila.desapilar() nodo_nuevo.prox = proximo proximo = nodo_nuevo self.prim = proximo
class IteradorListaEnlazada: """ Representa un iterador que puede recorrer una lista enlazada tanto avanzando como retrocediendo. """ def __init__(self, lista_enlazada): """ Crea un iterador para una lista enlazada. Pre: recibe una lista enlazada. """ self.lista = lista_enlazada self.anterior = None self.actual = lista_enlazada.prim self.pila_anteriores = Pila() self.posicion = 0 def esta_al_final(self): """ Evalua si esta en la posicion final. Devuelve un True en caso afirmativo, False caso contrario. """ return self.posicion == (len(self.lista) - 1) def elemento_actual(self): """ Devuelve el elemento actual. """ if not self.actual: return None return self.actual.dato def avanzar(self): """ Pasa al siguiente elemento de la lista. """ if (not len(self.lista)) or (self.esta_al_final()): raise StopIteration("Esta al final.") self.pila_anteriores.apilar(self.anterior) self.anterior = self.actual self.actual = self.actual.prox self.posicion += 1 return self.actual.dato def retroceder(self): """ Vuelve al elemento anterior de la lista. """ if self.pila_anteriores.esta_vacia(): raise StopIteration("Esta al principio.") self.actual = self.anterior self.anterior = self.pila_anteriores.desapilar() self.posicion -= 1 return self.actual.dato def insertar(self, dato): """ Inserta un elemento en la posicion actual del iterador. """ if self.posicion == 0: self.lista.insertar_primero(dato) self.actual = self.lista.prim return self.actual.dato nodo = _Nodo(dato) self.anterior.prox = nodo nodo.prox = self.actual self.actual = nodo self.lista.len += 1 return self.actual.dato def insertar_siguiente(self, dato): """ Pre: recibe un elemento cualquiera. Post: inserta el elemento recibido en la siguiente posicion del iterador. Si el iterador esta al final de la lista, entonces el elemento es insertado despues del ultimo. """ if not self.actual: raise ValueError("No existe un elemento actual.") if self.esta_al_final(): nodo = _Nodo(dato) self.actual.prox = nodo self.lista.len += 1 return self.avanzar() self.insertar(dato) self.retroceder() def insertar_anterior(self, dato): """ Pre: recibe un elemento cualquiera. Post: inserta el elemento recibido en la anterior posicion del iterador. Si el iterador esta al principio de la lista, entonces el elemento es insertado antes del primero. """ if not self.actual: raise ValueError("No existe un elemento actual") if self.posicion == 0: self.anterior = self.lista.insertar_primero(dato) self.pila_anteriores.apilar(None) self.posicion += 1 return self.retroceder() self.insertar(dato) self.avanzar() self.avanzar()
def main(): # Inicializar el estado del juego deshacer = Pila() pistas = [] teclas = archivo_teclas(RUTA_TECLAS) niveles = archivo_niveles(RUTA_NIVELES) contador = es_nivel(gamelib.input("Eliga un nivel:"), niveles) juego = emparejar(niveles[contador]) #lista de cadenas c, f = soko.dimensiones(juego) gamelib.resize(c * DIM_CELDA, f * DIM_CELDA) juego = soko.crear_grilla(juego) #lista de listas dibujar_juego(contador, juego, 1) while gamelib.is_alive(): ev = gamelib.wait(gamelib.EventType.KeyPress) if not ev: break # Actualizar el estado del juego, según la `tecla` presionada tecla = ev.key if es_tecla(tecla, teclas) == None: continue if tecla == 'Escape': gamelib.say("Gracias por jugar Sokoban :)") break if tecla == 'h': if len(pistas) == 0: pistas = backtraking(contador, juego) if pistas == None: pistas = [] else: pista = pistas.pop() juego = soko.mover(juego, pista) deshacer.apilar(juego) dibujar_juego(contador, juego, 2) #pista disponible if soko.juego_ganado(juego): contador += 1 while not deshacer.esta_vacia(): deshacer.desapilar() gamelib.say("Pasaste al siguiente nivel :)") juego = emparejar(niveles[contador]) c, f = soko.dimensiones(juego) gamelib.resize(c * DIM_CELDA, f * DIM_CELDA) juego = soko.crear_grilla(juego) dibujar_juego(contador, juego, 1) if tecla == 'r': if len(pistas) != 0: pistas = [] juego = emparejar(niveles[contador]) c, f = soko.dimensiones(juego) gamelib.resize(c * DIM_CELDA, f * DIM_CELDA) juego = soko.crear_grilla(juego) dibujar_juego(contador, juego, 1) if tecla == 'Control_L': if not deshacer.esta_vacia(): juego = deshacer.desapilar() dibujar_juego(contador, juego, 1) if teclas[tecla] in DIRECCIONES: deshacer.apilar(juego) juego = soko.mover(juego, DIRECCIONES[teclas[tecla]]) dibujar_juego(contador, juego, 1) if tecla != 'h': #vaciar la lista if len(pistas) != 0: pistas = []