Saber si es palíndromo o no, de forma recursiva

Hace unos días me pidieron por correo un programa que nos dijera si un string es palíndromo o no, pero usando una función recursiva. Me pareció interesante aunque raro que pidieran hacerlo de forma recursiva.

Tal vez recuerden que ya había publicado aquí una forma de saber si un string es palíndromo o no, el cual he descubierto (ahora que hice este otro) que no es muy eficiente.

Bueno pues el código es este:

#include
#include
using namespace std;
char cadenaf[50]={0}; int len, n=0;

string chk4palindrosity(int c)
{
    if(cadenaf[c] == cadenaf[len-1-c])
    {
        n++;
        if(n == len/2)
            return "Si es palindromo!";
        return chk4palindrosity(c+1);
    }
    else
        return "No es palindromo";
}

int main()
{
    char cadena[50],*parte;
    cout<<"Introduce un palindromo: "; cin.getline(cadena,50,'n');

    parte = strtok(cadena," ");                 //
    strcat(cadenaf,parte);                     //
    while((parte = strtok(NULL," ")) != NULL) //
        strcat(cadenaf,parte);               // quitar espacios del string

    len = strlen(cadenaf);
    cout << chk4palindrosity(0);
    cin.get();
}

La verdad es que es la función es recursiva de puro milagro. Lo que hice fue transformar el ciclo que checaba que los caracteres fueran iguales en una función en la que se aumenta una variable cada vez que se llama a sí misma.

El código ahora es más eficiente por dos simples razones:

  1. Se detiene y da el resultado a la primera comparación de caracteres que no sean iguales. Si el primer y el último caracter no son iguales, no es palíndromo y ya no sigue analizando los demás.
  2. Sólo checa la mitad de los caracteres. Si la mitad de los caracteres corresponden a la configuración de un palíndromo, ya no hay porqué seguir analizando la otra mitad.

Tal vez una mejor manera de hacerlo sería con una función que recibiera el string a analizar, comparar el primer y último caracter: si no, no es; si si, eliminar el primer y último caracter y volver a llamar a la función. Esto hasta que el numero de comparaciones ciertas sea igual a la mitad de la longitud inicial del string. ¿Alguien se anima a hacerlo?

Advertisements

Imprimir determinados números primos

Sobre números primos he escrito bastantes programas y me he dado cuenta de que los profesores de programación tienen cierta fijación con ellos. Pero bueno, el programa de hoy imprime la cantidad de números primos que el usuario quiera y es interesante porque es un buen ejemplo de la utilidad de los ciclos infinitos, que ya habíamos visto antes.

Ok, el código es este:

#include
using namespace std;

int main()
{
    int cnt,i=0,ii,res,nc=0,np=0;
    cout <> cnt;
    for(;;)
    {
        i++;
        for(ii=1;ii<=i;ii++)
        {
            res=i%ii;
            if(res==0)
                nc=nc+1;
        }
        if(nc==2)
        {
            cout << i << " ";
            np++;
        }
        nc=0;
        if(np==cnt)
            break;
    }
}

Si tienen problemas para entender cómo obtuvimos los números primos, deberían darle una revisada a estos posts: Saber si es primo o no y Primos en un rango.

Lo que hicimos es que todo el programa estuviera dentro de un ciclo infinito que se detendrá cuando nuestra variable que se aumenta cada vez que obtenemos un numero primo np sea igual a la variable con la cantidad deseada de números primos cnt.

Pero recuerden que donde podemos usar un ciclo infinito, queda mucho mejor un ciclo while:

#include
using namespace std;

int main()
{
    int cnt,i=0,ii,res,nc=0,np=0;
    cout <> cnt;
    while(np!=cnt)
    {
        i++;
        for(ii=1;ii<=i;ii++)
        {
            res=i%ii;
            if(res==0)
                nc=nc+1;
        }
        if(nc==2)
        {
            cout << i << " ";
            np++;
        }
        nc=0;
    }
}

Únicamente ponemos la palabra while en lugar de for, copiamos la condición que ‘condicionaba’ (sí, lo se) el break y la pegamos dentro de los paréntesis del while pero de manera contraria (de == a != o de ).

No se hacen proyectos finales

