1. Selección de Oponentes en un Torneo
En un torneo de tenis de mesa, dos equipos compiten, cada uno con tres jugadores. El Equipo A está formado por Alice, Bob y Charlie, mientras que el Equipo B lo integran Xavi, Yolanda y Zoe. Se conocen las siguientes restricciones: Alice no jugará contra Xavi, y Charlie no competirá ni contra Xavi ni contra Zoe. El objetivo es determinar todas las posibles combinaciones de emparejamientos, asegurando que cada jugador del Equipo A se enfrente a un único jugador del Equipo B.
#include <stdio.h>
int main() {
char oponenteAlice, oponenteBob, oponenteCharlie; // Representa los oponentes X, Y, Z
printf("Posibles emparejamientos para el torneo de tenis de mesa:\n");
// Iterar sobre las posibles asignaciones para Alice (X, Y, Z)
for (oponenteAlice = 'X'; oponenteAlice <= 'Z'; oponenteAlice++) {
// Iterar sobre las posibles asignaciones para Bob (X, Y, Z)
for (oponenteBob = 'X'; oponenteBob <= 'Z'; oponenteBob++) {
// Iterar sobre las posibles asignaciones para Charlie (X, Y, Z)
for (oponenteCharlie = 'X'; oponenteCharlie <= 'Z'; oponenteCharlie++) {
// Aplicar las reglas del juego y las restricciones dadas:
// 1. Cada jugador del Equipo A debe tener un oponente único del Equipo B.
// 2. Alice no juega contra Xavi.
// 3. Charlie no juega contra Xavi ni contra Zoe.
if (oponenteAlice != oponenteBob && // El oponente de Alice debe ser diferente al de Bob
oponenteAlice != oponenteCharlie && // El oponente de Alice debe ser diferente al de Charlie
oponenteBob != oponenteCharlie && // El oponente de Bob debe ser diferente al de Charlie
oponenteAlice != 'X' && // Restricción: Alice no juega contra Xavi
oponenteCharlie != 'X' && // Restricción: Charlie no juega contra Xavi
oponenteCharlie != 'Z') { // Restricción: Charlie no juega contra Zoe
printf("Alice vs %c, Bob vs %c, Charlie vs %c\n",
oponenteAlice, oponenteBob, oponenteCharlie);
}
}
}
}
return 0;
}
2. Suma de los Dígitos de un Número Entero
Este programa solicita al usuario un número entero y luego calcula la suma de todos sus dígitos. Por ejemplo, si el usuario introduce 31421, el resultado impreso será 11.
#include <stdio.h>
int main() {
int numeroEntrada;
int sumaDigitos = 0;
int digitoActual;
printf("Por favor, ingrese un número entero: ");
scanf("%d", &numeroEntrada);
// Iterar mientras el número sea mayor que 0
while (numeroEntrada > 0) {
digitoActual = numeroEntrada % 10; // Obtener el último dígito del número
sumaDigitos += digitoActual; // Añadir el dígito a la suma total
numeroEntrada /= 10; // Eliminar el último dígito del número para la siguiente iteración
}
printf("La suma de los dígitos es: %d\n", sumaDigitos);
return 0;
}
3. Verificación Sencilla de Número Primo
Este programa determina si un número entero proporcionado por el usuario es un número primo. Un número primo es un número natural mayor que 1 que no tiene divisores positivos más que 1 y él mismo.
#include <stdio.h>
#include <stdbool.h> // Para usar el tipo de dato booleano
int main() {
int numeroUsuario;
int divisor;
bool esPrimo = true; // Asumimos que el número es primo hasta que se demuestre lo contrario
printf("Ingrese un número entero para verificar si es primo: ");
scanf("%d", &numeroUsuario);
if (numeroUsuario <= 1) { // Los números 0, 1 y los negativos no son primos por definición
esPrimo = false;
} else {
// Un número primo solo es divisible por 1 y por sí mismo.
// Verificamos divisores desde 2 hasta numeroUsuario - 1.
// Para optimizar, se podría verificar solo hasta la raíz cuadrada del número.
for (divisor = 2; divisor < numeroUsuario; divisor++) {
if (numeroUsuario % divisor == 0) {
esPrimo = false; // Si encontramos un divisor, el número no es primo
break; // No necesitamos seguir buscando divisores
}
}
}
if (esPrimo) {
printf("%d es un número primo.\n", numeroUsuario);
} else {
printf("%d no es un número primo.\n", numeroUsuario);
}
return 0;
}
4. Ordenamiento Ascendente de un Arreglo
Este ejemplo demuestra cómo ordenar un arreglo de números enteros en orden ascendente utilizando un algoritmo de ordenamiento simple (ordenamiento de burbuja).
#include <stdio.h>
int main() {
int arregloNumeros[] = {23, 56, 24, 89, 14, 57, 95, 32};
// Calcular el tamaño del arreglo dinámicamente
int tamanoArreglo = sizeof(arregloNumeros) / sizeof(arregloNumeros[0]);
int tempIntercambio; // Variable temporal para realizar intercambios
printf("Arreglo original: ");
for (int k = 0; k < tamanoArreglo; k++) {
printf("%d ", arregloNumeros[k]);
}
printf("\n");
// Implementación del algoritmo de ordenamiento de burbuja
// Recorre el arreglo (tamanoArreglo - 1) veces
for (int i = 0; i < tamanoArreglo - 1; i++) {
// En cada pasada, el elemento más grande "burbujea" hasta su posición final
for (int j = 0; j < tamanoArreglo - 1 - i; j++) {
// Si el elemento actual es mayor que el siguiente, se intercambian
if (arregloNumeros[j] > arregloNumeros[j+1]) {
tempIntercambio = arregloNumeros[j];
arregloNumeros[j] = arregloNumeros[j+1];
arregloNumeros[j+1] = tempIntercambio;
}
}
}
printf("Arreglo ordenado: ");
for (int k = 0; k < tamanoArreglo; k++) {
printf("%d ", arregloNumeros[k]);
}
printf("\n");
return 0;
}
5. Encontrar Primos Sucesivos
El objetivo es implementar una función que identifique y almacene los k primeros números primos que son estrictamente mayores que un número m dado. Estos primos se guardarán en un arreglo.
#include <stdio.h>
#include <stdbool.h> // Para el tipo booleano
// Función auxiliar para verificar si un número es primo
bool esNumeroPrimo(int num) {
if (num <= 1) {
return false;
}
// Optimización: solo necesitamos verificar divisores hasta la raíz cuadrada del número
for (int i = 2; i * i <= num; i++) {
if (num % i == 0) {
return false; // Se encontró un divisor, no es primo
}
}
return true; // Si no se encontraron divisores, es primo
}
// Función principal: encuentra 'cantidadPrimos' primos mayores que 'limiteInferior'
// y los almacena en el arreglo 'arrPrimos'.
void buscarPrimosConsecutivos(int limiteInferior, int cantidadPrimos, int *arrPrimos) {
int contadorPrimosEncontrados = 0;
int numeroActual = limiteInferior + 1; // Comenzar la búsqueda desde el número siguiente a 'limiteInferior'
// Continuar buscando hasta que se haya encontrado la cantidad requerida de primos
while (contadorPrimosEncontrados < cantidadPrimos) {
if (esNumeroPrimo(numeroActual)) {
arrPrimos[contadorPrimosEncontrados] = numeroActual;
contadorPrimosEncontrados++;
}
numeroActual++; // Pasar al siguiente número para su verificación
}
}
int main() {
int valorM, valorK;
int arrayPrimosAlmacenados[20]; // Un arreglo para almacenar los primos (tamaño máximo 20)
printf("Ingrese un número límite inferior (m): ");
scanf("%d", &valorM);
printf("Ingrese la cantidad de primos a encontrar (k): ");
scanf("%d", &valorK);
// Validar que la cantidad de primos solicitada sea razonable para el tamaño del array
if (valorK <= 0 || valorK > 20) {
printf("La cantidad de primos (k) debe ser un número positivo y no exceder 20.\n");
return 1; // Salir con código de error
}
buscarPrimosConsecutivos(valorM, valorK, arrayPrimosAlmacenados);
printf("Los %d números primos consecutivos mayores que %d son:\n", valorK, valorM);
for (int i = 0; i < valorK; i++) {
printf("%d ", arrayPrimosAlmacenados[i]);
}
printf("\n");
return 0;
}
6. El Problema de los Monos y los Melocotones
Un mono recolecta melocotones. Cada día, el mono come la mitad de los melocotones restantes y, adicionalmente, un melocotón más. Al inicio del décimo día, el mono descubre que solo queda un melocotón. Este programa calcula cuántos melocotones había inicialmente el primer día, utilizando tanto un enfoque iterativo como uno recursivo.
#include <stdio.h>
// Enfoque iterativo: calculando la cantidad de melocotones hacia atrás
int calcularMelocotonesIterativo(int totalDias) {
int melocotonesDiaFinal = 1; // Sabemos que al inicio del día final (día 10) queda 1 melocotón.
int melocotonesDiaActual = melocotonesDiaFinal;
// Iteramos desde el día (totalDias - 1) hacia atrás hasta el día 1
for (int dia = totalDias - 1; dia >= 1; dia--) {
// Si 'M' melocotones quedaban al inicio del día siguiente,
// entonces al inicio del día actual había (M + 1) * 2 melocotones.
melocotonesDiaActual = (melocotonesDiaActual + 1) * 2;
}
return melocotonesDiaActual;
}
// Enfoque recursivo: la función devuelve los melocotones al inicio de un día específico.
// La base de la recursión es el día 10, donde conocemos la cantidad de melocotones.
int calcularMelocotonesRecursivo(int diaActual, int ultimoDiaConocido) {
if (diaActual == ultimoDiaConocido) {
return 1; // Al inicio del último día conocido (Día 10), queda 1 melocotón.
} else {
// La cantidad de melocotones al inicio del 'diaActual' se deriva
// de la cantidad de melocotones al inicio del día siguiente.
return (calcularMelocotonesRecursivo(diaActual + 1, ultimoDiaConocido) + 1) * 2;
}
}
int main() {
int numeroDeDias = 10;
printf("Problema de los Monos y los Melocotones:\n");
// Solución iterativa
int totalMelocotonesInicialIterativo = calcularMelocotonesIterativo(numeroDeDias);
printf("Cantidad inicial de melocotones (método iterativo): %d\n", totalMelocotonesInicialIterativo);
// Solución recursiva
// Llamamos a la función para calcular los melocotones al inicio del Día 1
int totalMelocotonesInicialRecursivo = calcularMelocotonesRecursivo(1, numeroDeDias);
printf("Cantidad inicial de melocotones (método recursivo): %d\n", totalMelocotonesInicialRecursivo);
return 0;
}
7. La Caja de Frutas
Se tiene una caja con una cantidad de manzanas que oscila entre 100 y 200. Si las manzanas se agrupan de 4 en 4, sobran 2. Si se agrupan de 7 en 7, sobran 3. Si se agrupan de 9 en 9, sobran 5. El programa determinará la cantidad exacta de manzanas en la caja.
#include <stdio.h>
int main() {
int cantidadManzanas;
printf("Buscando la cantidad de manzanas en la caja (entre 100 y 200):\n");
// Iterar a través de todos los números posibles de manzanas en el rango dado
for (cantidadManzanas = 100; cantidadManzanas <= 200; cantidadManzanas++) {
// Comprobar si se cumplen las tres condiciones simultáneamente
// 1. Al dividir por 4, el resto es 2 (cantidadManzanas % 4 == 2)
// 2. Al dividir por 7, el resto es 3 (cantidadManzanas % 7 == 3)
// 3. Al dividir por 9, el resto es 5 (cantidadManzanas % 9 == 5)
if ((cantidadManzanas % 4 == 2) &&
(cantidadManzanas % 7 == 3) &&
(cantidadManzanas % 9 == 5)) {
printf("La cantidad de manzanas en la caja es: %d\n", cantidadManzanas);
// Si asumimos que solo hay una solución en el rango, podemos salir del bucle
break;
}
}
return 0;
}
8. Suma de Series Aritméticas Concatenadas
Este programa calcula la suma de una serie de términos donde cada término está formado por la concatenación de un dígito base a un número n de veces. Por ejemplo, si a=2 y n=3, la suma sería 2 + 22 + 222 = 246.
#include <stdio.h>
int main() {
int digitoBase; // El dígito 'a' (ej. 2)
int numTerminos; // La cantidad de términos 'n' (ej. 3)
long long valorTerminoActual = 0; // Almacena el término actual (a, aa, aaa, etc.). Usamos long long para evitar desbordamientos.
long long sumaAcumulada = 0; // Almacena la suma total de la serie.
printf("Ingrese un dígito base (0-9): ");
scanf("%d", &digitoBase);
printf("Ingrese la cantidad de términos en la serie: ");
scanf("%d", &numTerminos);
// Validaciones básicas de entrada
if (digitoBase < 0 || digitoBase > 9) {
printf("Dígito base inválido. Debe ser un número entre 0 y 9.\n");
return 1;
}
if (numTerminos <= 0) {
printf("La cantidad de términos debe ser un número positivo.\n");
return 1;
}
// Calcular cada término y sumarlo
for (int i = 1; i <= numTerminos; i++) {
valorTerminoActual = valorTerminoActual * 10 + digitoBase; // Construye el siguiente término (ej. 2 -> 22 -> 222)
sumaAcumulada += valorTerminoActual; // Añade el término actual a la suma total
}
printf("La suma de la serie es: %lld\n", sumaAcumulada);
return 0;
}
9. Impresión de Patrones
Impresión de la Letra "K" (Patrón de Triángulos)
Este programa genera un patrón de asteriscos que, aunque no es la letra 'K' tipográfica, sigue la lógica de triángulos descendentes y ascendentes que se unen en un punto central. El patrón se forma con un número entero de entrada que define su tamaño.
#include <stdio.h>
int main() {
int tamanoPatron; // Representa el tamaño base del patrón
printf("Ingrese un número entero para el tamaño del patrón (2-20): ");
// El bucle permite la entrada de múltiples valores para probar diferentes patrones
while (scanf("%d", &tamanoPatron) == 1) {
if (tamanoPatron < 2 || tamanoPatron > 20) {
printf("El tamaño debe estar entre 2 y 20. Intente de nuevo: ");
continue; // Solicitar una nueva entrada si el tamaño es inválido
}
// Parte superior del patrón: triángulo descendente (de tamanoPatron+1 estrellas hasta 2 estrellas)
for (int fila = 0; fila < tamanoPatron; fila++) {
for (int col = 0; col <= tamanoPatron - fila; col++) {
printf("* ");
}
printf("\n");
}
// Línea central con una sola estrella
printf("*\n");
// Parte inferior del patrón: triángulo ascendente (de 2 estrellas hasta tamanoPatron+1 estrellas)
for (int fila = 1; fila <= tamanoPatron; fila++) {
for (int col = 0; col <= fila; col++) {
printf("* ");
}
printf("\n");
}
printf("\nIngrese otro número o Ctrl+D para salir: "); // Indicación para el usuario
}
return 0;
}
Impresión de un Rombo/Diamante
Este programa dibuja un patrón de rombo (o diamante) en la consola utilizando asteriscos y espacios. El tamaño del rombo está predefinido en este ejemplo, pero se puede ajustar cambiando la varible alturaMedia.
#include <stdio.h>
#include <math.h> // Necesario para la función abs()
int main() {
int alturaMedia = 2; // Define la "mitad" de la altura del diamante (para un total de 5 filas: -2, -1, 0, 1, 2)
int alturaTotal = alturaMedia * 2 + 1; // Calcula la altura total del diamante (ej. 5)
printf("Patrón de Rombo/Diamante:\n");
// Bucle para iterar a través de cada fila del diamante
// 'indiceFila' va desde -alturaMedia hasta +alturaMedia
for (int indiceFila = -alturaMedia; indiceFila <= alturaMedia; indiceFila++) {
// Imprimir los espacios iniciales para centrar el rombo
// La cantidad de espacios es proporcional al valor absoluto del indiceFila
for (int s = 0; s < abs(indiceFila); s++) {
printf(" ");
}
// Imprimir los asteriscos para la fila actual
// La cantidad de asteriscos disminuye o aumenta a medida que se aleja del centro
for (int a = 0; a < alturaTotal - 2 * abs(indiceFila); a++) {
printf("*");
}
printf("\n"); // Ir a la siguiente línea para la próxima fila del patrón
}
return 0;
}
10. Números Narcisistas
Un número narcisista (también conocido como número de Armstrong) es un número entero de n dígitos que es igual a la suma de las n-ésimas potencias de sus dígitos. Este programa identifciará todos los números narcisistas de tres dígitos (donde n=3). Por ejemplo, 153 es un número narcisista porque 1^3 + 5^3 + 3^3 = 1 + 125 + 27 = 153.
#include <stdio.h>
int main() {
int numeroActual; // El número de tres dígitos que estamos evaluando
int digitoUnidades, digitoDecenas, digitoCentenas;
int sumaCubosDigitos;
printf("Números narcisistas de tres dígitos:\n");
// Iterar a través de todos los números de tres dígitos, desde 100 hasta 999
for (numeroActual = 100; numeroActual < 1000; numeroActual++) {
// Extraer cada dígito del número
digitoUnidades = numeroActual % 10; // Obtener el dígito de las unidades
digitoDecenas = (numeroActual / 10) % 10; // Obtener el dígito de las decenas
digitoCentenas = numeroActual / 100; // Obtener el dígito de las centenas
// Calcular la suma de los cubos de cada dígito
sumaCubosDigitos = (digitoUnidades * digitoUnidades * digitoUnidades) +
(digitoDecenas * digitoDecenas * digitoDecenas) +
(digitoCentenas * digitoCentenas * digitoCentenas);
// Comprobar si la suma de los cubos de los dígitos es igual al número original
if (sumaCubosDigitos == numeroActual) {
printf("%d es un número narcisista.\n", numeroActual);
}
}
return 0;
}