Calcular los n primeros elementos del Conjunto de Wirth en C#

Abr 4, 2013 Codigos C# Tutoriales C# 7 comentarios

Cuando se empieza a estudiar recursividad en programación, generalmente se resuelve el clásico problema de Fibonacci o el Factorial, y ya después tal vez las Torres de Hanoi, que tal si entrenamos un poco con un ejercicio de conjuntos parecido a Fibonacci, a ver si de verdad entendimos como funciona la recursividad básica? Pues para esto les traigo este ejercicio resuelto, encontrar los primeros n elementos del conjunto de Wirth (que no estoy seguro si se refiere a Niklaus Wirth).

¿Qué rayos es el conjunto de Wirth?

El conjunto de Wirth es un subconjunto de los enteros positivos que cumple con la siguiente regla: el 1 pertenece al conjunto y si un numero k pertenece al conjunto entonces los numeros 2*k+1 y 3*k+1 pertenecen al conjunto.

Primero te reto a que trates de hacerlo solo, tal vez usando más o menos un código similar al de Fibonacci, que escribí hace un buen tiempo.

No diste con la solución?

Bueno, aquí está el código bien comentado:

//Función que retorna un array con los n primeros
//enteros del conjunto de Wirth
public static int[] EnesConjuntoWirth(int n)
{
    //Si n no es mayor que 1, solo habrá un elemento en el conjunto, el 1
    int[] result = (n>=1)? new int[n] : new int[0];
 
    //Empezamos el ciclo, que finalizará cuando
    //encontremos el n-esimo número de Wirth
    for(int i = 0, j = 1; i < n; j++)
        //Si J es de Wirth, lo añadimos al array
        if(EsDeWirth(j))
            //Aumentamos i también pq vamos a buscar el i+1 elemento
            result[i++] = j;
    //Retornamos el array
    return result;
}
 
//Este es el método recursivo que retorna true si n
//pertenece al conjunto de Wirth, parecido al de
//Fibonacci pero no tanto verdad??
private static bool EsDeWirth(int n)
{
    //Si n es 1, por supuesto que es de Wirth
    if(n == 1) return true;
 
    //Aquí está la magia, si es de la forma 2k+1 y k es de Wirth
    //o si es de la forma 3k+1 y k es de Wirth
    if((n%2 == 1 && EsDeWirth(n/2)) || (n%3 == 1 && EsDeWirth(n/3)))
        return true;
    //Si terminan los llamados recursivos, entonces no es de Wirth
    return false;
}
 
//Metodo Main para probar el algoritmo con la consola
static void Main()
{
    //Guardamos en el array los 50 primeros números del conjunto de Wirth
    int[] wirthConj = EnesConjuntoWirth(50);
 
    //Recorremos todos los números del array
    //y los imprimimos a ver si están bien
    for(int i=0; i<wirthConj.Length; i++)
        Console.WriteLine(wirthConj[i]);
 
    //para que no se cierre sola la consola ;)
    Console.ReadLine();
}

Compartir:

Relacionados

algunos artículos que te pueden interesar

7 comentarios

Forma parte de nuestra discusión y síguela de cerca

Hey! Q buen post @Yelinna, me parece excelente que lo programes en varios lenguajes, aunque fíjate, q puedes hacer par d mejoras en el de Linq ;)

Autor: Tomy | Fecha: Abr 21, 2013.

Tienes razón, Tomy, se le pueden hacer arreglos, pero especialmente uno y muy importante: calcular el doble de números de los requeridos es muy ineficiente. No se nota para cantidades pequeñas, tal vez de unos pocos miles, pero ¿qué ocurriría si un matenático loco desea usar mi algoritmo para calcular los primeros mil tropecientos zillones de números de Wirth? Desde ese punto de vista tu algoritmo está mucho mejor que el mío. Voy a ver si puedo arreglarlo.
Saludozzz!

Autor: Yelinna | Fecha: May 2, 2013.

Esto me recuerda mis primeras clases de recursividad y los ejercicios adicionales de programacion en el sitio de weboo.