Bueno pues lo dejé muy claro en el título ¿no? pero lo repito, no se hacen proyectos finales. Cuando cree este blog lo hice pensando en ayudar a todos los estudiantes de programación en c++ que necesitan algún empujón para lograr hacer sus propios programas.

Tengo pruebas para decir que casi nunca me niego a hacer programas pequeños que me piden por correo o por comentarios, pero cuando me llegan correos pidiendo que les haga un programa que “lleve el control del inventario de un almacén registrando cada entrada y salida de producto… pidiendo tipo, cantidad, numero de control, precio… imprimiendo al final del día el reporte….. y que además haga los cálculos para…. en formato de…  y con 7 menús con… con un apartado de ayuda…. para mañana por favor” pues ni les respondo.

La verdad es que no se vale. Durante todo el año estuvieron haciendo programas sencillos con los que era totalmente válido pedir ayuda, pero no, piden ayuda hasta el final del semestre cuando les encargan un proyecto final.

Recuerden que yo también soy un estudiante y en estos días también estuve ocupadísimo con tareas y trabajos. Por eso no había publicado nada. ¡Pero ya estoy de vacaciones!, así que ya voy a tener un poco más de tiempo para atender mis blogs 🙂

Clasificar números en C++

Por medio de un comentario Gaby me pidió un programa que:

“Genere 10 números aleatorios del 0 al 50 y los clasifique en 2 rangos: menores que 10 y mayores que 10 pero menores que 20.”

A nosotros nos sirve para practicar el uso de números random, de matrices y de ciclos.

El programa es este:

#include
#include
#include
using namespace std;
int main()
{
    int numrnd[10], cls1[10]={0}, cls2[10]={0}, ct1=0, ct2=0;
    srand(time(NULL));
    cout << "Los numeros: ";
    for(int i=0; i<=9; i++)
    {
        numrnd[i] = rand() % 51;
        cout << numrnd[i] << ", ";
        if(numrnd[i]  10 && numrnd[i] < 20)
        {
            cls2[ct2] = numrnd[i];
            ct2++;
        }
    }
    cout << endl << "Menores que 10: ";
    for(int i=0; i<ct1; i++)
        cout << cls1[i] << ", ";
    cout << endl << "Mayores que 10 y menores que 20: ";
    for(int i=0; i<ct2; i++)
        cout << cls2[i] << ", ";
}
  • Para dudas respecto a la generación de números random está este post: Obtener números aleatorios en C++.
  • Para dudas respecto a la declaración y uso de matrices está este otro post: ¡Ah nunca he escrito sobre matrices!, voy a tener que ponerme a ello.
  • Para dudas con respecto a los ciclos for, sí tengo un post: Ciclos for en C++.

Tenemos 3 matrices, en la primera guardamos nuestros 10 números aleatorios, en la segunda los números que queden en la primera clasificación (menores que 10) y en la tercera los que queden en la segunda clasificación. Así que lo que hacemos es ir traspasando los valores de la primera matriz a las otras dos según su valor. Para esto tenemos que llevar en el mismo ciclo 3 cuentas diferentes, una para cada matriz.

Las variable ct1 y ct2 se encargan de ir cambiando los índices de las matrices cls1 y cls2 respectivamente, por lo que sólo deben aumentar cuando en realidad sea necesario.

Después lo único necesario es mostrar nuestras dos matrices. Como cada matriz puede tener un número de elementos diferentes cada vez, tenemos que hacer dos ciclos, uno para cada matriz con ct1 o ct2 como límite.

Como última aclaración sólo digo que, tal como dice el problema, el número 10 nunca va a quedar clasificado en algún rango porque el 10 no es menor que 1o y tampoco es mayor que 10.

Convertir segundos a horas, minutos y segundos

Como les prometí en el post anterior, en este post vamos a hablar sobre un programa que usa los operadores compuestos de manera muy útil: convierte los segundos en horas minutos y segundos.

El programa es este:

#include 
using namespace std;

int main()
{
    int sec, hr, min;
    cout <> sec;
    cout << sec << " segundos son ";
    hr = sec / (60*60);
    sec %= 60*60;
    min = sec / 60;
    sec %= 60;
    cout << hr << " horas " << min << " minutos y " << sec << " segundos" << endl;
}

Primero dividimos los segundos sec entre 60*60 (3600) para obtener los horas y lo guardamos en hr. Noten que la variable sec no cambia.

