🎮 Juegos de Competición Real
Estos problemas están inspirados en competiciones reales de HP CodeWars (Barcelona, Valencia, León). Son el tipo de ejercicios que te encontrarás el día de la competición.
🎮 Juego 1: La Escalera Mágica (3 pts)
Dado el número de escalón N, ¿cuántas estrellas hay en ese escalón?
Entrada: 1
Salida: 1
Entrada: 4
Salida: 7
Entrada: 10
Salida: 19
💡 Pista 1: Observa el patrón
Mira la secuencia:
- Escalón 1 → 1 estrella
- Escalón 2 → 3 estrellas
- Escalón 3 → 5 estrellas
- Escalón 4 → 7 estrellas
¿Ves algo? Son los números impares: 1, 3, 5, 7...
💡 Pista 2: Fórmula de números impares
El n-ésimo número impar es: 2*n - 1
- n=1 → 2*1-1 = 1 ✓
- n=4 → 2*4-1 = 7 ✓
- n=10 → 2*10-1 = 19 ✓
🍌 Ver solución Minion (paso a paso)
# Leer el número de escalón
n = int(input())
# Observamos el patrón:
# Escalón 1 → 1 estrella
# Escalón 2 → 3 estrellas
# Escalón 3 → 5 estrellas
# Son números impares: 1, 3, 5, 7...
# El n-ésimo número impar es 2*n - 1
estrellas = 2 * n - 1
print(estrellas)
😎 Ver solución Gru (compacta)
n = int(input())
print(2 * n - 1)
🎮 Juego 2: El Detector de Espías (5 pts)
Dado un mensaje, responde "ALERTA" si es sospechoso o "SEGURO" si no lo es.
Entrada: Hola, esto es un mensaje normal
Salida: SEGURO
Entrada: El SeCrEtO está en la caja
Salida: ALERTA
Entrada: Nos vemos en secretolandia mañana
Salida: ALERTA
💡 Pista 1: Ignora mayúsculas
Convierte todo a minúsculas (o mayúsculas) antes de buscar.
mensaje = input().lower()
💡 Pista 2: Buscar substring
El operador in busca si una cadena está dentro de otra:
if "secreto" in mensaje:
# está!
🍌 Ver solución Minion (paso a paso)
# Leer el mensaje
mensaje = input()
# Convertir todo a minúsculas para comparar sin importar mayúsculas
mensaje_minusculas = mensaje.lower()
# Buscar si contiene la palabra "secreto"
if "secreto" in mensaje_minusculas:
print("ALERTA")
else:
print("SEGURO")
😎 Ver solución Gru (compacta)
mensaje = input().lower()
print("ALERTA" if "secreto" in mensaje else "SEGURO")
lower() + in + ternario en una línea. Combo perfecta.🎮 Juego 3: La Calculadora Romana (8 pts)
Números romanos: I=1, V=5, X=10, L=50, C=100, D=500, M=1000
Regla especial: IV=4, IX=9, XL=40, XC=90, CD=400, CM=900
Entrada:
3
X
V
III
Salida: 18
(X=10, V=5, III=3 → 10+5+3=18)
💡 Pista 1: Convierte cada número romano
Crea una función que convierta un número romano a decimal.
Recorre de izquierda a derecha. Si el valor actual es menor que el siguiente, resta; si no, suma.
💡 Pista 2: Diccionario de valores
valores = {'I':1, 'V':5, 'X':10, 'L':50,
'C':100, 'D':500, 'M':1000}
🍌 Ver solución Minion (paso a paso)
# Diccionario con los valores de cada letra
valores = {
'I': 1,
'V': 5,
'X': 10,
'L': 50,
'C': 100,
'D': 500,
'M': 1000
}
# Leer cuántas monedas hay
n = int(input())
suma_total = 0
# Procesar cada moneda
for moneda in range(n):
romano = input()
valor_moneda = 0
# Recorrer cada letra del número romano
i = 0
while i < len(romano):
letra_actual = romano[i]
valor_actual = valores[letra_actual]
# ¿Hay una letra después?
if i + 1 < len(romano):
letra_siguiente = romano[i + 1]
valor_siguiente = valores[letra_siguiente]
# Si la siguiente es mayor, hay que restar
if valor_siguiente > valor_actual:
valor_moneda = valor_moneda + (valor_siguiente - valor_actual)
i = i + 2 # Saltamos 2 letras
else:
valor_moneda = valor_moneda + valor_actual
i = i + 1
else:
valor_moneda = valor_moneda + valor_actual
i = i + 1
suma_total = suma_total + valor_moneda
print(suma_total)
😎 Ver solución Gru (compacta)
def romano_a_decimal(romano):
valores = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100, 'D':500, 'M':1000}
total = 0
for i in range(len(romano)):
if i + 1 < len(romano) and valores[romano[i]] < valores[romano[i+1]]:
total -= valores[romano[i]]
else:
total += valores[romano[i]]
return total
n = int(input())
print(sum(romano_a_decimal(input()) for _ in range(n)))
sum() con generador ahorra líneas.🎮 Juego 4: El Torneo de Ajedrez (10 pts)
Dados los resultados de N partidas (jugador1, jugador2, resultado), muestra la clasificación final ordenada por:
- Más puntos (descendente)
- Más victorias (descendente)
- Nombre alfabético (ascendente)
Entrada:
4
Ana Luis G
Luis Eva E
Eva Ana G
Ana Eva G
Salida:
Ana 6
Eva 4
Luis 1
(Ana: 2 victorias = 6pts, Eva: 1 victoria + 1 empate = 4pts, Luis: 1 empate = 1pt)
💡 Pista 1: Estructura de datos
Usa un diccionario donde guardes para cada jugador sus puntos y victorias:
jugadores = {}
# jugadores["Ana"] = {"puntos": 6, "victorias": 2}
💡 Pista 2: Procesar cada partida
if resultado == "G": # Gana jugador1
jugadores[j1]["puntos"] += 3
jugadores[j1]["victorias"] += 1
elif resultado == "P": # Pierde jugador1 (gana j2)
jugadores[j2]["puntos"] += 3
jugadores[j2]["victorias"] += 1
else: # Empate
jugadores[j1]["puntos"] += 1
jugadores[j2]["puntos"] += 1
💡 Pista 3: Ordenar con múltiples criterios
Convierte el diccionario a lista y ordena con lambda:
clasificacion = sorted(jugadores.items(),
key=lambda x: (-x[1]["puntos"], -x[1]["victorias"], x[0]))
🍌 Ver solución Minion (paso a paso)
# Leer número de partidas
n = int(input())
# Diccionario para guardar puntos y victorias de cada jugador
puntos = {}
victorias = {}
# Procesar cada partida
for i in range(n):
linea = input()
partes = linea.split()
jugador1 = partes[0]
jugador2 = partes[1]
resultado = partes[2]
# Asegurarnos que los jugadores existen en los diccionarios
if jugador1 not in puntos:
puntos[jugador1] = 0
victorias[jugador1] = 0
if jugador2 not in puntos:
puntos[jugador2] = 0
victorias[jugador2] = 0
# Asignar puntos según resultado
if resultado == "G":
# Gana jugador1
puntos[jugador1] = puntos[jugador1] + 3
victorias[jugador1] = victorias[jugador1] + 1
elif resultado == "P":
# Gana jugador2
puntos[jugador2] = puntos[jugador2] + 3
victorias[jugador2] = victorias[jugador2] + 1
else:
# Empate
puntos[jugador1] = puntos[jugador1] + 1
puntos[jugador2] = puntos[jugador2] + 1
# Crear lista para ordenar
lista_jugadores = []
for nombre in puntos:
lista_jugadores.append((nombre, puntos[nombre], victorias[nombre]))
# Ordenar: primero por puntos (mayor a menor), luego victorias, luego nombre
# Usamos bubble sort porque es fácil de entender
for i in range(len(lista_jugadores)):
for j in range(i + 1, len(lista_jugadores)):
a = lista_jugadores[i]
b = lista_jugadores[j]
# ¿Hay que intercambiar?
intercambiar = False
if b[1] > a[1]: # Más puntos
intercambiar = True
elif b[1] == a[1] and b[2] > a[2]: # Igual puntos, más victorias
intercambiar = True
elif b[1] == a[1] and b[2] == a[2] and b[0] < a[0]: # Alfabético
intercambiar = True
if intercambiar:
lista_jugadores[i] = b
lista_jugadores[j] = a
# Imprimir resultado
for jugador in lista_jugadores:
print(jugador[0], jugador[1])
😎 Ver solución Gru (compacta)
n = int(input())
jugadores = {}
for _ in range(n):
j1, j2, r = input().split()
for j in [j1, j2]:
if j not in jugadores:
jugadores[j] = {"p": 0, "v": 0}
if r == "G": jugadores[j1]["p"] += 3; jugadores[j1]["v"] += 1
elif r == "P": jugadores[j2]["p"] += 3; jugadores[j2]["v"] += 1
else: jugadores[j1]["p"] += 1; jugadores[j2]["p"] += 1
for n, d in sorted(jugadores.items(), key=lambda x: (-x[1]["p"], -x[1]["v"], x[0])):
print(n, d["p"])
sorted() con lambda y tupla de criterios. Negativo = descendente. ¡Ahorra 30 líneas!🎮 Juego 5: El Código del Tesoro (12 pts)
Direcciones: N (Norte, +Y), S (Sur, -Y), E (Este, +X), O (Oeste, -X)
Empezando en (0,0), ¿en qué coordenadas acabas después de seguir todas las instrucciones?
Entrada:
5
3N
2E
1S
4O
2N
Salida: -2 4
(Empiezas en (0,0). 3N→(0,3), 2E→(2,3), 1S→(2,2), 4O→(-2,2), 2N→(-2,4))
💡 Pista 1: Separa número y dirección
Cada instrucción tiene el número al principio y la letra al final:
instruccion = "3N"
pasos = int(instruccion[:-1]) # Todo menos el último = "3"
direccion = instruccion[-1] # El último = "N"
💡 Pista 2: Diccionario de movimientos
movimientos = {
'N': (0, 1), # Y aumenta
'S': (0, -1), # Y disminuye
'E': (1, 0), # X aumenta
'O': (-1, 0) # X disminuye
}
🍌 Ver solución Minion (paso a paso)
# Leer número de instrucciones
n = int(input())
# Posición inicial
x = 0
y = 0
# Procesar cada instrucción
for i in range(n):
instruccion = input()
# Separar el número de pasos y la dirección
# Ejemplo: "3N" → pasos = 3, direccion = "N"
direccion = instruccion[-1] # Última letra
pasos_texto = instruccion[:-1] # Todo menos la última
pasos = int(pasos_texto)
# Mover según la dirección
if direccion == "N":
y = y + pasos # Norte: subir (Y aumenta)
elif direccion == "S":
y = y - pasos # Sur: bajar (Y disminuye)
elif direccion == "E":
x = x + pasos # Este: derecha (X aumenta)
elif direccion == "O":
x = x - pasos # Oeste: izquierda (X disminuye)
# Mostrar posición final
print(x, y)
😎 Ver solución Gru (compacta)
n = int(input())
mov = {'N': (0,1), 'S': (0,-1), 'E': (1,0), 'O': (-1,0)}
x, y = 0, 0
for _ in range(n):
ins = input()
dx, dy = mov[ins[-1]]
x += dx * int(ins[:-1])
y += dy * int(ins[:-1])
print(x, y)
📚 Patrones que se repiten SIEMPRE
Después de ver muchos problemas de CodeWars, estos patrones aparecen una y otra vez. Memoriza estos trucos y los reconocerás al instante.
🔢 Secuencias numéricas — Busca la fórmula antes de hacer bucles
Fórmulas mágicas que aparecen mucho:
# Números impares: 1, 3, 5, 7...
impar_n = 2 * n - 1
# Suma de 1 a N: 1+2+3+...+N
suma = n * (n + 1) // 2
# Suma de impares hasta N: 1+3+5+...
suma_impares = n * n # ¡Es un cuadrado perfecto!
# Fibonacci (memoriza la lógica)
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
📝 Manipulación de Strings — El 50% de problemas usan esto
Los trucos más usados:
# Buscar ignorando mayúsculas
if "palabra" in texto.lower():
# Invertir un string
invertido = texto[::-1]
# ¿Es palíndromo?
es_palindromo = texto == texto[::-1]
# Quitar espacios y signos (solo letras)
limpio = "".join(c for c in texto if c.isalpha())
# Separar y volver a juntar
palabras = texto.split() # "a b c" → ["a","b","c"]
junto = " ".join(palabras) # ["a","b","c"] → "a b c"
🏆 Rankings y clasificaciones — Siempre el mismo patrón
Diccionario → Lista → Ordenar:
# 1. Guardar datos en diccionario
jugadores = {}
jugadores["Ana"] = {"puntos": 10, "goles": 3}
# 2. Ordenar con múltiples criterios
# Negativo = descendente, Positivo = ascendente
ranking = sorted(jugadores.items(),
key=lambda x: (-x[1]["puntos"], -x[1]["goles"], x[0]))
# 3. Imprimir
for nombre, datos in ranking:
print(nombre, datos["puntos"])
🗺️ Coordenadas y movimientos — Mapas, laberintos, robots
Diccionario de direcciones:
# Definir movimientos posibles
direcciones = {
'N': (0, 1), 'S': (0, -1),
'E': (1, 0), 'O': (-1, 0)
}
# También para las 8 direcciones (incluye diagonales)
vecinos = [(-1,-1), (-1,0), (-1,1),
(0,-1), (0,1),
(1,-1), (1,0), (1,1)]
# Mover
x, y = 0, 0
dx, dy = direcciones['N']
x, y = x + dx, y + dy
📊 Contar frecuencias — Letra más común, repetidos, etc.
Dos formas de hacerlo:
# Forma 1: Manual con .get()
freq = {}
for letra in texto:
freq[letra] = freq.get(letra, 0) + 1
# Forma 2: Con Counter (más fácil)
from collections import Counter
freq = Counter(texto)
# Encontrar el más común
mas_comun = max(freq, key=freq.get)
# Los 3 más comunes
top_3 = freq.most_common(3) # [('a', 5), ('b', 3), ('c', 2)]
🔄 Conversiones — Romano, binario, bases numéricas
Siempre usa diccionarios:
# Números romanos
romanos = {'I':1, 'V':5, 'X':10, 'L':50, 'C':100}
# Binario a decimal (sin usar int())
binario = "1011"
decimal = 0
for bit in binario:
decimal = decimal * 2 + int(bit)
# Decimal a binario (sin usar bin())
n = 11
bits = []
while n > 0:
bits.append(str(n % 2))
n //= 2
binario = "".join(bits[::-1]) # "1011"