Introducción

Este notebook es el complemento práctico, en código R, del documento teórico “Teoría y Ejercicios Resueltos: Regulación Económica”. Cada ejemplo y cada ejercicio propuesto en dicho documento se resuelve aquí paso a paso en RStudio, mostrando cómo traducir una fórmula económica a instrucciones de R, de modo que el estudiante aprenda simultáneamente la teoría y la programación.

La estructura sigue las cuatro unidades del documento original: monopolio natural, regulación de tarifas, discriminación de precios, y prácticas anticompetitivas en modelos de oligopolio.

Unidad 1: Monopolio Natural

Ejemplo resuelto: tres esquemas de tarifación

Con demanda \(P=100-Q\) y costos \(C(Q)=400+50Q\), se calculan la cantidad y el precio bajo tres esquemas de regulación: monopolio no regulado, tarifación a costo marginal, y tarifación a costo medio.

# Parametros del modelo
a <- 100      # intercepto de la demanda: P = a - Q
c <- 50       # costo marginal constante
F <- 400      # costo fijo

# --- Monopolio no regulado: IMg = CMg ---
# Demanda P = a - Q  =>  Ingreso total IT = P*Q = (a-Q)*Q = aQ - Q^2
# Ingreso marginal IMg = a - 2Q (derivada de IT respecto a Q)
# Se iguala IMg = CMg y se despeja Q
Q_m <- (a - c) / 2
P_m <- a - Q_m
beneficio_m <- P_m * Q_m - (F + c * Q_m)

cat("Monopolio no regulado:\n")
## Monopolio no regulado:
cat("  Q_m =", Q_m, " P_m =", P_m, " beneficio =", beneficio_m, "\n\n")
##   Q_m = 25  P_m = 75  beneficio = 225
# --- Tarificación a costo marginal: P = CMg ---
Q_cmg <- a - c   # despejando Q de: c = a - Q
P_cmg <- c
beneficio_cmg <- P_cmg * Q_cmg - (F + c * Q_cmg)
subsidio <- -beneficio_cmg

cat("Tarificación a costo marginal:\n")
## Tarificación a costo marginal:
cat("  Q =", Q_cmg, " P =", P_cmg, " beneficio =", beneficio_cmg,
    " subsidio requerido =", subsidio, "\n\n")
##   Q = 50  P = 50  beneficio = -400  subsidio requerido = 400
# --- Tarificación a costo medio: P = CMe(Q) = F/Q + c ---
# Se resuelve la ecuación cuadrática: a - Q = F/Q + c  =>  Q^2 - (a-c)Q + F = 0
coef_b <- -(a - c)
coef_c <- F
raices <- polyroot(c(coef_c, coef_b, 1))  # orden: término independiente, lineal, cuadrático
raices_reales <- Re(raices)
cat("Raíces de la ecuación cuadrática (tarificación CMe):", sort(raices_reales), "\n")
## Raíces de la ecuación cuadrática (tarificación CMe): 10 40
Q_cme <- max(raices_reales)   # la solución económicamente relevante es la de mayor Q
P_cme <- a - Q_cme
cat("Tarificación a costo medio (intersección de mayor Q):\n")
## Tarificación a costo medio (intersección de mayor Q):
cat("  Q =", round(Q_cme, 2), " P =", round(P_cme, 2), "\n")
##   Q = 40  P = 60

El resultado confirma lo obtenido a mano: monopolio en (25, 75) con beneficio 225, tarifación a costo marginal en (50, 50) con subsidio requerido de 400, y tarifación a costo medio en (40, 60) con beneficio nulo.

Ejercicio propuesto 1

Con demanda \(P=120-Q\) y costos \(C(Q)=800+60Q\), calcule en R los tres esquemas de tarifación (monopolio no regulado, tarifación a costo marginal y tarifación a costo medio), reutilizando la misma lógica del ejemplo anterior.

# Espacio para el desarrollo del alumno

Ejercicio propuesto 2

Escriba una función en R llamada costo_fragmentado(F, c, Q, n) que calcule el costo total de repartir una producción Q entre n empresas idénticas, cada una con costos F + c*(Q/n). Compare el resultado de dicha función, para n = 1, 2, 3, 4, 5, contra el costo de una sola empresa C(Q) = F + c*Q, y verifique que el costo fragmentado crece linealmente con n.