Luego obtenemos el residuo de dividir sec / 60*60 (es lo que el operador % hace) y lo guardamos en la misma variable. En este paso sí modificamos la variable sec, ahora contiene los segundos iniciales menos las horas que ya obtuvimos en el paso anterior.

Ahora dividimos nuevamente la variable sec / 60 para obtener los minutos y lo guardamos en hr. La variable sec no cambia.

Luego obtenemos el residuo de dividir sec / 60 (es lo que el operador % hace) y lo guardamos en la misma variable. En este paso sí modificamos la variable sec, ahora contiene los segundos iniciales menos las horas menos los minutos.

Ya sólo mostramos las tres variable y listo.

Ahora, si somos de los que nos preocupamos por el lenguaje, veremos que a veces hay errores de ortografía como “1 minutos”. Para solucionar eso sólo necesitamos unos cuantos ifs:

#include 
using namespace std;

int main()
{
    int sec, hr, min;
    cout <> sec;
    cout << sec << " segundos son ";
    hr = sec / (60*60);
    sec %= 60*60;
    min = sec / 60;
    sec %= 60;
    cout << hr << " hora";
    if(hr != 1) cout << "s";
    cout << " " << min << " minuto";
    if(min != 1) cout << "s";
    cout << " y " << sec << " segundo";
    if(sec != 1) cout << "s";
}

Operadores compuestos en C++

Los operadores (en cualquier lenguaje de programación) son los símbolos que permiten hacerle una operación a una o más variables. Los más conocidos son los operadores aritméticos:

  • + Suma
  • Resta
  • * Multiplicación
  • / División
  • % Módulo (residuo de la división)

Otros son los lógicos (&&, ||), los relacionales (<, >, !=, ==), etc. Pero en este post, como dice el título, vamos a ver los operadores compuestos en c++.

¿Cómo haríamos para sumarle a una variable int, por ejemplo, 3 unidades? Alguien que nunca hubiera programado escribiría algo así:
mivar + 3;
Sabemos que eso no es válido porque una suma retorna un valor (el resultado) y ese valor tiene que ser almacenado en una variable. En el código anterior ese valor no se almacena en ninguna variable, por lo tanto ERROR. Sabiendo esto último podemos escribir esto:
mivar = mivar + 3;
En la variable mivar, guardamos el contenido de esa misma variable más tres. Todo bien ¿no? eso es perfectamente válido y normal, sin embargo los operadores compuestos nos permiten hacer lo mismo con menos código:
mivar += 3;
Como ven está inspirado en hacer que ‘lo-primero-que-se-nos-ocurre’ sea posible.

Así tenemos que:

mivar = mivar + 3; es lo mismo que mivar += 3;
mivar = mivar - 3; es lo mismo que mivar -= 3;
mivar = mivar * 3; es lo mismo que mivar *= 3;
mivar = mivar / 3; es lo mismo que mivar /= 3;

Bueno, para ver un poco de la utilidad de estos operadores y haciéndole un favor a un tal Victor, vamos a ver un programa que imprima los múltiplos de un cierto número (introducido por el usuario) que haya desde 1 hasta otro cierto número (introducido por el usuario):

#include
using namespace std;
int main()
{
    int num, lims, m=0;
    cout <> num;
    cout <> lims;
    while(lims >= (m+=num))
    {
        cout << m << ", ";
    }
}

Primero pedimos el número del cual queremos obtener múltiplos (num), luego el límite superior (lims). m obtendrá el valor de los múltiplos y lo tenemos que igualar a 0 al inicio.

Luego tenemos un ciclo while. En español dice: “Me mantendré ejecutando mientras el lims sea mayor o igual a m más num“. Dentro del ciclo mostramos la variable m.

Si, por ejemplo, num = 3, entonces la instrucción n+=num se desarrolla así:
m = 0;
m+=num; -----> m= m + num; -----> m = 0 + 3; -----> m = 3;
m+=num; -----> m= m + num; -----> m = 3 + 3; -----> m = 6;
m+=num; -----> m= m + num; -----> m = 6 + 3; -----> m = 9;
etc, etc.

Aquí podría poner un otro programa aún más útil para usar los operadores compuestos, pero mejor lo dejo para el siguiente post. Ah y si tú eres Victor, entonces tal vez te interese este post: Cómo contar el número de veces que sucede algo.

Tipos de funciones en C++