Autor: Amy | Fecha: Jun 9, 2013.

Gracias amigo por entregarnos el conocimiento.

Autor: Richard Andres castillo | Fecha: Ago 8, 2013.

como terminar y mejorar este codigo!!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication72
{
class Program
{
static void Main(string[] args)
{
int o;
float[] datos = new float[10];
float[] vta = new float[10];
float[] vm1 = new float[10];
float[] vm2 = new float[10];
float[] vm3 = new float[10];
string[] nombre = new string[10];
do
{
Console.Clear();
Console.WriteLine(“MENU PRINCIPAL”);
Console.WriteLine(“1.LEER DATOS”);
Console.WriteLine(“2.VISUALIZAR DATOS”);
Console.WriteLine(“3.VENDEDOR CON MAYOR VENTAS ACUMULADAS”);
Console.WriteLine(“4.VENDEDOR CON MENOR VENTAS ACUMULADAS”);
Console.WriteLine(“5.PROMEDIO DE VENTAS POR MES”);
Console.WriteLine(“6.BUSCAR UN VENDEDOR”);
Console.WriteLine(“7.VENDEDORES CON VENTAS MAS ALTAS POR CADA MES”);
Console.WriteLine(“8.VENDEDORES CON VENTAS MAS BAJAS POR CADA MES”);
Console.WriteLine(“ELIGA SU OPCION: “);
o = int.Parse(Console.ReadLine());
switch (o)
{
case 1:
LEER(nombre, vm1, vm2, vm3);
break;
case 2:
ver(nombre, vm1, vm2, vm3);
break;
case 3:
vma(nombre, vm1, vm2, vm3);
break;
case 4:
vmen(nombre, vm1, vm2, vm3);
break;
case 5:
PVM (vm1, vm2, vm3);
break;
case 6:
buscart(nombre, vm1, vm2, vm3);
break;
case 7:
int vp1, vp2, vp3;
vp1 = (int)vpm1(nombre, vm1);
vp2 = (int)vpm2(nombre, vm2);
vp3 = (int)vpm3(nombre, vm3);
Console.WriteLine(“EL VENDEDOR CON MENOR VENTAS EN EL MES 1 ES: ” + nombre[vp1] + ” SU VENTA ES: ” + vm1[vp1]);
Console.WriteLine(“EL VENDEDOR CON MENOR VENTAS EN EL MES 2 ES: ” + nombre[vp2] + ” SU VENTA ES: ” + vm2[vp2]);
Console.WriteLine(“EL VENDEDOR CON MENOR VENTAS EN EL MES 3 ES: ” + nombre[vp3] + ” SU VENTA ES: ” + vm3[vp3]);
break;
} Console.ReadKey();
} while (o != 0);
}
static void LEER(string[] nombre, float[] vm1, float[] vm2, float[] vm3)
{
int s = 0;
for (s = 0; s < 2; s++)
{
Console.Write("NOMBRE DEL VENDEDOR: ");
nombre[s] = Console.ReadLine();
Console.Write("INGRESE LA VENTA DEL MES 1: ");
vm1[s] = float.Parse(Console.ReadLine());
Console.Write("INGRESE LA VENTA DEL MES 2: ");
vm2[s] = float.Parse(Console.ReadLine());
Console.Write("INGRESE LA VENTA DEL MES 3: ");
vm3[s] = float.Parse(Console.ReadLine());
}

}
static void ver(string[] nombre, float[] vm1, float[] vm2, float[] vm3)
{
int a;
string salida = "";
salida += "NOMBRE\t\tVENTA MES 1\tVENTA MES 2\tVENTA MES 3\n";

for (a = 0; a < 2; a++)
{
salida += nombre[a] + "\t\t" + vm1[a] + "\t\t" + vm2[a] + "\t\t" + vm3[a] + "\n";
}
Console.WriteLine(salida);
}
static void vma(string[] nombre, float[] vm1, float[] vm2, float[] vm3)
{
int a;
string pos = "";
float VMA = 0;
float[] vta = new float[10];
for (a = 0; a < 2; a++)
{
vta[a] = vm1[a] + vm2[a] + vm3[a];
}
for (a = 0; a VMA)
VMA = vta[a];
pos = nombre[a];
}
Console.WriteLine(“EL VENDEDOR CON MAYOR VEMTAS ACUMULADAS ES: ” + pos + ” Y SU VENTA ACUMULADA ES: ” + VMA);
}

static void vmen(string[] nombre, float[] vm1, float[] vm2, float[] vm3)
{
int a;
float[] vta = new float[10];

for (a = 0; a < 2; a++)
{
vta[a] = vm1[a] + vm2[a] + vm3[a];
}
float vm = vta[0];
string MN = "";
for (a = 1; a vta[a])
vm = vta[a];
MN=nombre[a];
}
Console.WriteLine(“EL VENDEDOR CON MENOR VENTAS ACUMULADAS ES:”+MN+” Y SU VENTAS ACUMULADAS ES: ” + vm);
}
static void PVM(float[] vm1, float[] vm2, float[] vm3)
{
int a;
float suma1=0,suma2=0,suma3=0;
float mes1=0, mes2=0, mes3=0;
for (a = 0; a < 2; a++)
{
suma1 = suma1 + vm1[a];
mes1=suma1/10;
suma2 = suma2 + vm2[a];
mes2 = suma2 / 10;
suma3 = suma3 + vm3[a];
mes3 = suma3 / 10;
}
Console.WriteLine("EL PROMEDIO DE VENTAS EN EL MES 1 ES: " + mes1);
Console.WriteLine("EL PROMEDIO DE VENTAS EN EL MES 2 ES: " + mes2);
Console.WriteLine("EL PROMEDIO DE VENTAS EN EL MES 3 ES: " + mes3);
}
static void buscart(string[] nombre, float[] vm1, float[] vm2, float[] vm3)
{
int a,c=0;
float va1=0,va2=0,va3=0;
string bd ="";
Console.WriteLine("INGRESE EL NOMBRE DEL VENDEDOR: ");
bd = Console.ReadLine();
for (a = 0; a < 2; a++)
{
if (bd == nombre[a])
{
c = a;
va1 = vm1[a];
va2 = vm2[a];
va3 = vm3[a];
}
}
Console.WriteLine("el vendedor ingresado esta en la posicion: " + (c+1) + " con ventas acumuladas1 de: " + va1 + " \nVENTAS ACUMULADAS2: " + va2 + " VENTAS ACUMULADAS3: " + va3);
}
static float vpm1(string[] nombre, float[] vm1)
{
float S;
int suma1 = 0;
int vpm=0, v,a;
for (a = 0; a vpm)
{

suma1 = a;
}
}
return (suma1);
}
static float vpm2(string[] nombre, float[] vm2)
{
int a, suma2 = 0;
float V = 0;
for (a = 0; a V)
{

suma2 = a;
}
}
return (suma2);
}
static float vpm3(string[] nombre, float[] vm3)
{
int a, suma3 = 0;
float P=0;
for (a = 0; a P)
{

suma3 = a;
}

} return (suma3);
}

}
}

Autor: juerghens | Fecha: Dic 3, 2013.

buenas amigos tengo una consulta sobre c# que talves me puedan ayudar, programe cuatro botones con el if y x++, pero el problema es que cuando depuro el programa y le doy al primer boton me da la selida en el puerto paralelo 2, pero si le doy a otro boton no me tira la señal en le otro puerto tengo que salir de la depuracion y luego darle al boton dos y asi si me da salida en le puerto 2, entoces mi pregunta es que hago para que si al tocar un boton y luego el otro y el otro den las salidas en los puertos paralelos sin estar saliendo de la depuracion, graciasss…

Autor: luis | Fecha: Abr 20, 2015.

Escribe tu comentario

Requerido.

Requerido. No público.

Si tienes alguno.