# Espacio para el desarrollo del alumno

Unidad 2: Regulación de Tarifas

Ejemplo resuelto: tasa de retorno y precio tope

# --- Regulacion por tasa de retorno ---
RB <- 10000000    # base tarifaria
r <- 0.08         # tasa de retorno permitida
OpEx <- 1200000   # costos operativos
D <- 500000       # depreciacion
Q <- 50000        # unidades vendidas

RR <- OpEx + D + r * RB
tarifa <- RR / Q

cat("Requerimiento de ingresos (RR) =", RR, "\n")
## Requerimiento de ingresos (RR) = 2500000
cat("Tarifa unitaria =", tarifa, "\n\n")
## Tarifa unitaria = 50
# --- Regulacion por precio tope (Price Cap, esquema RPI-X) ---
P0 <- 100
RPI <- 0.03
X <- 0.015

factor_ajuste <- 1 + RPI - X
P1 <- P0 * factor_ajuste

cat("Factor de ajuste anual =", factor_ajuste, "\n")
## Factor de ajuste anual = 1.015
cat("Precio del siguiente periodo P1 =", P1, "\n")
## Precio del siguiente periodo P1 = 101.5

Ejercicio propuesto 1

Una empresa de agua potable reporta \(RB=\text{S/}\,8\,000\,000\), \(r=10\,\%\), \(OpEx=\text{S/}\,900\,000\) y \(D=\text{S/}\,300\,000\), con \(Q=40\,000\) unidades vendidas. Calcule en R el requerimiento de ingresos y la tarifa unitaria.

# Espacio para el desarrollo del alumno

Ejercicio propuesto 2

Una empresa regulada bajo precio tope tiene \(P_0=\text{S/}\,80\), con \(RPI=4\,\%\) y \(X=2\,\%\) constantes cada año. Calcule en R el precio máximo permitido para los años 1, 2 y 3, utilizando un bucle for que aplique el factor de ajuste año tras año.

# Espacio para el desarrollo del alumno

Unidad 3: Discriminación de Precios

Ejemplo resuelto: discriminación de tercer grado en dos mercados

Una empresa vende en dos mercados con demandas \(P_1=100-Q_1\) y \(P_2=80-2Q_2\), y costo marginal constante \(CMg=20\). Se calcula la cantidad y el precio óptimos en cada mercado, los excedentes del consumidor y del productor, y se verifica el índice de Lerner con la elasticidad de cada mercado.

CMg <- 20

# --- Mercado 1: P1 = 100 - Q1 ---
# IMg1 = 100 - 2*Q1 (derivada del ingreso total (100-Q1)*Q1)
# Se iguala IMg1 = CMg y se despeja Q1
a1 <- 100; b1 <- 1
Q1 <- (a1 - CMg) / (2 * b1)
P1 <- a1 - b1 * Q1

# --- Mercado 2: P2 = 80 - 2*Q2 ---
a2 <- 80; b2 <- 2
Q2 <- (a2 - CMg) / (2 * b2)
P2 <- a2 - b2 * Q2

cat("Mercado 1: Q1 =", Q1, " P1 =", P1, "\n")
## Mercado 1: Q1 = 40  P1 = 60
cat("Mercado 2: Q2 =", Q2, " P2 =", P2, "\n\n")
## Mercado 2: Q2 = 15  P2 = 50
# --- Excedente del consumidor: area bajo la demanda menos el gasto total ---
# Para una demanda lineal P = a - b*Q, el area bajo la curva hasta Q* es: a*Q* - b*Q*^2/2
area_bajo_demanda_1 <- a1 * Q1 - b1 * Q1^2 / 2
CS1 <- area_bajo_demanda_1 - P1 * Q1

area_bajo_demanda_2 <- a2 * Q2 - b2 * Q2^2 / 2
CS2 <- area_bajo_demanda_2 - P2 * Q2

# --- Excedente del productor: (Precio - Costo marginal) * Cantidad ---
PS1 <- (P1 - CMg) * Q1
PS2 <- (P2 - CMg) * Q2

cat("Excedente del consumidor: CS1 =", CS1, " CS2 =", CS2, "\n")
## Excedente del consumidor: CS1 = 800  CS2 = 225
cat("Excedente del productor:  PS1 =", PS1, " PS2 =", PS2, "\n\n")
## Excedente del productor:  PS1 = 1600  PS2 = 450
# --- Verificacion del indice de Lerner: (P-CMg)/P = 1/elasticidad ---
# Mercado 1: Q1 = a1 - b1*P1  =>  dQ1/dP1 = -b1 = -1
elasticidad_1 <- b1 * (P1 / Q1)
lerner_1 <- (P1 - CMg) / P1