Los tipos de funciones en c++ son 4, aunque en realidad son las combinaciones de las 2 cosas que una función puede hacer. Si andan perdidos en cuanto a funciones les recomiendo leer mi post anterior: Funciones en C++.

Una función, como les decía, puede hacer (o no) dos cosas: 1 – Recibir datos y 2 – Retornar datos. De esto surgen los cuatro tipos de funciones:

  1. No reciben ni retornan
  2. Reciben y no retornan
  3. No reciben y retornan
  4. Reciben y retornan

Vamos a hacer un programa que sume dos números, usando los cuatro tipos de funciones:

No reciben ni retornan

Las más sencillas. Para usarlas sólo tenemos que saber cómo crearlas y cómo llamarlas. Una función se crea de esta forma general:
tipo nombre(){}
El ‘tipo’ se refiere al tipo de dato (int, float, void, char) y en las funciones que no retornan siempre es void.

El ‘nombre’ es el nombre de la función: cualquiera que empiece con una letra, que sea significativo y que no sea una palabra reservada.

Para llamarlas sólo hay que escribir el nombre de la función seguido de sus paréntesis y un punto y coma (;).
nombre();

Así nuestro programa sería:

#include
using namespace std;

void sumar()
{
    int num1, num2, r;
    cout <> num1;
    cout <> num2;
    r = num1 + num2;
    cout << "La suma es " << r;
}

int main()
{
    sumar();
}

Como ven, todo lo que habríamos puesto en nuestro main mejor los pusimos en una función y desde el main la llamamos. Una función siempre, siempre, siempre tiene que ir antes del main.

Una función de este tipo que hemos usado muchas veces es getch();

Reciben y No Retornan

¿Cómo haríamos para pedir los dos números en el main y que la función haga la suma? Para eso tenemos que hacer una función capaz de recibir datos, entonces la sintaxis cambia un poco:
tipo nombre(tipo_var1 nombre_var1, tipo_var2 nombre_var2){}
‘tipo’ y ‘nombre’ se refieren a lo mismo y como no retorna el tipo siempre es void.

Dentro del paréntesis tenemos otros aspectos:

‘tipo_var1’ se refiere al tipo de la variable que nuestra función va a recibir.

‘nombre_var1’ se refiere al nombre de esa variable.

Si queremos recibir una variable hasta ahí es suficiente, si queremos otra variable ponemos una coma (,) y declaramos la siguiente variable.

Para llamar la función hay que poner la variables que vamos a enviar dentro del paréntesis en el mismo orden en que las declaramos en la función:
nombre(var1, var2);

Nuestro programa quedaría así:

#include
using namespace std;

void sumar(int num1, int num2)
{
    int r;
    r = num1 + num2;
    cout << "La suma es " << r;
}

int main()
{
    int num1, num2;
    cout <> num1;
    cout <> num2;
    sumar(num1, num2);
}

Pedimos los dos números en el main, los enviamos a la función, ésta los suma y los muestra.

Una función de este tipo que hemos usado muchas veces es el odiado por muchos, amados por otros, gotoxy(x,y);

Retornan y No Reciben

¿Y si ahora queremos lo contrario? Pedir los números en la función, pero mostrar el resultado en el main. Para eso necesitamos una función que retorne.

Recibir es enviar datos del main a la función. Retornar es enviar datos de la función al main. Para retornar datos hay que hacer dos cosas: no usar void como tipo y usar return.

De forma general:
tipo nombre() { return var; }
El ‘tipo’ tiene que ser del tipo de variable que queremos retornar, si nuestra variable retorna una variable int, pues el tipo de la función es int.

Para indicar qué variable estamos retornando usaremos la palabra return seguido de la variable. Usualmente esto va al final de la función.

Para llamar a la función hay que preparar un colchón en donde caiga la variable que está retornando.
var = nombre();
La variable que está retornando nuestra función se va a almacenar en la variable ‘var’. Este es un buen momento para recordarles que las variables declaradas entre dos llaves {} únicamente existen entre esas dos llaves. O sea que la variable ‘var’ de la función no es la misma que la variable ‘var’ de la función; sin embargo la var del main está adquiriendo el valor de la var del main. Un poco confuso lo se, no se preocupen.

Nuestro programa quedaría así:

#include
using namespace std;

