CLASE PRÁCTICA LUNES 2026-08-10
- [00:00:00]
— Bienvenida e Introducción a la Cátedra
- Presentación y organización inicial.
- Acceso al entorno virtual (Moodle/FICH) y apuntes de la
materia.
- [00:01:43]
— Entornos de Desarrollo / IDEs recomendados
- Uso de Visual Studio Code y plugins para C++.
- Mención sobre el entorno local desarollado en la facultad (CZ)
vs. VS Code.
- [00:03:24]
— Recursos y Organización de las Clases
- Definición de la dinámica con la teoría (clases de los martes con
Mario).
- [00:04:18]
Wiki de la cátedra: slides, guías, exámenes anteriores y listas de
reproducción de YouTube.
- [00:07:42]
— Modalidad de Evaluación y Trabajos Prácticos
- Novedades sobre el cursado: enfoque en exámenes parciales y práctica
sin entregas obligatorias de TPLs.
- [00:09:00]
— Repaso de Sintaxis de C++: Conceptos Fundamentales
- [00:09:44]
Lenguajes compilados (C++) vs. interpretados (Python): diferencias de
eficiencia y rendimiento.
- [00:15:23]
Tipado fuerte y declaración explícita de variables.
- [00:17:28]
Estructura básica de un programa en C++ (
#include,
main(), cuerpo y retorno).
- [00:18:41]
— Elementos del Lenguaje C++
- Identificadores, palabras reservadas, literales y operadores.
- [00:20:45]
Tipos de datos primarios (
int, float,
char, bool, string).
- [00:23:41]
Definición de constantes (
const y enum).
- [00:25:20]
Definición e inicialización de variables.
- [00:26:57]
Ámbito y alcance de variables (uso de llaves
{}).
- [00:32:44]
— Reglas de Sintaxis y Buenas Prácticas
- Importancia del punto y coma
; e indentación del
código.
- Referencia a documentación online (
cppreference.com,
cplusplus.com).
- [00:41:18]
— Entrada y Salida de Datos (Flujos standard)
- Uso de
#include <iostream> y
using namespace std;.
- Manejo de
std::cout y std::cin (ejemplo
práctico).
- Caracteres de escape (
\n, \t, etc.) y
comentarios (//, /* */).
- [00:48:48]
— Operadores y Expresiones
- Operadores aritméticos, asignación y módulo (
%).
- [00:49:12]
Pre-incremento (
++i) vs. Post-incremento
(i++).
- [00:54:10]
Operadores abreviados (
+=, -=,
*=).
- [00:55:10]
Operadores relacionales (
==, !=,
<, >) y prioridad lógica.
- [01:01:00]
Operadores lógicos (
&&, ||,
!).
- [01:02:30]
Operaciones a nivel de bits (bitwise).
- [01:04:20]
Precedencia de operadores.
- [01:06:38]
— Biblioteca Estándar y Funciones Matemáticas
- Uso de librerías como
<cmath>.
- [01:09:00]
— Estructuras de Control
- Bucles:
while, do-while y
for.
- Condicionales:
if-else y switch.
- Control de flujo:
break y continue.
- [01:17:00]
— Configuración de Entorno de Desarrollo (Instalación y
DUDAS)
- Instalación de herramientas en diferentes Sistemas Operativos
(Windows, Linux, macOS via Docker/Virtual Machines).
- Material bibliográfico de referencia.
- [01:25:22]
— Reflexión sobre la Inteligencia Artificial (IA) en la
Cátedra
- Uso responsable de herramientas de IA (ChatGPT, LLMs, Vibe
Coding).
- Límites y riesgos de la IA frente a la evaluación en papel y pruebas
técnicas laborales.
- Eficiencia del código generado vs. optimización de hardware.
- [01:39:50]
— Consultas Finales y Horarios
- Aclaraciones sobre comisiones, clases teóricas y prácticas.
CLASE PRÁCTICA JUEVES 2026-08-13
-
[00:00:13] — Repaso de Sintaxis y Tipos de Datos en C++
- Estructura del programa con
main() e inclusión de librerías.
- Declaración de variables:
int, float, double y truncamiento en conversión implícita.
- Uso de
std::cout, std::cin, using namespace std; y std::endl.
- [00:07:22] Operaciones aritméticas y división entera vs. flotante (casteo explícito con
float(a)/b).
- [00:14:28] Tipos
bool, char y uso básico de std::string.
-
[00:19:30] — Funciones y Modularización en C++
- Prototipos, firma y declaración de funciones fuera del
main().
- Ejemplo práctico: implementación de una función de cálculo de promedio.
- [00:40:03] Paso de parámetros: Por copia vs. Por referencia (
&) y administración eficiente de memoria.
-
[00:45:41] — Complejidad Algorítmica y Notación Asintótica (Guía TP1)
- Concepto de eficiencia y medición del tiempo de ejecución por cantidad de operaciones/pasos temporales.
- Escalamiento de la complejidad temporal $T(n)$ en función del tamaño de entrada de datos $n$.
- [00:57:45] Definición formal de la cota superior asintótica (Notación Big-O: existencia de constantes $c$ y $n_0$).
- Jerarquía y orden de crecimiento de funciones: constantes $\mathcal{O}(1) < \log n < \sqrt{n} < n < n^p < 2^n < n! < n^n$.
-
[01:04:31] — Resolución del TP1: Ejercicio 1 (Términos Dominantes)
- Identificación del término dominante en expresiones polinómicas y exponenciales ($T_1$ a $T_5$).
- [01:14:45] Inciso B: Demostración de por qué $(n+1)^2 = \mathcal{O}(n^2)$ hallando las constantes $c$ y $n_0$.
-
[01:23:26] — Análisis de Casos en Algoritmo de Búsqueda Lineal Recursiva (Inciso F)
- Lectura y análisis de una función recursiva de búsqueda en listas.
- Mejor caso: elemento en la primera posición $\mathcal{O}(1)$.
- Peor caso: elemento al final de la lista $\mathcal{O}(n)$.
- Caso promedio: deducción probabilística con distribución homogénea ($p = 1/n$) $\mathcal{O}(n)$.
-
[01:31:24] — Sobrecarga, Funciones Wrapper y Generación de Cadenas de Bits (Inciso G)
- Concepto de sobrecarga de funciones y funciones envoltorio (wrappers).
- Paso recursivo con generación y bifurcación de vectores booleanos (
push_back(0) y push_back(1)).
- Modelado y visualización del proceso mediante un árbol binario completo de altura $n$.
- Orden de ejecución y recorrido en profundidad (preorden).
-
[01:46:18] — Recomendaciones de Estudio y Cierre
- Pautas para completar el resto de ejercicios del TP1 (propiedades algebraicas y transitividad).
- Planificación y consultas finales.
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=jGeAOw3B4Fc
CLASE PRÁCTICA VIERNES 2026-08-14
-
[00:00:01] — Introducción y Organización
- Objetivo de la clase: ampliación de la introducción a C++ y transición desde Python (orientado a Ciencia de Datos e IA).
- Coordinación de contenidos entre las comisiones de práctica.
-
[00:02:52] — Configuración del Entorno de Desarrollo (ZinjaI / IDE)
- Instalación y compatibilidad en Linux, Windows y macOS (Docker / Wine).
- [00:06:01] Instalación del complemento/plantilla de la cátedra (
sin_aed.zcp) y verificación con "Hola Mundo".
-
[00:09:08] — Comparativa de Sintaxis: C++ vs. Python
- Comentarios simples (
//) y multilínea (/* */).
- Tipado fuerte y declaración explícita de tipos primarios (
int, float, bool, string).
- Fin de sentencia con punto y coma (
;) vs. indentación en Python.
- Definición de constantes (
const).
- [00:17:32] Entrada/Salida por consola:
std::cout / std::cin y uso de using namespace std;.
- Operaciones aritméticas y división entera entre tipos
int.
-
[00:23:44] — Estructuras de Control y Operadores en C++
- Condicionales (
if, else if, else) y delimitación por bloques con llaves {}.
- Bucle
while y diferencia práctica entre post-incremento (i++) y pre-incremento (++i).
- [00:31:08] Bucle
for tradicional (inicialización, condición y paso) y bucle basado en rangos (range-based for).
- Inferencia de tipos con
auto (características, alcances y limitaciones).
-
[00:38:58] — Funciones en C++ y Paso de Parámetros
- Firma, tipos de retorno y funciones de tipo
void.
- [00:47:06] Ejercicio guiado en vivo: implementación interactiva de una función para calcular promedios.
- [01:02:02] Sobrecarga de funciones (misma función con diferente firma y comportamiento).
- [01:08:07] Paso de parámetros: Por copia vs. Por referencia (
&) y administración de memoria.
-
[01:14:11] — Introducción a la Guía TP1: Complejidad Algorítmica
- Cuantificación de la eficiencia mediante conteo de operaciones elementales independientes del hardware.
- Concepto del tamaño de entrada de datos ($N$) y tasa de crecimiento del esfuerzo computacional.
- Comportamiento asintótico (Notación Big-O) y análisis en el peor caso.
- Material de la cátedra: notas (
AED Notes) vs. diapositivas (slides).
-
[01:25:25] — Resolución del TP1: Ejercicio 1 (Términos Dominantes y Jerarquía)
- Regla de la suma para determinar la complejidad global a partir del término dominante.
- Jerarquía de crecimiento: constantes $\mathcal{O}(1) < \log N < \sqrt{N} < N < N^p < 2^N < 4^N < N! < N^N$.
- Análisis de funciones $T_1$ a $T_5$ y ordenamiento de menor a mayor costo computacional.
- [01:50:33] Equivalencia asintótica de logaritmos en distintas bases.
- [01:52:34] Justificación del ítem B: por qué $(N+1)^2 = \mathcal{O}(N^2)$ al desarrollar el binomio.
-
[01:56:52] — Consultas Finales, Calendario y Cierre
- Aclaración sobre el feriado del lunes, asistencia a comisiones y dinámicas de cursado.
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=VinCjLnnop0
CLASE PRÁCTICA JUEVES 2026-08-20
-
[00:00:00] — Introducción y Organización
- Revisión de dudas generales sobre la Guía 1 de Complejidad Algorítmica.
-
[00:01:36] — Modelado con Grafos: Ejercicio 1K (Aplicaciones de Coloreado de Grafos)
- K1 — Fixture de Torneo de 6 Equipos:
- [00:07:24] Modelado inicial con grafos no dirigidos (cálculo de partidos totales: $\binom{6}{2} = 15$).
- [00:18:15] Cuello de botella por grado máximo ($\text{grado}(E) = 4$ partidos pendientes para Estudiantes $\Rightarrow$ mínimo 4 semanas).
- [00:24:34] Enfoque dual de incompatibilidad: vértices como partidos pendientes y aristas como equipos compartidos.
- [00:29:30] Asignación de colores por semana libre de solapamientos.
- [00:44:24] K2 — Programación de Exámenes Finales Universitarios:
- Vértices como materias y aristas como alumnos inscriptos en común.
- Asignación de turnos/horarios como coloración de grafos disjuntos.
- [01:12:00] K3 — Asignación de Canales/Frecuencias de TV:
- Estaciones como vértices e interferencia como aristas en radio de 250 km.
-
[01:14:02] — Optimización de Multiplicación Encadenada de Matrices (Ejercicio 1L)
- Cálculo del costo de operaciones escalares en productos matriciales ($P \times Q \times R$).
- [01:24:34] Análisis de las distintas asociaciones para $M_1(10\times 20)$, $M_2(20\times 50)$, $M_3(50\times 1)$ y $M_4(1\times 100)$.
- Estrategia óptima: minimizar tamaños intermedios asociando $(M_1 \times (M_2 \times M_3)) \times M_4$.
- [01:30:04] Planteo general mediante Programación Dinámica para $N$ matrices arbitrarias.
-
[01:44:08] — Repaso del Ejercicio 1C (Capacidad de Cómputo vs. Complejidad)
- Procesador de 3 GHz a 3 ciclos/operación ($10^9$ ops/segundo).
- Comparación del tamaño del problema $N$ según la complejidad:
- Lineal $\mathcal{O}(N) \Rightarrow N = 10^9$.
- Logarítmico $\mathcal{O}(\log_2 N) \Rightarrow N = 2^{10^9}$.
- Cuadrático $\mathcal{O}(N^2) \Rightarrow N \approx 31.622$.
- Exponencial $\mathcal{O}(2^N)$ y Factorial $\mathcal{O}(N!)$.
-
[01:53:04] — Cierre de la Clase y Próximos Pasos
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=qFCd8QsNvSQ
CLASE PRÁCTICA VIERNES 2026-08-21
-
[00:00:00] — Introducción y Organización de la Clase
- Repaso de los avances en la Guía 1 y referencias a los conceptos teóricos (transitividad, regla del producto).
-
[00:01:52] — Resolución TP1: Ejercicio 1C (Capacidad de Procesamiento vs. Complejidad)
- Cálculo de operaciones por segundo de un procesador de 3 GHz (1 operación cada 3 ciclos = $10^9$ ops/seg).
- Estimación del tamaño máximo del problema ($N$) abordable en 1 segundo:
- [00:04:50] Orden logarítmico $\mathcal{O}(\log_2 N) \Rightarrow N = 2^{10^9}$.
- [00:09:03] Orden lineal $\mathcal{O}(N) \Rightarrow N = 10^9$.
- [00:09:21] Orden cuadrático $\mathcal{O}(N^2) \Rightarrow N \approx 31.622$.
- [00:10:37] Orden exponencial $\mathcal{O}(2^N) \Rightarrow N \approx 29$.
- [00:12:24] Orden factorial $\mathcal{O}(N!) \Rightarrow N = 12$.
-
[00:14:36] — Resolución TP1: Ejercicio 1E (Ejemplos de Algoritmos por Orden)
- Búsqueda binaria $\mathcal{O}(\log N)$, acceso por índice en arreglos $\mathcal{O}(1)$ y algoritmos de ordenamiento $\mathcal{O}(N^2)$.
-
[00:17:01] — Resolución TP1: Ejercicio 1F (Búsqueda Lineal Recursiva en Listas)
- Manejo de iteradores en C++ y llamada recursiva.
- Importancia del pre-incremento (
++p) vs. post-incremento (p++) para evitar bucles infinitos.
- Análisis de complejidad: Mejor caso $\mathcal{O}(1)$, Peor caso $\mathcal{O}(N)$ y Caso promedio $\mathcal{O}(N)$.
-
[00:22:05] — Resolución TP1: Ejercicio 1G (Generación de Cadenas de Bits / Conjunto Potencia)
- Mecánica recursiva con bifurcación de vectores booleanos.
- Deducción de la complejidad $\mathcal{O}(N \cdot 2^N)$.
-
[00:26:41] — Resolución TP1: Ejercicio 1K (Aplicaciones de Coloreado de Grafos)
- K1 — Fixture de Torneo de Fútbol: Modelado de partidos pendientes como vértices y partidos incompatibles como aristas; resolución óptima en 4 semanas (colores).
- [00:40:37] K2 — Asignación de Turnos de Exámenes Universitarios: Materias como vértices e incompatibilidad por alumnos compartidos.
- [00:44:03] K3 — Asignación de Frecuencias de Televisión: Estaciones como vértices e interferencia por distancia menor a 250 km.
-
[00:48:01] — Cierre de la Clase
- Aviso sobre la Guía 2 (Listas) y despedida.
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=LFND3TLEprk
CLASE PRÁCTICA LUNES 2026-08-24
-
[00:00:06] — Introducción y Consultas Generales
- Canales de consulta (foro de Moodle / IFICH) y material de años anteriores.
- Configuración de pizarras virtuales para la resolución en vivo.
-
[00:09:09] — Introducción a Tipos de Datos Abstractos: Listas en C++ (Guía 2)
- Estructura de evaluaciones: Teoría, Operativos y Clases.
- Inclusión de listas estándar en C++:
#include <list>.
- [00:12:37] Listas Simplemente Enlazadas vs. Doblemente Enlazadas:
- Estructura de la clase
cell (nodo).
- Dirección de punteros (unidireccional vs. bidireccional) y sobrecarga en memoria.
-
[00:21:50] — Métodos de la STL para Listas:
insert() y Constructores
- Signatura y sobrecargas del método
insert() (inserción simple, por relleno con $N$ copias y por rangos).
- [00:26:29] Diferencia entre Punteros e Iteradores (seguridad, abstracción por contenedor).
- [00:35:06] Constructor por defecto de
std::list y verificación de lista vacía (empty(), size() == 0, begin() == end()).
-
[00:39:21] — Seguimiento Operativo: Iteradores y Eliminación con
erase() (Ejercicio 1E)
- Comportamiento de pre-incremento en iteradores (
++p).
- Efecto de
p = L.erase(q): invalidación del iterador borrado y retorno del iterador al siguiente elemento válido.
- Traza paso a paso sobre la lista
{1, 3, 4, 2, 5, 6} hasta determinar las posiciones finales de $P$ y $Q$.
-
[00:56:33] — Implementación: Ordenamiento Básico con Lista Auxiliar (
basic_sort)
- Consigna: extraer sucesivamente el menor elemento de $L$ e insertarlo al final de una lista auxiliar $L_2$.
- Recorrido de listas mediante bucles
while(!L.empty()) y for con iteradores.
- [01:22:23] Uso de la palabra clave
auto para deducir iteradores vs. valores en range-based loops.
- [01:28:19] Análisis Comparativo: Listas vs. Vectores (eficiencia en inserción en posición arbitraria vs. acceso contiguo en memoria).
- Depuración en vivo en ZinjaI: corrección de errores al copiar valores vs. guardar iteradores antes de invocar
erase().
-
[01:46:23] — Planteo de Ejercicio: Ordenamiento por Selección In-Place (
selection_sort)
- Definición de algoritmo in-place (sin estructuras auxiliares).
- Estrategia de búsqueda del mínimo en la sublista restante e intercambio (
swap) con el primer elemento no ordenado.
- Propuesta de solución aportada por alumnos mediante doble iterador.
-
[01:57:46] — Recomendaciones de Estudio y Cierre
- Pautas de avance sobre la Guía 2: foco en ejercicios de Listas (postergar pilas, colas y correspondencias para más adelante).
- Avisos sobre las clases teóricas y prácticas siguientes.
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=ur07yu0SWDw
CLASE PRÁCTICA JUEVES 2026-08-27
-
[00:05:43] — Inicio y Configuración Inicial
- Organización de la clase y continuación de la Guía 2 (Listas).
-
[00:11:07] — Implementación de Función Auxiliar para Visualización (
show_list)
- Definición de función
void con paso por referencia (list<int>&).
- Recorrido de listas mediante iteradores en bucle
for (auto it = L.begin(); it != L.end(); ++it).
- Acceso al elemento por derreferenciación (
*it) y formateo de salida con std::cout.
-
[00:17:45] — Revisión de Ejercicio: Ordenamiento por Selección (
selection_sort)
- Análisis de propuesta con
std::min_element y std::swap (librería <algorithm>).
- [00:28:25] Discusión sobre la complejidad algorítmica: justificación de $\mathcal{O}(N^2)$ al evaluar
next(), size() y búsqueda del mínimo.
- Pautas para parciales: resolución algorítmica propia vs. uso de funciones estándar de la STL.
-
[00:33:25] — Resolución de Ejercicios de Concatenación de Listas
- Item A — Concatenar dos listas usando
insert:
- Creación de lista resultante vs. modificación de la lista original.
- Paso de parámetros por copia vs. por referencia (
const y preservación de datos originales).
- [00:50:04] Item B — Concatenar una lista de sublistas (
list<list<int>>) usando insert:
- Estructura y declaración de listas de listas.
- Uso de plantillas (templates) para funciones genéricas (
template <typename T>).
- [01:01:45] Item C — Concatenar una lista de sublistas usando
splice:
- Mecánica de
std::list::splice: transferencia/movimiento de nodos mediante punteros sin alocación de memoria extra.
- Vaciado de las sublistas origen al transferir los nodos a la lista destino.
-
[01:10:50] — Debate Técnico: Uso de Templates y Complejidad
- Polimorfismo estático en tiempo de compilación y concepto de code bloating.
- Impacto en tiempo de compilación vs. tiempo de ejecución (runtime).
- Uso de
<ctime> (clock()) para mediciones empíricas de tiempo.
-
[01:21:45] — Implementación: Invertir una Lista In-Place (
invert)
- Requisitos de diseño: algoritmo in-place (sin memoria auxiliar) y complejidad $\mathcal{O}(N)$.
- Estrategia con dos iteradores convergentes (
it1 desde begin() e it2 desde prev(end())) e intercambio sucesivo con swap.
- [01:33:30] Manejo de condiciones de parada para listas de longitud par e impar (evitar rebotes/bucles infinitos).
- Dependencia de listas doblemente enlazadas al requerir
std::prev.
-
[01:40:14] — Implementación: Agrupación y Suma de Elementos (
junta)
- Consigna: agrupar de a $C$ elementos sumándolos in-place y eliminando los nodos sobrantes.
- Estructura con bucle principal
while(it != L.end()) y control interno.
- [01:57:07] Acumulación directa y eliminación combinada mediante
it = L.erase(it) para avanzar al siguiente nodo.
- Garantía de complejidad $\mathcal{O}(N)$ recorriendo la lista en una sola pasada.
-
[02:05:26] — Consultas Finales y Metodología de Exámenes
- Formato de los exámenes parciales presenciales en papel (ejercicios conceptuales, análisis y completado de código).
- Aclaración sobre la no realización de Trabajos Prácticos de Laboratorio (TPLs) y cierre de la clase.
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=n0TXXIDwaXU
CLASE PRÁCTICA LUNES 2026-08-31
-
[00:00:06] — Introducción y Organización de la Clase
- Revisión de temas previos (Guía 2) y configuración de la pizarra virtual.
-
[00:02:14] — Resolución Guía 2: Reemplazo de Secuencias en Listas (
reemplaza_secuencia)
- Planteo del problema: buscar una secuencia $SEC$ dentro de una lista $L$ y reemplazarla por otra sublista $REM$.
- Manejo de sublistas de longitudes arbitrarias y condiciones de borde (listas vacías con
empty()).
- [00:46:25] Variante 1 (Darío): Implementación mediante bandera booleana y bucle
for interno.
- [00:54:55] Variante 2 (Ezequiel): Implementación compacta con doble
while, inserción y borrado seguro de rangos con erase.
-
[01:07:37] — Resolución Guía 2: Partición en Sublistas Ascendentes (
ascendente_1 y ascendente_2)
- Consigna de
ascendente_1: dividir una lista $L$ en una lista de listas $LL$ tal que cada sublista sea estrictamente ascendente.
- [01:11:05] Comparación con
ascendente_2: uso de Listas de Listas (acceso secuencial $\mathcal{O}(K)$) vs. Vector de Listas (acceso aleatorio $\mathcal{O}(1)$).
- [01:36:07] Puesta en común y revisión de código: manejo de
push_back, iteradores previos y corte de sublistas.
-
[01:42:42] — Planteo de Ejercicio: Ordenamiento Parametrizado (Camaleón /
ordena)
- Definición de predicados de ordenamiento:
menor(x, y), mayor(x, y) y distancia(x, y) (comparación por valor absoluto abs()).
- Uso de plantillas (templates) y punteros a función para parametrizar el criterio de ordenamiento en
ordena(L, F).
- Análisis de lógica de intercambio (
swap) y necesidad de ordenamiento global vs. local.
-
[02:01:00] — Consultas Finales y Próximos Temas
- Coordinación para el foro de consultas y anticipo de la siguiente sección (Pilas y Colas).
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=qdQDIT6-i6Q
CLASE PRÁCTICA JUEVES 2026-09-03
-
[00:00:02] — Introducción y Comparativa Conceptual: Pilas vs. Colas vs. Listas (Guía 2B)
- Pilas (
std::stack): Principio LIFO (Last-In, First-Out), acceso y mutación restringidos al tope.
- Colas (
std::queue): Principio FIFO (First-In, First-Out), inserción por el fondo (back) y extracción por el frente (front).
- Naturaleza destructiva del recorrido sin iteradores y necesidad de contenedores auxiliares para preservar datos.
- [00:08:49] Operaciones primitivas de pilas (
push, pop, top) vs. colas (front, back).
-
[00:13:59] — Resolución Ejercicio 2B.1: Manipulaciones Básicas en Pilas
- Item A (
asignar_segundo_destructivo): Asignar $I$ al segundo elemento desde el tope eliminando los dos superiores (dos pop() y un push(I)).
- [00:17:40] Item B (
asignar_segundo_no_destructivo): Preservación del elemento superior mediante variable auxiliar antes de sobreescribir el segundo elemento.
- [00:24:50] Item C (
asignar_n_destructivo): Desapilar $N$ elementos usando bucle for / while y apilar el nuevo valor. Validación de tamaño (size() >= N).
- [00:31:56] Items D y E (
asignar_fondo): Vaciado total de la pila hacia una pila auxiliar para insertar en la base y posterior restitución no destructiva.
-
[00:35:08] — Resolución Ejercicio 2B.3: Reconocimiento de Cadenas Espejadas (
inverso)
- Consigna: determinar si una cadena $Z$ tiene la forma $X \cdot Y$ donde $Y$ es la inversa de $X$ (palíndromo par).
- Uso combinado de una pila (LIFO) y una cola (FIFO) para verificar la simetría carácter a carácter.
- [00:41:13] Verificación preliminar de paridad sobre la longitud de la cadena (
size() % 2 == 0).
- Poblado de estructuras (primera mitad en la cola y segunda mitad en la pila) y comparación simultánea con
top() y front().
- [00:54:00] Tratamiento de espacios en blanco: conveniencia de eliminarlos previamente sobre una copia para evitar falsos desbalances de paridad.
-
[00:58:46] — Resolución Ejercicio 2B.4: Ordenamiento de Lista mediante Pila Auxiliar (
sort_stack)
- Consigna: ordenar una lista $L$ de mayor a menor extrayendo sucesivamente el mínimo hacia una pila auxiliar $P$ y luego reinsertando en $L$.
- Implementación con doble bucle
while(!L.empty()) y búsqueda del mínimo con iteradores.
- [01:06:20] Importancia del orden de operaciones: realizar
P.push(*it_min) antes de L.erase(it_min) para no invalidar el dato.
- Repoblado final de la lista mediante
L.push_back(P.top()) y P.pop() aprovechando la inversión natural de la pila.
- [01:14:40] Discusión sobre optimizaciones y análisis de complejidad en el peor caso $\mathcal{O}(N^2)$.
-
[01:18:22] — Resolución Ejercicio 2B.5: Ordenamiento de Lista mediante Cola Auxiliar (
sort_queue)
- Comparación con el ejercicio anterior: extracción del mínimo hacia una cola auxiliar (FIFO) para ordenar de menor a mayor.
- Diferencias en la reconstrucción: uso de
push_back vs. push_front según la disciplina de salida de la cola.
-
[01:25:28] — Planteo y Visualización: Pancake Sorting sobre Pilas (Ejercicio 2B.6)
- Consigna: ordenar una pila únicamente invirtiendo prefijos/sub-rangos contiguos desde el tope.
- Demostración visual mediante animación: analogía de la pila de panqueques de distintos tamaños.
- Estrategia del algoritmo: localizar el elemento máximo no ordenado, voltear el prefijo hasta el tope para colocarlo arriba, y luego voltear todo el prefijo restante para depositarlo en su posición definitiva en la base.
-
[01:31:46] — Cierre de la Clase
- Avisos para continuar con la implementación en el foro de consultas y anticipo del tema Correspondencias (Maps).
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=7YngpCgffHg
CLASE PRÁCTICA VIERNES 2026-09-04
-
[00:00:00] — Introducción y Comparativa Conceptual: Pilas vs. Colas
- Pilas (
std::stack): Principio LIFO (Last-In, First-Out), analogía del lavaplatos y el mecanismo Deshacer (Ctrl+Z).
- Colas (
std::queue): Principio FIFO (First-In, First-Out), analogía de la fila de atención.
- Métodos fundamentales en pilas:
push, top (inspección) y pop (eliminación destructiva).
- [00:09:08] Implementación de función auxiliar
show_stack mediante paso por copia para vaciar y visualizar con top() y pop() sin alterar los datos originales.
-
[00:16:08] — Resolución Ejercicio 2B.1: Operaciones Básicas sobre Pilas
- Item A (Asignar al segundo elemento desapilando los dos superiores):
- Mecánica de dos
pop() y un push(I); manejo de validación previa de tamaño (size() >= 2) para prevenir desbordamientos.
- [00:21:13] Item B (Asignar al segundo elemento sin modificar la pila):
- Analogía de la pila de libros: resguardo del tope en variable auxiliar, inserción del nuevo valor y re-apilado del elemento original.
- [00:32:05] Item C (Asignar al enésimo elemento eliminando los superiores):
- Bucle de desapilado hasta la posición $N$ verificando
size() >= N e inserción del nuevo tope.
- [00:33:28] Item D y E (Asignar al fondo de la pila):
- Item D (vaciando la pila): Vaciado sistemático mediante
while(!S.empty()) S.pop(); y apilado único de $I$.
- Item E (sin modificar el contenido previo): Vaciado completo hacia una pila auxiliar, inserción de $I$ en la base y restitución no destructiva.
-
[00:38:53] — Resolución Ejercicio 2B.3: Reconocimiento de Cadenas Espejadas (
inverso)
- Consigna: determinar si una cadena $Z$ tiene la forma $X \cdot Y$ donde $Y$ es el reflejo inverso de $X$.
- Estrategia combinada: carga de la primera mitad en una pila (inversión por LIFO) y la segunda mitad en una cola (FIFO) para verificar coincidencias exactas con
top() y front().
- [00:49:40] Manejo de iteradores para partir la lista por la mitad (
size() / 2).
- [01:03:02] Tratamiento de Espacios en Blanco:
- Cálculo de longitud efectiva omitiendo espacios para validar la paridad.
- Avance condicional del contador de mitad compensando caracteres en blanco.
- Debate sobre costo algorítmico: depuración previa sobre copia vs. filtrado en una sola pasada.
-
[01:17:14] — Planteo de Ejercicio: Verificación de Paréntesis Embebidos (
chequeo) y Cierre
- Introducción al algoritmo de balanceo de paréntesis en expresiones aritméticas mediante pilas.
- Organización de la clase siguiente y despedida.
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=3FJU0cQd9PQ
CLASE PRÁCTICA LUNES 2026-09-07
-
[00:00:00] — Introducción y Algoritmo de Ordenamiento Pancake Sort (Guía 2B)
- Concepto del ordenamiento de la pila de panqueques (analogía de la espátula invertida en el tope).
- Estrategia paso a paso: localizar el elemento mayor de la subpila no ordenada, invertir hasta el tope para colocarlo arriba e invertir toda la subpila no ordenada para dejarlo en su posición final de la base.
- [00:11:53] Modularización: función
posicion_mayor e invertir rango de pila usando una cola auxiliar (FIFO).
- [00:26:28] Depuración en vivo: ajuste de índices (base 0 vs. base 1), control de rangos contiguos y visualización de traza.
- [00:33:00] Enfoque alternativo con tres pilas (original, espátula y mesa) y análisis de complejidad algorítmica ($\mathcal{O}(N^2)$).
- [00:38:45] Recursos visuales de algoritmos de ordenamiento y mención de ejercicios derivados (Burned Pancake Sort y colas rotativas).
-
[00:40:20] — Introducción al TAD Correspondencia (Map / Diccionarios)
- Definición matemática: correspondencia unívoca entre dominio (claves / keys) y contradominio (valores / values).
- Diferencias entre contenedores:
std::map (ordenado internamente por clave mediante árboles balanceados) vs. std::unordered_map (tablas hash).
- Propiedades esenciales: unicidad de claves (sin duplicados) y orden lexicográfico/numérico intrínseco.
- Representación como pares clave-valor (
std::pair) y acceso mediante miembros first (clave) y second (valor).
-
[00:48:20] — Resolución Ejercicio 2C.1: Descomposición de un Mapa en Listas (
map_to_list)
- Consigna: extraer por separado las listas de claves (
keys) y valores (vals) a partir de un mapa dado $M$.
- Recorrido secuencial con iteradores (
auto x : M) y extracción mediante x.first y x.second hacia listas con push_back.
-
[00:51:35] — Resolución Ejercicio 2C.2: Construcción de un Mapa a partir de Listas (
list_to_map)
- Consigna: dadas dos listas de claves y valores, construir el mapa $M$ asociando cada clave con su respectivo valor.
- Reglas de negocio y casos de borde:
- Sobreescritura: ante claves repetidas debe prevalecer la última asignación.
- Exceso de valores: ignorar los valores sobrantes cuando se terminan las claves.
- Falta de valores: asignar valor cero por defecto a las claves restantes.
- [01:00:20] Manejo y particularidades del
operator[]: inserción implícita con valor por defecto (0) cuando la clave consultada no existe previamente.
- Validación y pruebas en vivo sobre distintas combinaciones y longitudes de listas.
-
[01:07:30] — Recomendaciones de Estudio y Cierre
- Indicaciones para completar la sección de pilas y colas, y preparación para la siguiente clase de correspondencias.
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=AxpzMKOrORg
CLASE PRÁCTICA JUEVES 2026-09-10
-
[00:00:00] — Introducción y Repaso
- Revisión de los ejercicios anteriores de la Guía 2C:
map_to_list y list_to_map.
-
[00:02:04] — Resolución Ejercicio 2C.3: Correspondencias Inversas (
are_inverse)
- Condición matemática de inversión: $M_2(M_1(x)) = x$ para todo elemento, preservando el número de asignaciones.
- [00:12:09] Puesta en común de código:
- Validación rápida por tamaño (
M1.size() != M2.size()).
- Recorrido de pares de $M_1$, búsqueda en $M_2$ por clave (
M2.find(par.second)) y verificación de consistencia con par.first.
-
[00:21:14] — Resolución Ejercicio 2C.4: Fusión de Correspondencias (
merge_map)
- Planteo del problema: correspondencias de enteros a listas ordenadas de enteros (
map<int, list<int>>).
- [00:27:49] Repaso del algoritmo
merge de listas ordenadas (Ejercicio 14 de la Guía 2A).
- [00:46:14] Implementación de
merge_map:
- Casos base y salidas tempranas si alguno de los mapas está vacío (
empty()).
- Recorrido simultáneo con doble iterador comparando claves (
first).
- Tratamiento de colisión de claves: invocación a
merge_list sobre los valores asociados (second) para fusionar ambas listas en forma no decreciente.
- Vaciado de restos para mapas de distinta cantidad de claves.
-
[01:08:11] — Resolución Ejercicio 2C.5: Filtrado por Rango de Claves y Valores (
cutoff_map)
- Consigna: acotar el mapa al intervalo semiabierto $[P, Q)$ tanto a nivel de claves como en los elementos internos de cada lista de valores.
- Restricción: implementación in-place sin contenedores auxiliares.
- [01:19:05] Análisis y corrección de la lógica de depuración:
- Eliminación de claves fuera de rango mediante
it = M.erase(it) y actualización correcta del iterador.
- Recorrido y filtrado interno de la lista (
it->second).
- Eliminación automática de la clave si su lista asociada queda vacía (
it->second.empty()).
-
[01:29:49] — Resolución Ejercicio 2C.6: Aplicación de una Correspondencia sobre una Lista (
apply_map)
- Mapeo de elementos de una lista $L$ a través de $M$ hacia una lista resultante $ML$.
- Manejo de elementos ausentes en el dominio de $M$: omisión de la entrada sin insertar valores espurios.
- [01:38:00] Implementación con
M.find() y push a $ML$ sólo cuando find != M.end().
-
[01:50:20] — Planteo Ejercicio 2C.7: Verificación de Caminos en Grafos (
camino) y Cierre
- Modelado de grafos mediante correspondencias (vértice como clave y lista de adyacencia como valor).
- Estrategia de verificación de caminos válidos y despedida.
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=pUst6XCk7x4
CLASE PRÁCTICA VIERNES 2026-09-11
-
[00:00:00] — Repaso Conceptual: TAD Correspondencia (
std::map vs. std::unordered_map)
- Estructura interna: pares clave-valor (
std::pair) ordenados intrínsecamente por clave[cite: 9].
- [00:04:13] Diferencia entre
std::pair y std::map:
- El par almacena una tupla de dos valores; el mapa es una colección ordenada de pares con claves estrictamente únicas[cite: 9].
- Comportamiento ante claves duplicadas en inicializadores vs. sobreescritura con
operator[] o insert()[cite: 9].
- [00:15:09] Complejidad de búsqueda:
map::find logarítmica $\mathcal{O}(\log N)$ vs. búsqueda lineal $\mathcal{O}(N)$ en listas[cite: 9].
- Acceso a elementos del par mediante desreferenciación (
(*it).first) o puntero flecha (it->first y it->second)[cite: 9].
-
[00:21:57] — Resolución Ejercicio 2C.3: Correspondencias Inversas (
are_inverse)
- Consigna: determinar si dos mapas $M_1$ y $M_2$ son inversos ($M_2(M_1(x)) = x$ para toda asignación)[cite: 9].
- Validaciones iniciales: comparación de tamaños (
size()) y manejo de mapas vacíos (empty())[cite: 9].
- [00:49:40] Implementación del recorrido: búsqueda en $M_2$ del valor de $M_1$ (
it = M2.find(par.second)) y verificación de retorno frente a M2.end() y it->second == par.first[cite: 9].
- Depuración en vivo en ZinjaI: resolución de sintaxis con
const auto& par y acceso a miembros[cite: 9].
-
[01:02:19] — Resolución Ejercicio 2C.4: Fusión de Correspondencias (
merge_map)
- Planteo del problema: mapas con claves enteras y listas ordenadas de enteros como valor (
map<int, list<int>>)[cite: 9].
- Estrategia de resolución: volcado de $A$ en el mapa resultante $C$ y recorrido de $B$ detectando coincidencias de claves[cite: 9].
- [01:24:34] Manejo de colisión de claves: invocación de
merge_list para unificar de forma ordenada y no decreciente las listas asociadas a la misma clave[cite: 9].
- Pruebas de ejecución y revisión de la preservación del orden ascendente[cite: 9].
-
[01:41:05] — Resolución Ejercicio 2C.5: Filtrado por Rango In-Place (
cutoff_map)
- Consigna: eliminar del mapa $M$ todas las claves fuera del intervalo semiabierto $[P, Q)$, filtrar los elementos de cada lista fuera del mismo rango y eliminar la clave si su lista queda vacía[cite: 9].
- Restricción algorítmica: implementación in-place sin contenedores auxiliares[cite: 9].
- [01:57:00] Implementación de la depuración en dos niveles:
- Filtrado de claves con
it = M.erase(it) para no invalidar el recorrido[cite: 9].
- Filtrado interno de la lista (
it->second) en el bloque else[cite: 9].
- [02:10:30] Borrado de la clave principal cuando la lista interna queda vacía (
if (it->second.empty()) it = M.erase(it);)[cite: 9].
-
[02:16:38] — Cierre de la Clase y Próximos Temas
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=rtvh6G2CWXo
CLASE PRÁCTICA LUNES 2026-09-14
-
[00:00:00] — Introducción y Organización de la Clase
- Consultas generales sobre evaluaciones parciales y repaso de temas pendientes de la Guía 2C[cite: 10].
-
[00:03:08] — Resolución Ejercicio 2C.7: Verificación de Caminos en Grafos (
camino)
- Modelado de grafos no dirigidos mediante correspondencias: cada vértice como clave (
key) y su lista de adyacencias como valor (list<int>)[cite: 10].
- [00:12:00] Análisis de adyacencia y ordenamiento en listas de vecinos[cite: 10].
- [00:16:00] Implementación del algoritmo:
- Recorrido de vértices consecutivos en la lista $L$ ($u$ y $v$)[cite: 10].
- Búsqueda del vértice en el grafo con
G.find(u) y verificación contra G.end()[cite: 10].
- Búsqueda de $v$ dentro de la lista de adyacencia de $u$ con
std::find[cite: 10].
- Salida temprana en
false si alguna arista consecutiva no existe[cite: 10].
- [00:35:00] Visualización del grafo de pruebas mediante Graphviz[cite: 10].
-
[00:40:12] — Resolución Ejercicio 2C.8: Detección de Componentes Conexas (
componentes_conexas)
- Definición de grafo conexo y componentes conexas como subgrafos conexos disjuntos[cite: 10].
- Estructura de salida: lista de listas de enteros (
list<list<int>>)[cite: 10].
- [00:51:30] Estrategia de recorrido: Búsqueda en Anchura (BFS) / Profundidad (DFS) para expandir componentes completas[cite: 10].
- [01:03:20] Control de nodos visitados mediante un mapa auxiliar (
map<int, bool> visitados) para evitar ciclos y visitas redundantes[cite: 10].
- [01:13:00] Análisis del cierre transitivo de adyacencias y expansión recursiva de vecinos pendientes[cite: 10].
-
[01:29:20] — Resolución Ejercicio 2C.11: Verificación de Caminos Hamiltonianos (
es_hamiltoniano)
- Definición teórica: camino simple que visita cada vértice del grafo exactamente una vez[cite: 10].
- Diferencias entre camino y circuito hamiltoniano (cerrado), y caminos eulerianos (visita de aristas)[cite: 10].
- [01:43:00] Condiciones necesarias y filtros rápidos:
- Correspondencia exacta de longitud:
L.size() == G.size()[cite: 10].
- Unicidad de nodos en $L$ (sin vértices repetidos)[cite: 10].
- Revisión de grados mínimos en vértices intermedios[cite: 10].
- [01:50:00] Implementación del algoritmo y verificación de adyacencia secuencial entre nodos consecutivos[cite: 10].
- [01:58:00] Pruebas de ejecución en ZinjaI, depuración de casos de borde y validación sobre grafos no dirigidos simétricos[cite: 10].
-
[02:07:00] — Cierre de la Clase y Próximos Pasos
- Orientación sobre material bibliográfico (Rosen: teoría de grafos y árboles) y coordinación para la clase de Árboles[cite: 10].
🔗 Video completo en YouTube: https://www.youtube.com/watch?v=5Fx5dYTG_0I