# Mercado 2: Q2 = (a2-P2)/b2  =>  dQ2/dP2 = -1/b2
elasticidad_2 <- (1 / b2) * (P2 / Q2)
lerner_2 <- (P2 - CMg) / P2

cat("Mercado 1: elasticidad =", elasticidad_1, " indice de Lerner =", round(lerner_1, 4),
    " 1/elasticidad =", round(1 / elasticidad_1, 4), "\n")
## Mercado 1: elasticidad = 1.5  indice de Lerner = 0.6667  1/elasticidad = 0.6667
cat("Mercado 2: elasticidad =", round(elasticidad_2, 4), " indice de Lerner =", lerner_2,
    " 1/elasticidad =", round(1 / elasticidad_2, 4), "\n")
## Mercado 2: elasticidad = 1.6667  indice de Lerner = 0.6  1/elasticidad = 0.6

Como el mercado 1 tiene una demanda más inelástica (elasticidad 1.5 frente a 1.667), la empresa cobra allí un margen proporcionalmente mayor, confirmando el teorema del índice de Lerner.

Ejercicio propuesto 1

Una empresa discrimina precios en dos mercados con demandas \(P_1=90-Q_1\) y \(P_2=60-3Q_2\), y costo marginal \(CMg=30\). Calcule en R \(Q_1,P_1,Q_2,P_2\), los excedentes del consumidor y del productor en cada mercado, y verifique el índice de Lerner con la elasticidad de cada mercado, reutilizando la lógica del ejemplo anterior.

# Espacio para el desarrollo del alumno

Unidad 4: Prácticas Anticompetitivas

Ejemplo resuelto: Cournot, cártel y sostenibilidad de la colusión

Con demanda \(P=100-Q_1-Q_2\) y costo marginal \(CMg=10\) para ambas empresas, se calcula el equilibrio de Cournot-Nash, el resultado bajo cártel, el beneficio de desviarse del acuerdo, y el factor de descuento crítico \(\delta^{*}\) necesario para sostener la colusión.

a <- 100
cmg <- 10

# --- Equilibrio de Cournot-Nash simétrico ---
# Formula derivada analiticamente: Qi_nash = (a-c)/3
Q_nash <- (a - cmg) / 3
P_nash <- a - 2 * Q_nash
pi_nash <- (P_nash - cmg) * Q_nash

cat("Cournot-Nash: Q por empresa =", Q_nash, " P =", P_nash, " beneficio por empresa =", pi_nash, "\n\n")
## Cournot-Nash: Q por empresa = 30  P = 40  beneficio por empresa = 900
# --- Cartel: cada empresa produce la mitad de la cantidad de monopolio ---
# Formula: Qi_cartel = (a-c)/4  (monopolio conjunto Q_total=(a-c)/2, dividido entre 2 empresas)
Q_cartel <- (a - cmg) / 4
P_cartel <- a - 2 * Q_cartel
pi_cartel <- (P_cartel - cmg) * Q_cartel

cat("Cartel: Q por empresa =", Q_cartel, " P =", P_cartel, " beneficio por empresa =", pi_cartel, "\n\n")
## Cartel: Q por empresa = 22.5  P = 55  beneficio por empresa = 1012.5
# --- Desviación óptima: dado que el rival mantiene Q_cartel, se maximiza el beneficio propio ---
# pi_dev(Q1) = (a - Q1 - Q_cartel - c)*Q1 ; FOC: a - 2*Q1 - Q_cartel - c = 0
Q_dev <- (a - cmg - Q_cartel) / 2
pi_dev <- (a - Q_dev - Q_cartel - cmg) * Q_dev

cat("Desviación óptima: Q =", Q_dev, " beneficio de desviarse =", pi_dev, "\n\n")
## Desviación óptima: Q = 33.75  beneficio de desviarse = 1139.062
# --- Factor de descuento crítico ---
delta_critico <- (pi_dev - pi_cartel) / (pi_dev - pi_nash)
cat("Factor de descuento crítico delta* =", delta_critico, "\n")
## Factor de descuento crítico delta* = 0.5294118
cat("Fraccion exacta 9/17 =", 9/17, "\n")
## Fraccion exacta 9/17 = 0.5294118