int sumar()
{
    int num1, num2, r;
    cout <> num1;
    cout <> num2;
    r = num1 + num2;
    return r;
}

int main()
{
    int r;
    r = sumar();
    cout << "La suma es " << r;
}

¿A alguien se le ocurre una función conocida de este tipo?

Reciben y Retornan

Ahora queremos que nuestra función únicamente sume, el main se va a encargar de pedir los números y sumar los resultados. Para eso necesitamos que nuestra función reciba las variables y además retorne el resultado. ¡Wow! ¿Es acaso eso posible? Claro que sí.

Es sólo cuestión de combinar las funciones que reciben y no retornan con las que retornan y no reciben.

Nuestro programa quedaría así:

#include
using namespace std;

int sumar(int num1, int num2)
{
    int r;
    r = num1 + num2;
    return r;
}

int main()
{
    int num1, num2, r;
    cout <> num1;
    cout <> num2;
    r = sumar(num1, num2);
    cout << "La suma es " << r;
}

Las funciones de la librería math.h son en su mayoría de este tipo. sqrt(); pow(); sin();

En principio puede parecer que las funciones sirven únicamente para organizar el código, lo cual es cierto, pero no sólo eso. ¿Se imaginan si tuviéramos que escribir todo el código detrás de un simple gotoxy();? Ah verdad…

Bueno, no me iba a quedar tranquilo si no les mostraba la versión optimizada de la última función:

#include
using namespace std;

int sumar(int num1, int num2)
{
    return num1 + num2;
}

int main()
{
    int num1, num2;
    cout <> num1;
    cout <> num2;
    cout << "La suma es " << sumar(num1, num2);
}

😀

Funciones en C++

Supongo que ya es hora de retomar el blog y ponerme a hablar de funciones en c++. Una función es un pedazo de código fuera del main, con un nombre y que puede ser ‘llamado’ desde otra parte de nuestro programa.

Imagínense que están entrenando a su perro a hacerse el muertito. Cada vez que ustedes dicen ‘muertito‘, el perro se tira de espaldas en el suelo, cierra los ojos y saca la lengua. En programación, el contenido de la función sería tirarse de espaldas, cerrar los ojos y sacar la lengua; el nombre de la función sería muertito; y cada vez que nosotros decimos muertito estamos llamando a la función.

Nuestra función sería algo así:

void muertito()
{
   Perro.Tirarse(posicion='espalda');
   Perro[OjoDer].Cerrar();
   Perro[OjoIzq].Cerrar();
   Perro[Lengua].Sacar();
}

Jajaja, bueno, bueno. Ya en serio vamos a hacer un clásico Hola Mundo pero usando una función:

#include
using namespace std;
void hola()
{
    cout << "Hola Mundo!";
}
int main()
{
    hola();
}

Como ven, esta función es muy estúpida. No nos beneficia en nada y nos hace escribir más código del necesario, pero nos sirve para ver cómo actúa una función: al momento de llamar a la función, el compilador se brinca a la función, la ejecuta y cuando termina, vuelve al punto desde donde brincó.

Si pudieran leerle la mente a un compilador, este diría:

Linea 1. Incluir la librería iostream. OK
Linea 2. Usar el namespace estándar. OK
Linea 3. Oh! una función llamada hola, la recordaré.
Linea 4. Llave. Parte de la función. Ignorar
Linea 5. Imprimir “Hola Mundo!”. Parte de la función. Ignorar
Linea 6. Llave. Parte de la función. Ignorar
Linea 7. ¡Por fin el main!
Linea 8. Llave. Entrar
Linea 9. Esta función se me hace conocida… oh sí ya recuerdo. Ejecutar lineas 4, 5 y 6
Linea 10. Llave. Salir

Ahora veamos una función que sí nos es útil:

#include
using namespace std;

void hola(char nombre[50])
{
    cout << "Hola " << nombre << "!";
}

int main()
{
    char nombre[50];
    cout << "Cual es tu nombre?: "; cin.getline(nombre, 50, 'n');
    hola(nombre);
}

Primero pedimos un nombre, lo guardamos en una variable y se le mandamos a la función para que lo muestre.

No se preocupen, si nunca habían visto una función tal vez no entiendan la sintaxis, pero el objetivo de este post es que sepan qué es una función y para qué se puede usar. En el siguiente post voy a explicar la sintaxis de los cuatro tipos de funciones en c++.

