Final TALLER


En esta página voy a tratar de explicar todo lo que se necesita para aprobar el final independientemente del tema. Hay muchas cosas que uno lo puede deducir, pero en esta cátedra el más mínimo error es motivo para un 2(dos).

💀 Final Taller de Programación

Final Pascal

Si te toca este final, tenes 2 opciones nada más.

  • Merge acumulador
  • Arboles

Para ambos temas te tenes que saber si o si:

  • Agregar Adelante
  • Agregar Atras
  • Insertar Ordenado

Agregar Adelante

Procedure AgregarAdelante (var L:lista; x:integer);
Var 
    nue:Lista;
Begin  
    New(nue);  
    nue^.datos:=x;  
    nue^.sig:=L;  
    L:=nue; 
End;    

Agregar Atras

procedure AgregarAlFinal(var l,ult:lista;x:integer); 
var  
    nue : lista;
begin 
    new (nue);
    nue^.dato:= x;
    nue^.sig := NIL;
    if l <> Nil then 
        ult^.sig := nue
    else 
        l := nue;
    ult := nue;
end;

Insertar Ordenado

Procedure InsertarElemento ( var pri: lista; x: Integer);
var 
    ant, nue, act: lista;
begin
    new (nue);
    nue^.dato := x;
    act := pri;
    ant := pri;
    while (act<>NIL) and (act^.dato < x) do 
    begin
        ant := act;
        act := act^.sig ;
    end;
    if (ant = act)  then 
        pri := nue   
    else  
        ant^.sig  := nue; 
    nue^.sig := act ;
end;

Mira, para probar los codigos yo lo que hago es hacer una lista de numeros enteros y, insertando lo que quiera probar y despues imprimo la lista para ver si esta bien.

procedure ImprimirLista (L:lista);
begin
    while (L <> nil) do 
    begin
        writeln (L^.dato);
        L:= L^.sig;
    end;
end;