El resultado confirma que \(\delta^{*}=9/17\approx 0.529\), exactamente el valor que predice la teoría para cualquier duopolio de Cournot simétrico con demanda lineal, sin importar los parámetros de demanda o costo.

Función reutilizable para el modelo de Cournot

Para facilitar la resolución del ejercicio propuesto, se construye una función que automatiza todo el procedimiento anterior a partir de los parámetros a (intercepto de demanda) y c (costo marginal).

analizar_cournot <- function(a, c) {

  Q_nash <- (a - c) / 3
  P_nash <- a - 2 * Q_nash
  pi_nash <- (P_nash - c) * Q_nash

  Q_cartel <- (a - c) / 4
  P_cartel <- a - 2 * Q_cartel
  pi_cartel <- (P_cartel - c) * Q_cartel

  Q_dev <- (a - c - Q_cartel) / 2
  pi_dev <- (a - Q_dev - Q_cartel - c) * Q_dev

  delta_critico <- (pi_dev - pi_cartel) / (pi_dev - pi_nash)

  resultado <- data.frame(
    Escenario = c("Cournot-Nash", "Cartel", "Desviacion"),
    Cantidad = c(Q_nash, Q_cartel, Q_dev),
    Beneficio = c(pi_nash, pi_cartel, pi_dev)
  )

  list(tabla = resultado, delta_critico = delta_critico)
}

# Se reproduce el ejemplo anterior como prueba de la función
resultado_ejemplo <- analizar_cournot(a = 100, c = 10)
resultado_ejemplo$tabla
resultado_ejemplo$delta_critico
## [1] 0.5294118

Gráfico: funciones de reacción de Cournot

Las funciones de reacción de cada empresa, despejadas en el plano \((Q_1,Q_2)\), son \(Q_2=90-2Q_1\) (reacción de la empresa 1) y \(Q_2=45-Q_1/2\) (reacción de la empresa 2). El equilibrio de Cournot-Nash es el punto donde ambas rectas se cruzan.

Q1_vals <- seq(0, 90, by = 1)

# Reacción de la empresa 1: Q2 = 90 - 2*Q1 (solo válida para Q1 entre 0 y 45)
reaccion_1 <- ifelse(Q1_vals <= 45, 90 - 2 * Q1_vals, NA)

# Reacción de la empresa 2: Q2 = 45 - Q1/2
reaccion_2 <- 45 - Q1_vals / 2

# Frontera de colusion (cartel): Q1 + Q2 = 45
frontera_cartel <- ifelse(Q1_vals <= 45, 45 - Q1_vals, NA)

plot(Q1_vals, reaccion_1, type = "l", col = "blue", lwd = 2,
     xlim = c(0, 90), ylim = c(0, 90),
     xlab = "Cantidad de la empresa 1 (Q1)", ylab = "Cantidad de la empresa 2 (Q2)",
     main = "Funciones de reacción del duopolio de Cournot")
lines(Q1_vals, reaccion_2, col = "red", lwd = 2)
lines(Q1_vals, frontera_cartel, col = "darkgreen", lwd = 2, lty = 2)

points(30, 30, pch = 19, col = "black", cex = 1.4)
text(30, 30, labels = "Nash (30,30)", pos = 4, cex = 0.8)

points(22.5, 22.5, pch = 19, col = "gray40", cex = 1.4)
text(22.5, 22.5, labels = "Cartel (22.5,22.5)", pos = 1, cex = 0.8)

legend("topright",
       legend = c("Reacción empresa 1", "Reacción empresa 2", "Frontera de colusión"),
       col = c("blue", "red", "darkgreen"), lty = c(1, 1, 2), lwd = 2, bty = "n", cex = 0.8)

El punto negro confirma el equilibrio de Cournot-Nash (30,30) exactamente donde se cruzan ambas rectas de reacción, mientras que el punto gris (cártel) se ubica sobre la frontera de colusión, más cerca del origen.

Ejemplo resuelto: Bertrand y comparación de los tres regímenes de competencia

Con los mismos parámetros del ejemplo de Cournot (\(P=100-Q\), \(CMg=10\)), bajo competencia a la Bertrand el único equilibrio de Nash es \(P_1=P_2=CMg\), ya que cualquier precio por encima del costo marginal invita a que el rival lo subvalúe ligeramente y capture todo el mercado.