Cómo pasar una matriz o arreglo como parámetro a una función

Bueno, casi creo que nunca he hablado de matrices, parámetros o funciones en este blog, pero este post es una petición de Rodrigo que me dijo por email que tenía problemas con su tarea porque no sabe cómo pasar una matriz como parámetro a una función en c++. Es algo sencillo, pero difícil de deducir. Veamos.

Si tu arreglo es de una dimensión…
int matriz[4];
… la forma de declarar la función es la siguiente:
void fx(int m[4]) { ...código... }
Y la forma de llamar la función sería:
fx(matriz);

Si el arreglo es de dos dimensiones…
int matriz[4][3];
… pues es lo mismo:
void fx(int m[4][3]) { ...código... }
Y la forma de llamar la función sería:
fx(matriz);

Si la función retorna una matriz…
int matriz[4];
… se declara normal:
void fx(int m[4]) { return matriz[4]; }
Y la forma de llamar la función sería:
matriz[4] = fx(matriz);

Este programa pide tres números, los almacena en una matriz, le suma 1 a cada elemento y los muestra, usando para cada acción una función. Así que tenemos funciones que reciben matrices y que retornan matrices. Chéquenlo.

#include
using namespace std;

void pedir(int matriz[3], int len)
{
    for(int i=0; i<=len; i++)
    {
        cout << "Numero " << i+1 <> matriz[i];
    }
}

int sumar(int matriz[3], int len)
{
    for(int i=0; i<=len; i++)
        matriz[i]++;
    return matriz[3];
}

void mostrar(int matriz[3], int len)
{
    for(int i=0; i<=len; i++)
        cout << matriz[i] << " ";
}

int main()
{
    int matriz[3]={0}, len = sizeof(matriz)/sizeof(int);
    pedir(matriz, len-1);
    matriz[3] = sumar(matriz, len-1);
    mostrar(matriz, len-1);
    return 0;
}

Gráfica de Seno y Coseno en C++

Juand a través de un comentario me pidió ayuda con un programa que grafique utilizando gotoxy las gráficas de seno y coseno en c++. El programa me pareció interesante y, aunque tuve que desempolvar el Borland C++ que usaba en la prepa, lo hice… feo, pero lo hice.

A mi parecer, para graficar por ejemplo la función seno, hacen falta 3 pasos:

1. Hacer un ciclo de 0 a 360º (con aumentos de 5 queda muy bien) con for, algo muy normal.

2. Calcular, obviamente, el seno de cada valor. Para esto la librería math.h nos regala la función sin(). Su uso es el obvio, pero el asunto es que todas las funciones trigonométricas que usa c++ trabajan en radianes. Es decir que primero tendremos que convertir nuestro ángulo en radianes y luego ya sacar el seno. Si la variable ‘i’ contiene el ángulo y tenemos ya definida la constante PI, la función quedaría así:
sin(i/180*PI)

3. Luego viene la parte más rara, convertir ese valor en un entero que pueda meter como coordenada en un gotoxy. Si tenemos una variable int y y la igualamos a nuestra función anterior podría quedar bien si multiplicamos por 10:
int x, y; y = sin(i/180*PI)*10; gotoxy(x,y);
Nos quedaría nuestra gráfica en una escala 1:10, pero al correr el programa veremos que hay muchos valores de seno que son 10 (por el redondeo) y por lo tanto la gráfica se ve achatada.

Para mejorar un poco eso (de todos modos queda un poco fea) podemos usar la función ceil() incluida también en la librería math.h que nos redondea los decimales. Y esta vez multiplicamos por 20, redondeamos, dividimos entre 2 y convertimos a int. Nos vuelve a quedar escala 1:10 (¿o 10:1 …? no se) pero ya no hay tantas cantidades amontonadas en el 10 y -10.

El programa ya listo para graficar seno está aquí abajo, obviamente para graficar coseno sólo hay que cambiar la función sin por cos, y copiar, pegar y hacer un menú no debe ser difícil.

#include
#include
#include
#define PI 3.14159265

int main()
{
	int x=2, y;
	for(float i=0; i<=360; i+=5)
	{
		y = ceil(sin(i/180*PI)*20)/2;
		gotoxy(x, 12-y);printf("o");
		x++;
	}
	getch();

	return 0;
}

gráfica seno