IMPORTANTE: Yo no avanzaria hasta saber bien estos codigos, ya que si tenes algun error en estos es causa de desaprobar :,(

Y con esto nos aseguramos de tener todo en orden.

Bien, una vez que sabemos que funcionan los codigos, vamos a resolver el siguiente final.

Final Merge Acumulador

En este final no me acordaba el insertar ordenado y el modulo recursivo del punto c, lo habia hecho mal

image

Tenemos los datos relevantes con colores que seria denuncia que contiene lo siguiente:

  • Categoria de denuncia 1..6
  • DNI
  • Direccion
    • Numero de calle
    • Numero de altura
  • Mes
  • Dia
  • Hora

Bien una vez que tenemos estos datos, podemos empezar a ver los puntos dados.

Punto A

  • Al decirnos que estan agrupadas por categoria nos indica que es un vector de listas (un vector de 6 agrupa las denuncias por categoria).
  • Tambien nos dice que estan ordenadas por numero de calle, por lo que usaremos el proceso de InsertarOrdenado

Punto B

  • Al decir que recibe un vector de listas y devuelve una sola lista nos indica que tenemos que usar un merge y por defecto usamos un agregarAtras en el modulo de minimo.
  • Cuando nos dice que para cada nro de calle en especifica, ya sabemos que es un merge acumulador (un merge normal pero con un corte de control)
  • Para los merges acumuladores es recomendable crear una estructura de datos aparte, que tenga los datos solicidatos, en este caso, nro de calle, cantidad total de denuncias y cantidad de denuncias realizadas en el mes de julio

Punto C

Bien, en este caso, yo lo que hago siempre es hacer el module en forma iterativa, para probar y despues lo paso a recursivo. Basicamente cambias el while por el if y despues llavas cambias en donde se incrementa la variable, por una llamada a la funcion con el incremento o modificación correspondiente.

Codigo Completo (No lo probe)

program imperativo;
const
    DIMF = 6;
type
    categoria = 1..DIMF;
    direccion = record
        nroCalle:integer;
        nroAltura:integer;
    end;
    denuncia = record
        cat:categoria;
        DNI:integer;
        dir:direccion;
        mes:integer;
        dia:integer;
        hora:integer;
    end;
    lista = ^nodo;
    nodo = record
        dato:denuncia;
        sig:lista;
    end;
    vectorContador = array [1..DIMF] of lista;

    datoNuevo = record
        nroCalle:integer;
        denunciasTotales:integer;
        denunciasJulio:integer;
    end;
    listaNueva = ^nodoNuevo;
    nodoNuevo = record
        dato:datoNuevo;
        sig:listaNueva;
    end;

procedure insertarOrdenado(var l:lista;d:denuncia);
var
    act,ant,nue:lista;
begin
    new(nue);
    nue^.dato:=d;
    act:=l;
    ant:=l;
    while (act <> nil) and (act^.dato.DNI < d.DNI) do
    begin
        ant:=act;
        act:=act^.sig;
    end;
    if (act = ant) then
        l:=nue
    else
        ant^.sig:=nue;
    nue^.sig:=act;
end;

procedure imprimirLista(l:lista);
begin
    while l <> nil do
    begin
        WriteLn(l^.dato.DNI);
        l:=l^.sig;
    end;
end;

procedure agregarAtras(var l,ult:listaNueva; nro:datoNuevo);
var
    nue:listaNueva;
begin
    new(nue);
    nue^.dato:=nro;
    nue^.sig:=nil;
    if (l = nil) then
        l:=nue
    else
        ult^.sig:=nue;
    ult:=nue;    
end;

procedure leerDenuncia(var d:denuncia);
begin
    
    writeln('Ingresar dni: '); ReadLn(d.DNI);

    if (d.DNI <> 0) then
    begin
        writeln('Ingresar categoria: '); ReadLn(d.cat);
        writeln('Ingresar nroCalle: '); ReadLn(d.dir.nroCalle);
        writeln('Ingresar nroAltura: '); ReadLn(d.dir.nroAltura);
        writeln('Ingresar mes: '); ReadLn(d.mes);
        writeln('Ingresar dias: '); ReadLn(d.dia);
        writeln('Ingresar hora: '); ReadLn(d.hora);
    end;
end;

procedure cargarDenuncias(var vc:vectorContador);
var
    d:denuncia;
begin
    leerDenuncia(d);
    while (d.DNI <> 0) do
    begin
        insertarOrdenado(vc[d.cat],d);
        leerDenuncia(d);
    end;
end;
procedure inicializarVector (var vc:vectorContador);
var
    i:integer;
begin
    for i:=1 to DIMF do
    begin
        vc[i]:=nil;
    end;
end;

procedure minimo(vc:vectorContador; var min:denuncia);
var
    posMin:integer;
    i:integer;
begin
    posMin:=-1;
    min.DNI:=9999;
    for i:=1 to DIMF do
    begin
        if (vc[i] <> nil) and (vc[i]^.dato.DNI < min.DNI) then
        begin
            min.DNI:=vc[i]^.dato.DNI;
            posMin:=i;
        end;
    end;
    if (posMin <> -1) then
    begin
        min:=vc[posMin]^.dato;
        vc[posMin]:=vc[posMin]^.sig;
    end;
end;
procedure mergeAcumulador(vc:vectorContador;var ln:listaNueva);
var
    min:denuncia;
    actual:datoNuevo;
    ult:listaNueva;
begin
    ult:=nil;
    minimo(vc,min);
    while (min.DNI <> 9999) do
    begin
        actual.nroCalle:=min.DNI;
        actual.denunciasTotales:=0;
        actual.denunciasJulio:=0;
        while (min.DNI <> 9999) and (actual.nroCalle = min.DNI)  do
        begin
            actual.denunciasTotales:=actual.denunciasTotales + 1;
            if (min.mes = 6) then
                actual.denunciasJulio:=actual.denunciasJulio + 1;
            minimo(vc,min);  
        end;
        agregarAtras(ln,ult,actual);
    end;
end;
procedure calleDenuncias(l:listaNueva;var nroCalle:integer;calleMax:integer);
begin
    if l <> nil then
    begin
        if (calleMax < l^.dato.denunciasTotales) then
        begin
            calleMax:=l^.dato.denunciasTotales;
            nroCalle:=l^.dato.nroCalle;
        end;
        calleDenuncias(l^.sig,nroCalle,calleMax)
    end;
end;
var
    vc:vectorContador;
    l:listaNueva;
    calleDenuncias:integer;
    calleMaxima:integer;
begin
    inicializarVector(vc);
    cargarDenuncias(vc);
    mergeAcumulador(vc,l);
    calleDenuncias:=0;
    calleMaxima:=-1;
    calleMasDenuncias(l,calleDenuncias,calleMaxima);
    writeln('La calle con mas denuncias es: ', calleDenuncias);
end.

Final Arboles

En este final tenia mal el recorrido del arbol, lo puse dos condicionales en la condicion base. (Y siempre va <> nil en la condicion base)

image

IMPORTANTE: Primero te diria que resuelvas este parcial con full enteros y despues le agregues los datos compuestos, ya que es mas facil/rapido de testear

En los teoricos suelen tomar el recorrido optimo del arbol

Tenemos recital con los siguientes datos

  • Nombre de la Banda
  • Fecha del recital
  • Cantidad de canciones tocadas
  • Monto recaudado por la venta de entradas

Bien, una vez que tenemos estos datos, podemos empezar a ver los puntos dados.

Punto A

  • En el momento que nos dice que tienen que estar en una estructura que permite el recorrido optimo por monto recaudado, usamos un arbol

Punto B

  • Mira, esta parte puede ser la menos intuitiva, ya que NO tenemos que recorrer el arbol completo, tenemos que recorrer las ramas, hasta estar en el rango de numeros
  • Tenemos que usar un agregarAtras, ya que el arbol al estar ordenado, mantenemos el orden.

Punto C

  • Aca simplemente hacemos el modulo iterativo, cambiamos el while por el if y despues cambiamos el incremento de la variable, por la llamada al proceso con el incremento como parametro.

Codigo Completo (No lo probe)

program arboles;
type
    recital = record
        nombreBanda:String;
        fecha:String;
        cantTocadas:integer;
        montoRecaudado:real;
    end;
    arbol = ^nodo;
    nodo = record
        dato:recital;
        HI:arbol;
        HD:arbol;
    end;
    lista = ^nodoNuevo;
    nodoNuevo = record
        dato:recital;
        sig:lista;
    end;

procedure crearArbol(var abb:arbol;nro:recital);
begin
    if (abb = nil) then
    begin
        new(abb);
        abb^.dato:=nro;
        abb^.HI:=nil;
        abb^.HD:=nil;
    end
    else
        if (abb^.dato.montoRecaudado > nro.montoRecaudado) then
            crearArbol(abb^.HI,nro)
        else
            crearArbol(abb^.HD,nro);
end;

procedure leerRecital(var r:recital);
begin
    Write('Ingresar nombreBanda: '); ReadLn(r.nombreBanda);
    if (r.nombreBanda <> 'ZZZ') then
    begin
        Write('Ingresar fecha: '); ReadLn(r.fecha);
        Write('Ingresar cantTocadas: '); ReadLn(r.cantTocadas);
        Write('Ingresar monto Recaudado: '); ReadLn(r.montoRecaudado);
    end;
end;
procedure LeerRecitales(var abb:arbol);
var
    dato:recital;
begin
    leerRecital(dato);
    while dato.nombreBanda <> 'ZZZ' do
    begin
        crearArbol(abb,dato);
        leerRecital(dato);
    end;
end;
procedure agregarAdelante(var l:lista; r:recital);
var
    nue:lista;
begin
    new(nue);
    nue^.dato:=r;
    nue^.sig:=l;
    l:=nue;
end;

procedure entreRango(abb:arbol;nro1,nro2:integer;var l:lista);
begin
    if (abb <> nil)then
    begin
        if (abb^.dato.montoRecaudado < nro1) then
            entreRango(abb^.HD,nro1,nro2,l)
        else if (abb^.dato.montoRecaudado > nro2) then
            entreRango(abb^.HI,nro1,nro2,l)
        else
            begin
                entreRango(abb^.HI,nro1,nro2,l);
                agregarAdelante(l,abb^.dato);
                entreRango(abb^.HD,nro1,nro2,l);
            end;
    end;
end;
procedure recitalesMas12Canciones(l:lista; var cantMas12:integer);
begin
    if (l <> nil) then
    begin
        if (l^.dato.cantTocadas >= 12) then
          cantMas12:= cantMas12 + 1;
        recitalesMas12Canciones(l^.sig,cantMas12);
    end;    
end;
var
    abb:arbol;
    nro1,nro2:integer;
    l:lista;
    cantMas12:integer;
begin
    abb:=nil;
    LeerRecitales(abb);
    nro1:=3;
    nro2:=8;
    l:=nil;
    entreRango(abb,nro1,nro2,l);
    cantMas12:=0;
    recitalesMas12Canciones(l,cantMas12);
    WriteLn('La cantidad de recitales que tocaron mas de 12 canciones son:', cantMas12);
end.

Final Objetos

En todos los finales de objetos son mas o menos lo mismo, con resolver bien este final creo que abarcas todos los temas de objetos.

Cuando rendi este final me dijieron que tenia un 10 en el practico, pero me fue mal en las preguntas teoricas.

Objetos

IMPORTANTE en este tipo de finales NO tenes collecciones, nos manejamos siempre con arrays

Lo mas importante es identificar los objetos con sus atributos y herencias que tenemos.

  • Tenista
    • Nombre
    • Cantidad de Partidos Ganados
    • Premios obtenidos en toda su carrera (un array de reales)
  • Partido
    • Fecha (string)
    • Lugar
    • Resultado
      • SetsEquipo1
      • SetsEquipo2
  • Partido Single (Heredan de Partido)
    • 2 tenistas
  • Partido Doble (Heredan de Partido)
    • 4 tenistas

Una vez que definimos todos los tipos de datos. Empezamos a ver los puntos y definimos los metodos segun el objeto.

  • Cuando decimos que debe instanciarse con todos sus datos, nos referimos al constructor.

Main (Falta el de dobles pero me estoy durmiendo y no tengo muchas ganas)

public class Ultimo {

    public static void main(String[] args) {

        Tenista t1 = new Tenista("Fabian",2,12);
        Tenista t2 = new Tenista("Fernando",1,1);
        
        String fecha = "1-1-2023";
        String lugar = "La Plata";
        
        Single partidoS = new Single(fecha,lugar,t1,t2); 
        partidoS.registrarResultado(1, 2);
        partidoS.registrarResultado(1, 2);
        partidoS.registrarResultado(1, 2);
        
        partidoS.otorgarPremio(100000);
    }
}

Tenista

public class Tenista {
    private String nombre;
    private int partidosGanados;
    private double premios;
    
    public Tenista(String nombre, int partidosGanados, double premios){
        this.nombre = nombre;
        this.partidosGanados = partidosGanados;
        this.premios = premios;
    }
    
    public void ganoPartido(){
        this.partidosGanados++;
    }
    
    public void agregarPremio(double premio){
        this.premios = this.premios + premio;
    }
    
    public int getPartidosGanados(){
        return this.partidosGanados;
    }
}

Partido

public abstract class Partido {
    private String fecha;
    private String lugar;
    private int lado1;
    private int lado2;
    
    public Partido(String fecha, String lugar){
        this.fecha = fecha;
        this.lugar = lugar;
        this.lado1 = 0;
        this.lado2 = 0;
    }
    
    public void registrarResultado(int lado1, int lado2){
        if (lado1 > lado2) {
            this.lado1++;
        }
        else{
            this.lado2++;
        }
    }
    
    public boolean finalizo(){
        if ((this.lado1 == 3) || (this.lado2 == 3)) {
            return true;
        }
        return false;
    }
    
    abstract public void otorgarPremio(double premio);
    
    public boolean ganoLado1(){
        if (this.lado1 == 3){
            return true;
        }
        return false;
    }
}

Single

public class Single extends Partido {
    private Tenista t1;
    private Tenista t2;
    
    public Single(String fecha, String lugar,Tenista t1, Tenista t2){
        super(fecha,lugar);
        this.t1 = t1;
        this.t2 = t2;
    }

    @Override
    public void otorgarPremio(double premio) {
        //Suponemos que el partido termino (algun lado tiene 3 sets ganados)
        if (this.ganoLado1()){
            this.t1.ganoPartido();
            this.t1.agregarPremio(premio);
        }
        else{
            this.t2.ganoPartido();
            this.t2.agregarPremio(premio);
        }
    }
}

Doble

public class Doble extends Partido {
    Tenista t1E1;
    Tenista t2E1;
    Tenista t1E2;
    Tenista t2E2;
    
    public Doble (String fecha, String lugar, Tenista t1E1, Tenista t2E1, Tenista t1E2, Tenista t2E2){
        super(fecha, lugar);
        this.t1E1 = t1E1;
        this.t2E1 = t2E1;
        this.t1E2 = t1E1;
        this.t2E2 = t1E2;
    }

    public double calcularPremio(int ganadosJ1, int ganadosJ2){
        return (ganadosJ1 / (ganadosJ1 + ganadosJ2));
    }
    @Override
    public void otorgarPremio(double premio) {
        double premio1,premio2 = 0;
        if (this.ganoLado1()){
            premio1 = premio * this.calcularPremio(this.t1E1.getPartidosGanados(), this.t2E1.getPartidosGanados());
            this.t1E1.agregarPremio(premio1);
            premio2 = premio * this.calcularPremio(this.t2E1.getPartidosGanados(), this.t1E1.getPartidosGanados());
            this.t2E1.agregarPremio(premio2);
        }
        else{
            premio1 = premio * this.calcularPremio(this.t1E2.getPartidosGanados(), this.t2E2.getPartidosGanados());
            this.t1E2.agregarPremio(premio1);
            premio2 = premio * this.calcularPremio(this.t2E2.getPartidosGanados(), this.t1E2.getPartidosGanados());
            this.t2E2.agregarPremio(premio2);
        }
    }
}   

Final Concurrente

concurrente

El programa tiene la siguiente estructura:

  • programa NombrePrograma
  • procesos
    • proceso x()
  • areas
    • area1 : AreaP(5, 1, 5, 10) // Recorre la avenida 5, desde la calle 1 hasta la 10
  • robots
    • robot RECOLECTOR
  • variables
    • R1 : RECOLECTOR
  • comenzar
    • AsignarArea(R1, area1)
    • Iniciar(R1, 5, 1)
  • fin

Extraemos los datos del enunciado

programa final
procesos
  proceso VaciarBolsa
  comenzar
    mientras (HayFlorEnLaBolsa)
      depositarFlor
    mientras (HayPapelEnLaBolsa)
      depositarPapel
  fin
  proceso recorrerAvenida
  comenzar
    derecha
    mover
    repetir 18
      mover
      si HayFlorEnLaEsquina
        tomarFlor
  fin
  proceso depositarFlores
  variables
    av:numero
    ca:numero
  comenzar
    av:=PosAv
    ca:=PosCa
    mientras HayFlorEnLaBolsa
      BloquearEsquina(1,6)
      Pos(1,6)
      depositarFlor
      Pos(av,ca)
      LiberarEsquina(1,6)
  fin
areas
  area1: AreaP(1,1,20,1)
  area2: AreaP(1,2,20,2)
  area3: AreaP(1,3,20,3)
  area4: AreaP(1,4,20,4)
  area5: AreaP(1,5,1,5)
  areaMulti: AreaPC(1,6,1,6)
robots
  robot TIPO1
  variables
    av:numero
    ca:numero
    id:numero
  comenzar
    RecibirMensaje(id,RF)
    av:=PosAv
    ca:=PosCa
    VaciarBolsa
    recorrerAvenida
    depositarFlores
    EnviarMesanje(id,RF)
    Pos(av,ca)
  fin
  robot FISCALIZADOR
  variables
    idFinal1:numero
    idFinal2:numero
    id:numero
  comenzar
    EnviarMensaje(1,R1)
    EnviarMensaje(2,R2)
    EnviarMensaje(3,R3)
    EnviarMensaje(4,R4)

    RecibirMensaje(idFinal1,*)
    RecibirMensaje(idFinal2,*)
    RecibirMensaje(id,*)
    RecibirMensaje(id,*)

  fin
variables
  R1:TIPO1
  R2:TIPO1
  R3:TIPO1
  R4:TIPO1
  RF:FISCALIZADOR
comenzar
  AsignarArea(R1,area1)
  AsignarArea(R1,areaMulti)
  AsignarArea(R2,area2)
  AsignarArea(R2,areaMulti)
  AsignarArea(R3,area3)
  AsignarArea(R3,areaMulti)
  AsignarArea(R4,area4)
  AsignarArea(R4,areaMulti)
  AsignarArea(RF,area5)
  
  Iniciar(R1,1,1)
  Iniciar(R2,1,2)
  Iniciar(R3,1,3)
  Iniciar(R4,1,4)
  Iniciar(RF,1,5)
fin

La primera parte la hice mas o menos asi, para simular cuando lleguen todos, se podria usar un repetir o un recibirMensaje en el fiscalizador 4 veces, para saber que estan todos listos

Hay varios parciales que son mas faciles en mi github


Aprobe :D 8

En el teorico me preguntaron sobre el recorrido de un arbol de forma optima, que es lo que esta arriba y tambien que tenia mal el codigo de r-info (El robot jefe recibia el id y despues las flores o algo asi).

Bueno en cuanto a la practica hice tres objetos nada mas, sin herencia ni nada, un objeto Sistema con dos arreglos, uno para partidos y otro para apuestas (Partidos y Apuestas son los otros 2 objetos)

image