a <- 100
cmg <- 10

# Bertrand: el equilibrio siempre es P = CMg, sin importar el número de rivales (mientras haya al menos 2)
P_bertrand <- cmg
Q_bertrand <- a - P_bertrand
beneficio_bertrand <- 0  # por definicion, P=CMg implica beneficio economico nulo

cat("Bertrand: P =", P_bertrand, " Q total =", Q_bertrand, " beneficio =", beneficio_bertrand, "\n\n")
## Bertrand: P = 10  Q total = 90  beneficio = 0
# Tabla comparativa de los tres regimenes (usando los resultados ya calculados de Cournot y cartel)
comparacion_regimenes <- data.frame(
  Regimen = c("Cártel (Monopolio)", "Cournot", "Bertrand"),
  Precio = c(a - 2 * (a - cmg) / 4, a - 2 * (a - cmg) / 3, P_bertrand),
  Cantidad_total = c(2 * (a - cmg) / 4, 2 * (a - cmg) / 3, Q_bertrand)
)
comparacion_regimenes
barplot(
  rbind(comparacion_regimenes$Precio, comparacion_regimenes$Cantidad_total),
  beside = TRUE,
  names.arg = comparacion_regimenes$Regimen,
  col = c("indianred", "steelblue"),
  ylim = c(0, 100),
  ylab = "Precio (soles) / Cantidad total (unidades)",
  main = "Comparación de regímenes de competencia"
)
legend("topright", legend = c("Precio de mercado", "Cantidad total"),
       fill = c("indianred", "steelblue"), bty = "n", cex = 0.8)

A medida que aumenta la intensidad competitiva (de cártel a Cournot a Bertrand), el gráfico muestra cómo el precio cae y la cantidad total se expande, hasta alcanzar en Bertrand el resultado de competencia perfecta: la paradoja de Bertrand.

Ejercicio propuesto 1

Para un duopolio de Cournot con demanda \(P=90-Q_1-Q_2\) y \(CMg=6\), utilice la función analizar_cournot() creada anteriormente para calcular el equilibrio de Cournot-Nash, el resultado bajo cártel, la desviación óptima y el factor de descuento crítico. Compruebe que \(\delta^{*}\) coincide nuevamente con \(9/17\).

# Espacio para el desarrollo del alumno

Solucionario de los Ejercicios Propuestos

A continuación se resuelve, en R, cada uno de los ejercicios propuestos a lo largo del notebook.

Solución al Ejercicio 1 (Monopolio Natural)

a <- 120
c <- 60
F <- 800

Q_m <- (a - c) / 2
P_m <- a - Q_m
beneficio_m <- P_m * Q_m - (F + c * Q_m)
cat("Monopolio: Q =", Q_m, " P =", P_m, " beneficio =", beneficio_m, "\n")
## Monopolio: Q = 30  P = 90  beneficio = 100
Q_cmg <- a - c
subsidio <- F
cat("Tarificación CMg: Q =", Q_cmg, " P =", c, " subsidio =", subsidio, "\n")
## Tarificación CMg: Q = 60  P = 60  subsidio = 800
raices <- polyroot(c(F, -(a - c), 1))
Q_cme <- max(Re(raices))
P_cme <- a - Q_cme
cat("Tarificación CMe: Q =", round(Q_cme, 2), " P =", round(P_cme, 2), "\n")
## Tarificación CMe: Q = 40  P = 80

Solución al Ejercicio 2 (Monopolio Natural)

costo_fragmentado <- function(F, c, Q, n) {
  n * (F + c * (Q / n))
}

F <- 400
c <- 50
Q <- 100

for (n in 1:5) {
  costo_n <- costo_fragmentado(F, c, Q, n)
  cat("n =", n, " costo total fragmentado =", costo_n, "\n")
}
## n = 1  costo total fragmentado = 5400 
## n = 2  costo total fragmentado = 5800 
## n = 3  costo total fragmentado = 6200 
## n = 4  costo total fragmentado = 6600 
## n = 5  costo total fragmentado = 7000
cat("\nComparacion con formula general n*F + c*Q:\n")
## 
## Comparacion con formula general n*F + c*Q:
for (n in 1:5) {
  cat("n =", n, " n*F + c*Q =", n * F + c * Q, "\n")
}
## n = 1  n*F + c*Q = 5400 
## n = 2  n*F + c*Q = 5800 
## n = 3  n*F + c*Q = 6200 
## n = 4  n*F + c*Q = 6600 
## n = 5  n*F + c*Q = 7000

Como se observa, el costo total crece exactamente en incrementos de F (400) por cada empresa adicional, confirmando que la ineficiencia de fragmentar la producción aumenta linealmente con n.

Solución al Ejercicio 1 (Regulación de Tarifas)

RB <- 8000000
r <- 0.10
OpEx <- 900000
D <- 300000
Q <- 40000

RR <- OpEx + D + r * RB
tarifa <- RR / Q

cat("RR =", RR, "\n")
## RR = 2e+06
cat("Tarifa unitaria =", tarifa, "\n")
## Tarifa unitaria = 50

Solución al Ejercicio 2 (Regulación de Tarifas)

P0 <- 80
RPI <- 0.04
X <- 0.02
factor_ajuste <- 1 + RPI - X

P <- P0
for (anio in 1:3) {
  P <- P * factor_ajuste
  cat("Precio en el anio", anio, "=", round(P, 4), "\n")
}
## Precio en el anio 1 = 81.6 
## Precio en el anio 2 = 83.232 
## Precio en el anio 3 = 84.8966

Solución al Ejercicio 1 (Discriminación de Precios)

CMg <- 30

a1 <- 90; b1 <- 1
Q1 <- (a1 - CMg) / (2 * b1)
P1 <- a1 - b1 * Q1

a2 <- 60; b2 <- 3
Q2 <- (a2 - CMg) / (2 * b2)
P2 <- a2 - b2 * Q2

cat("Mercado 1: Q1 =", Q1, " P1 =", P1, "\n")
## Mercado 1: Q1 = 30  P1 = 60
cat("Mercado 2: Q2 =", Q2, " P2 =", P2, "\n\n")
## Mercado 2: Q2 = 5  P2 = 45
CS1 <- (a1 * Q1 - b1 * Q1^2 / 2) - P1 * Q1
CS2 <- (a2 * Q2 - b2 * Q2^2 / 2) - P2 * Q2
PS1 <- (P1 - CMg) * Q1
PS2 <- (P2 - CMg) * Q2

cat("CS1 =", CS1, " CS2 =", CS2, "\n")
## CS1 = 450  CS2 = 37.5
cat("PS1 =", PS1, " PS2 =", PS2, "\n\n")
## PS1 = 900  PS2 = 75
elasticidad_1 <- b1 * (P1 / Q1)
lerner_1 <- (P1 - CMg) / P1
elasticidad_2 <- (1 / b2) * (P2 / Q2)
lerner_2 <- (P2 - CMg) / P2

cat("Mercado 1: elasticidad =", elasticidad_1, " Lerner =", lerner_1, " 1/elasticidad =", round(1/elasticidad_1,4), "\n")
## Mercado 1: elasticidad = 2  Lerner = 0.5  1/elasticidad = 0.5
cat("Mercado 2: elasticidad =", elasticidad_2, " Lerner =", round(lerner_2, 4), " 1/elasticidad =", round(1/elasticidad_2,4), "\n")
## Mercado 2: elasticidad = 3  Lerner = 0.3333  1/elasticidad = 0.3333

Solución al Ejercicio 1 (Prácticas Anticompetitivas)

resultado_propuesto <- analizar_cournot(a = 90, c = 6)
resultado_propuesto$tabla
resultado_propuesto$delta_critico
## [1] 0.5294118
cat("\nComparacion con 9/17 =", 9/17, "\n")
## 
## Comparacion con 9/17 = 0.5294118

El factor de descuento crítico vuelve a ser exactamente \(9/17\approx 0.529\), confirmando que este valor es independiente de los parámetros de demanda y costo utilizados.

Cierre del notebook

Este notebook demostró que cada resultado del documento teórico de Regulación Económica puede reproducirse en R traduciendo directamente las fórmulas algebraicas a código, ya sea de forma manual o mediante funciones reutilizables como analizar_cournot(). Se recomienda que los estudiantes trabajen primero el desarrollo matemático de cada ejercicio propuesto en su cuaderno, y utilicen después el código de R únicamente para verificar su propio resultado.