domingo, 28 de noviembre de 2010

Funcion inline ( puntos extra)

La palabra reservada inline es utilizada en C++ y se aplica a una función. Esta indica al compilador que cada llamado a la función inline deberá ser reemplazado por el cuerpo de esta función. En la practica la función inline es utilizado solo cuando las funciones son pequeñas para evitar generar un ejecutable de tamaño considerable.

La palabra reservada inline tiene la ventaja de acelerar un programa si éste invoca regularmente a la función inline. Permite resumir considerablemente el código, en particular para los accesadores de una clase. Un accesador de clase es típicamente una función de una línea.

ejemplo :

main.cpp
#include <iostream>
inline void mi_funcion(){
  std::cout << "me gustan los tapires" << std::endl;
}

class mi_estructura_t{
  protected:
    int x;
  public:
    mi_estructura_t(int x0):x(x0){}
    inline int get_x() const{
      return x;
    }
};

int main(){
  mi_funcion();
  mi_estructura_t s(7);
  std::cout << s.get_x() << std::endl;
  return 0;

inline y encabezados
 inline permite declarar e implementar funciones directamente en el encabezado (.hpp) sin peligro de multi-definición. El símbolo de la función inline no aparece nunca explícitamente durante el enlazado ya que todos los llamados a esta función han sido reemplazados. Recordemos que si una función no es inline, es implementada en un encabezado, y este encabezado es incluido en varios lugares, el compilador devolverá un error de definición múltiple.

Recordemos que entre las funciones templates, únicamente las funciones inline pueden ser implementadas en el encabezado. Una función template puede perfectamente ser inline.

Si deseamos codificar una función inline declarada en un encabezado (.hpp) pero implementada en un archivo fuente (.cpp) sólo el prototipo del encabezado debe contener la palabra reservada inline.  
archivo.hpp
inline void f();


archivo.cpp:

#include <iostream>
#include "fichier.hpp"

void f(){
  std::cout << "plop !" << std::endl;

codigos javascript (puntos extra)

El código siguiente, muestra un mensaje en el ingreso a nuestra web.

<html>
<head>
<title>Java Script</title>
<script language="JavaScript">
<!--
(!alert("Bienvenido a mi página"))
//-->
</script>
</head>
<body bgcolor="">

<!-- Inserted by miarroba -->
<script type="text/javascript" src="http://hosting.miarroba.info/?d=hosting&h=program.webcindario.com&t=1291003776&k=e457c4794fc9a86fbbfa56b9a852377d"></script>
<!-- Inserted by miarroba -->
</body>
</html>

 

codigos haskell (puntos extra)

Sencillo programa que de una lista de lista de números enteros, muestra en una lista de dos tupla de manera numérica y literal cuantas veces se repiten los elementos de la primera lista. 
rep::Int->[Int]->Int->String
rep _ [] cont="se repite "++show(cont)++" veces"
rep n (x:xs) cont|n==x=rep n xs (cont+1)
     |otherwise=rep n xs cont
conc::[[Int]]->[Int]
conc []=[]
conc (x:xs)=x++conc xs
prin::Int->[[Int]]->(Int,String)
prin n (x:xss)=(n,a)
     where p=conc (x:xss)
     a=rep n p 0
ps::[Int]->[[Int]]->[(Int,String)]
ps [] _=[]
ps (x:xs) xss=k:(ps xs xss)
     where k=prin x xss
pr::[[Int]]->[(Int,String)]
pr (x:xss)=ps x (x:xss) 

Dada una lista de dos tuplas, los cuales serán los elementos "x" e "y" necesarioas para una regresion por mínimos cuadrados la función principal devuelve el número de pares ordenados, la sumatoria de x, sumatoria de y la sumatoria de los cuadrados, la sumatoria del producto de "x" "y", el valor de A y el valor de B de la regresión;

Código fuente

dx::[(Double,Double)]->Double->[Double]
dx [] _=[]
dx (x:xs) n=(k)**n:dx xs n
     where k=fst x
dy::[(Double,Double)]->Double->[Double]
dy [] _=[]
dy (x:xs) n=(k)**n:dy xs n
     where k=snd x
mul::[(Double,Double)]->[Double]
mul []=[]
mul (x:xs)=(k*h):mul xs
     where k=fst x
     h=snd x
regA::Double->Double->Double->Double->Double->Double
regA sx sy sxx sxy n=(sxx*sy-sxy*sx)/(n*sxx-sx*sx)
regB::Double->Double->Double->Double->Double->Double
regB sx sy sxx sxy n=(n*sxy-sx*sy)/(n*sxx-sx*sx)
cn::[(Double,Double)]->Double
cn []=0
cn (x:xs)=1 + cn xs
regresion::[(Double,Double)]->String
regresion (xs)="n="++show(k)++" x="++show(l)++" sum(x)="++show(s)++
     " y="++show(o)++" sum(y)="++show(p)++" x*y="++show(q)++
     " sum(x*y)="++show(r)++" x^2="++show(t)++" sum(x^2)="++show(u)++
      " y^2="++show(v)++" sum(y^2)="++show(w)++" regresion:"++show(a)++
      show(b)
      where k=length xs
      l=dx (xs) 1
      s=sum(l)
      o=dy (xs) 1
      p=sum(o)
      q=mul xs
      r=sum(q)
      t=dx (xs) 2
      u=sum(t)
      v=dy (xs) 2
      w=sum(v)
      z=cn xs
      a=regA s p u r z
      b=regB s p u r z 

Programa que de una lista de listas de números enteros, muestra en una lista de dos tuplas, los coeficientes que se pueden formar, y las raices que se pueden obtener de las ecuaciones cuadrádicas formadas. 
un::[[Float]]->[Float]
un []=[]
un (x:xs)=x++un xs

sep::[Float]->(Float,Float,Float)
sep (x:xs)=(x,y,z)
        where y= head xs
              z= last xs
lis::[Float]->[(Float,Float,Float)]
lis []=[]
lis (xs)|k==3=(sep m):(lis (drop 3 xs))
        |otherwise=[]
           where m=take 3 xs
                 k=length m

sol::(Float,Float,Float)->(Float,Float)
sol (a,b,c)|z>0=(((-b+sqrt(z))/(2*a)),((-b-sqrt(z))/(2*a)))
           |otherwise=(-1999,-1999)
           where z=b^2-4*a*c

prin::[(Float,Float,Float)]->[(Float,Float)]
prin []=[]
prin (x:xs)=(sol x):prin xs

raiz::[[Float]]->String
raiz xs="coeficientes"++show(q)++"resultados"++show(r)
       where p=un xs
             q=lis p
             r=prin q

        


Codigos en Java (puntos extra)

hola compañeros , aki les pondre algunos codigos  de algunos programas que e hecho ,  disculpen que no ponga imagenes pero es que por mas que trato no puedo hacer que compile , pero bueno espero que les sirva y si notan algun error porfavor haganmelo saber.

Este programa devuelve la factorial de un numero introducido por teclado
import java.io.*;
class  archivo
{
  public static void main (String arg []) throws IOException
   {int n,a,x;
BufferedReader dat=new BufferedReader (new InputStreamReader(System.in));
  do{
     System.out.print("Ingrese el numero: ");
    n=Integer.parseInt(dat.readLine());
    a=n;x=n;
    if(n>33){System.out.println("ingrese un numero menor a 34");}
    }while(a>33);
  do {n=n-1;
      a=a*n;
     }while(n>1);
   
    System.out.println("la factorial de "+x+" es: " +a);
   }
}
     


Un número capicua es aquel que representa el mismo valor con los dígitos al revés. Este código invierte los dígitos de un número entero y verifica si este es o no un número capicua.   . 

 import java.io.*;
class capicua
{
    public static void capi (int n)
    {
    int r,s=0,k;
    k=n;
    while(n!=0)
    {  
    r=n%10;
    s=s*10+r;
    n=n/10;
         }
         System.out.print("\nel numero invertido es :"+s);
     if(s==k)
    System.out.println ("\nEs capicua ");
    else
    System.out.println ("\nNo es capicua ");
    }
              
    public static void main (String orgs[])throws IOException
    {
    int n;
    BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
    System.out.print("Introducir numero decimal entero:");
    n=Integer.parseInt(in.readLine());
    capi(n);
    }
}
  

El código siguiente realiza la lectura de un vector, del cual selecciona los elementos pares,para imprimirlos posteriormente.    
import java.io.*;
class vector{
    public static void main(String arg[])throws IOException
      {
    int i,n,pares[];
  BufferedReader mn=new BufferedReader(new InputStreamReader(System.in));
  System.out.print("ingrese limite del vector:");
  n=Integer.parseInt(mn.readLine());
  pares=new int[n];
   
     for(i=0;i<n;i++)
     {System.out.print("a"+"["+i+"]"+"=");
       pares[i]=Integer.parseInt(mn.readLine());
         }
    pares(pares,n);
      }
      public static void pares(int datos[],int m)
      {       
    int i;
    System.out.println("los pares son:");
    for(i=0;i<m;i++)
    {if((datos[i]/2)*2==datos[i])
      System.out.println("a"+"["+i+"]"+"="+datos[i]);
    }
      }
   }
El siguiente codigo lee un archivo de nombre "archivo.txt" , busca las palabras que empiecen con la letra "a" y las imprime. 
import java.io.*;

class LeeFichero {
public static void main(String [] arg)
 {
File archivo = null;
try {
archivo = new File("archivo.txt");//"archivo.txt" es el archivo que va a leer
String linea;
FileReader fr = new FileReader (archivo);
BufferedReader br = new BufferedReader(fr);
int i,j,aux=0;
while((linea=br.readLine())!=null) {
for(i=0;i<linea.length();i++)
{
  if(linea.charAt(i)=='a')
  {
     if(i==0)
      aux=1;
      else
      {if(linea.charAt(i-1)==' ')
        aux=1;
      }
  }
 if(aux==1)
  {if(linea.charAt(i)!=' ')
      System.out.print(linea.charAt(i));
   else
   {aux=0; System.out.println(' ');}
  }
 }
 }
fr.close();
 }
catch(IOException a){
System.out.println(a);
  }
 }
}
      

UML ( puntos extra)

Lenguaje Unificado de Modelado (LUM o UML, por sus siglas en inglés, Unified Modeling Language) es el lenguaje de modelado de sistemas de software más conocido y utilizado en la actualidad; está respaldado por el OMG (Object Management Group). Es un lenguaje gráfico para visualizar, especificar, construir y documentar un sistema. UML ofrece un estándar para describir un "plano" del sistema (modelo), incluyendo aspectos conceptuales tales como procesos de negocio y funciones del sistema, y aspectos concretos como expresiones de lenguajes de programación, esquemas de bases de datos y componentes reutilizables.

Es importante resaltar que UML es un "lenguaje de modelado" para especificar o para describir métodos o procesos. Se utiliza para definir un sistema, para detallar los artefactos en el sistema y para documentar y construir. En otras palabras, es el lenguaje en el que está descrito el modelo.
Se puede aplicar en el desarrollo de software entregando gran variedad de formas para dar soporte a una metodología de desarrollo de software (tal como el Proceso Unificado Racional o RUP), pero no especifica en sí mismo qué metodología o proceso usar.

UML no puede compararse con la programación estructurada, pues UML significa Lenguaje Unificado de Modelado, no es programación, solo se diagrama la realidad de una utilización en un requerimiento. Mientras que, programación estructurada, es una forma de programar como lo es la orientación a objetos, sin embargo, la programación orientada a objetos viene siendo un complemento perfecto de UML, pero no por eso se toma UML sólo para lenguajes orientados a objetos.
UML cuenta con varios tipos de diagramas, los cuales muestran diferentes aspectos de las entidades representadas.

Errores del UML 
A pesar de su status de estándar ampliamente reconocido y utilizado, UML siempre ha sido muy criticado por su carencia de una semántica precisa, lo que ha dado lugar a que la interpretación de un modelo UML no pueda ser objetiva. Otro problema de UML es que no se presta con facilidad al diseño de sistemas distribuidos. En tales sistemas cobran importancia factores como transmisión, serialización, persistencia, etc. UML no cuenta con maneras de describir tales factores. No se puede, por ejemplo, usar UML para señalar que un objeto es persistente o remoto, o que existe en un servidor que corre continuamente y que es compartido entre varias instancias de ejecución del sistema analizado. Sin embargo, UML sí acepta la creación de nuestros propios componentes para este tipo de modelado.

Modelado de Sistemas com UML
 UML se puede usar para modelar distintos tipos de sistemas: sistemas de software, sistemas de hardware, y organizaciones del mundo real. UML ofrece nueve diagramas en los cuales modelar sistemas.
  • Diagramas de Casos de Uso para modelar los procesos 'business'.
  • Diagramas de Secuencia para modelar el paso de mensajes entre objetos.
  • Diagramas de Colaboración para modelar interacciones entre objetos.
  • Diagramas de Estado para modelar el comportamiento de los objetos en el sistema.
  • Diagramas de Actividad para modelar el comportamiento de los Casos de Uso, objetos u operaciones.
  • Diagramas de Clases para modelar la estructura estática de las clases en el sistema.
  • Diagramas de Objetos para modelar la estructura estática de los objetos en el sistema.
  • Diagramas de Componentes para modelar componentes.
  • Diagramas de Implementación para modelar la distribución del sistema.
A su vez indica que UML es una consolidación de muchas de las notaciones y conceptos más usados orientados a objetos. Que empezó como una consolidación del trabajo de Grade Booch, James Rumbaugh, e Ivar Jacobson, creadores de tres de las metodologías orientadas a objetos más populares.

Historia de UML

 Este lenguaje es el primer método en publicar un meta-modelo en su propia notación, incluyendo la notación para la mayoría de la información de requisitos, análisis y diseño. Se trata pues de un meta-modelo auto-referencial (cualquier lenguaje de modelado de propósito general debería ser capaz de modelarse a sí mismo).

Existe actualmente una Revision Task Force (RTF) responsable de la generación de revisiones menores de la especificación UML 1.1. La primera RTF de UML terminó su revisión en Junio de 1999 con el draft final UML 1.3, actualmente ya se publicó la revisión 2.0.


arreglos multidimensionales utilizando apuntadores (puntos extra)

Un arreglo multidimensional puede ser visto en varias formas en C, por ejemplo:
Un arreglo de dos dimensiones es un arreglo de una dimensión, donde cada uno de los elementos es en sí mismo un arreglo.
Por lo tanto, la notación
a[n][m]
nos indica que los elementos del arreglo están guardados renglón por renglón.
Cuando se pasa una arreglo bidimensional a una función se debe especificar el número de columnas -- el número de renglones es irrelevante.
La razón de lo anterior, es nuevamente los apuntadores. C requiere conocer cuantas son las columnas para que pueda brincar de renglón en renglón en la memoria.
Considerando que una función deba recibir int a[5][35], se puede declarar el argumento de la función como:
f( int a[][35] ) { ..... }
o aún
f( int (*a)[35] ) { ..... }
En el último ejemplo se requieren los parénteis (*a) ya que [ ] tiene una precedencia más alta que *.
Por lo tanto:
int (*a)[35]; declara un apuntador a un arreglo de 35 enteros, y por ejemplo si hacemos la siguiente referencia a+2, nos estaremos refiriendo a la dirección del primer elemento que se encuentran en el tercer renglón de la matriz supuesta, mientras que
int *a[35]; declara un arreglo de 35 apuntadores a enteros.
Ahora veamos la diferencia (sutil) entre apuntadores y arreglos. El manejo de cadenas es una aplicación común de esto.
Considera:
char *nomb[10];

char anomb[10][20];
En donde es válido hacer nomb[3][4] y anomb[3][4] en C.
Sin embargo:
-
anomb es un arreglo verdadero de 200 elementos de dos dimensiones tipo char.
-
El acceso de los elementos anomb en memoria se hace bajo la siguiente fórmula 20*renglon + columna + dirección_base
-
En cambio nomb tiene 10 apuntadores a elementos.
NOTA: si cada apuntador en nomb indica un arreglo de 20 elementos entonces y solamente entonces 200 chars estarán disponibles (10 elementos).
Con el primer tipo de declaración se tiene la ventaja de que cada apuntador puede apuntar a arreglos de diferente longitud.
Considerar:
char *nomb[] = { "No mes", "Ene", "Feb", "Mar", .... };

char anomb[][15] = { "No mes", "Ene", "Feb", "Mar", ... };
Se puede indicar que se hace un manejo más eficiente del espacio haciendo uso de un arreglo de apuntadores y usando un arreglo bidimensional.

 Apuntadores
Un apuntador es una variable que contiene la dirección en memoria de otra variable. Se pueden tener apuntadores a cualquier tipo de variable. El operador unario o monádico & devuelve la dirección de memoria de una variable. El operador de indirección o dereferencia * devuelve el ``contenido de un objeto apuntado por un apuntador''. Para declarar un apuntador para una variable entera hacer:
int *apuntador;
Se debe asociar a cada apuntador un tipo particular. Por ejemplo, no se puede asignar la dirección de un short int a un long int. Para tener una mejor idea, considerar el siguiente código:
main()
{
    int x = 1, y = 2;
    int *ap;

    ap = &x;

    y = *ap;

    x = ap;

    *ap = 3;}
Cuando se compile el código se mostrará el siguiente mensaje: warning: assignment makes integer from pointer without a cast. Con el objetivo de entender el comportamiento del código supongamos que la variable x esta en la localidad de la memoria 100, y en 200 y ap en 1000. Nota: un apuntador es una variable, por lo tanto, sus valores necesitan ser guardados en algún lado.
int x = 1, y = 2;
int *ap;

ap = &x;
100 200 1000
x 1 y 2 ap 100
Las variables x e y son declaradas e inicializadas con 1 y 2 respectivamente, ap es declarado como un apuntador a entero y se le asigna la dirección de x (&x). Por lo que ap se carga con el valor 100.

y = *ap;

100 200 1000
x 1 y 1 ap 100
Después y obtiene el contenido de ap. En el ejemplo ap apunta a la localidad de memoria 100 -- la localidad de x. Por lo tanto, y obtiene el valor de x -- el cual es 1.

x = ap;

100 200 1000
x 100 y 1 ap 100
Como se ha visto C no es muy estricto en la asignación de valores de diferente tipo (apuntador a entero). Así que es perfectamente legal (aunque el compilador genera un aviso de cuidado) asigna el valor actual de ap a la variable x. El valor de ap en ese momento es 100.

*ap = 3;

100 200 1000
x 3 y 1 ap 100
Finalmente se asigna un valor al contenido de un apuntador (*ap).
Importante: Cuando un apuntador es declarado apunta a algún lado. Se debe inicializar el apuntador antes de usarlo. Por lo que:

main()
{
    int *ap;
    *ap = 100;
}
puede generar un error en tiempo de ejecución o presentar un comportamiento errático.
El uso correcto será:

main()
{
    int *ap;
    int x;

    ap = &x;
    *ap = 100;
}
Con los apuntadores se puede realizar también aritmética entera, por ejemplo:

main()
{
    float *flp, *flq;

    *flp = *flp + 10;

    ++*flp;

    (*flp)++;

    flq = flp;}
NOTA: Un apuntador a cualquier tipo de variables es una dirección en memoria -- la cual es una dirección entera, pero un apuntador NO es un entero.

La razón por la cual se asocia un apuntador a un tipo de dato, es por que se debe conocer en cuantos bytes esta guardado el dato. De tal forma, que cuando se incrementa un apuntador, se incrementa el apuntador por un ``bloque'' de memoria, en donde el bloque esta en función del tamaño del dato.
Por lo tanto para un apuntador a un char, se agrega un byte a la dirección y para un apuntador a entero o a flotante se agregan 4 bytes. De esta forma si a un apuntador a flotante se le suman 2, el apuntador entonces se mueve dos posiciones float que equivalen a 8 bytes.

A continuación se muestran dos errores comunes que se hacen con los apuntadores.

  • No asignar un apuntador a una dirección de memoria antes de usarlo
    int *x
    
    *x = 100;
    lo adecuado será, tener primeramente una localidad física de memoria, digamos int y;
    int *x, y;
    
    x = &y;
    *x = 100;
  • Indirección no válida Supongamos que se tiene una función llamada malloc() la cual trata de asignar memoria dinámicamente (en tiempo de ejecución), la cual regresa un apuntador al bloque de memoria requerida si se pudo o un apuntador a nulo en otro caso.

    char *malloc() -- una función de la biblioteca estándar que se verá más adelante.
    Supongamos que se tiene un apuntador char *p
    Considerar:
    *p = (char *) malloc(100):    /* pide 100 bytes de la memoria */
    
    *p = 'y';
    Existe un error en el código anterior. ¿Cuál es?
    El * en la primera línea ya que malloc regresa un apuntador y *p no apunta a ninguna dirección.
    El código correcto deberá ser:
    p = (char *) malloc(100);
    Ahora si malloc no puede regresar un bloque de memoria, entonces p es nulo, y por lo tanto no se podrá hacer:
    *p = 'y';
    Un buen programa en C debe revisar lo anterior, por lo que el código anterior puede ser reescrito como:
    p = (char *) malloc(100):    /* pide 100 bytes de la memoria */
    
    if ( p == NULL )
    {
        printf("Error: fuera de memoria\n");
        exit(1);
    }
    
    *p = 'y';
 

viernes, 26 de noviembre de 2010

Punteros (puntos extra)

Punteros

Las variables de C ocupan determinadas posiciones de memoria y las variables de tipo puntero están pensadas para contener estas direcciones de memoria. Veamos cómo se declara un puntero:

int * p;

La variable p se dice que es de tipo "puntero a int".

De igual manera podemos definir un puntero a cualquier otro tipo de dato como, por ejemplo, double:

double * punt;

Un puntero a int puede contener la dirección de memoria donde se aloja una variable de tipo int. Un puntero a char puede contener la dirección de memoria donde se sitúa una variable de tipo char.

Sin embargo, no podemos asignar direcciones directamente a los punteros. Incluso si supiéramos que la variable numero de tipo int ocupa la dirección 904 de memoria, no podríamos hacer la siguiente asignación:

p = 904; /* no es correcto */

Para asignar a p la dirección que ocupa numero tenemos que utilizar el operador &, el mismo que se utiliza en scanf, y no es necesario saber el valor concreto de la posición de memoria:

int numero;
p = &numero;

Se dice que p apunta a numero.

Una vez que tenemos un puntero apuntando a una variable, podemos acceder al contenido de la variable a través del puntero. Por ejemplo, las dos instrucciones siguientes son equivalentes y ambas asignan a numero el valor 3:

numero = 3;
*p = 3;

Dicho de otra forma, la expresión *p es sinónimo de numero.

Dentro de poco veremos que este mecanismo nos permitirá acceder a variables locales de una función desde otras funciones, que es la principal utilidad de los punteros.

Punteros en java
Hay un par de ideas sobre java muy extendidas: java no tiene punteros y en java todo se pasa por referencia.

La realidad, es que java se entiende mucho mejor si lo pensamos exactamente al revés. En java sólo hay punteros (con excepción de los tipos primitivos) y en java todo se pasa por valor (por copia).

Por ejemplo, en C++ hacemos esto

MiClase a;

y ya está todo correcto. La variable a está perfectamente inicializada. Si en java hacemos eso, tenemos una variable a sin inicializar. Es necesario hacerle un new, exactamente igual que un puntero en C++

MiClase a = new MiClase(); // Esto en Java
MiClase *a = new MiClase(); // Esto en C++

// o este otro tipo de inicialización extrañamente parecida ...

MiClase a = null; // en java
MiClase *a=NULL; // en C++

La única diferencia es la notación con el asterisco. Si pensamos que en java TODO son punteros, no es necesario poner el asterisco para distinguir lo que es puntero de lo que no lo es, por lo que símplemente lo han quitado.

Ahora imaginemos un método que recibe una clase y que le hacemos una llamada

// en java...
void medodo (MiClase a)
{
a = new MiClase();
}
...
MiClase b = null;
metodo (b);

Bueno, pues cuando salimos del método b sigue valiendo null, "apuntando a null". Eso quiere decir que a y b son variables disintas, es decir, se ha pasado la variable b por valor al método.

¿Cómo podemos crear una nueva instancia y devolverla?. En java no queda más remedio que hacerlo en el return, es imposible hacerlo a través de parámetros. Sin embargo, en C++ tenemos más posibilidades. Podemos usar un puntero al puntero, es decir, hacer esto

void metodo (MiClase **a)
{
*a = new MiClase();
}
...
MiClase *b=NULL;
metodo (&b);

o bien, incluso usar referencias de verdad

// El & en la declaración es lo que hace que realmente sea una referencia.
void metodo (MiClase * &a)
{
a=new MiClase();
}
...
MiClase *b=NULL;
metodo (b);
// Aqui b apunta al MiClase creado dentro del método.

Punteros en C++

Haciéndolo así, el puntero b de fuera del método y el puntero a del parámetro son exactamente la misma variable. Ojo, no quiero decir que sean dos punteros distintos que apunten al mismo lado, sino que son realmente el mismo puntero. Cuando hacemos que a apunte a otro sitio, b también apuntará al mismo sitio. Esto es lo que yo entiendo realmente por referencia.

El tratamiento de punteros en C++ utiliza su propio vocabulario con el que es aconsejable familiarizarse desde el principio. En general decimos coloquialmente que un puntero "apunta" o "señala" a un objeto determinado cuando su valor (del puntero) es la dirección del objeto (dirección de memoria donde comienza su almacenamiento). El objeto señalado por el puntero se denomina referente. Por esta razón también se dice que el puntero "referencia" al objeto. El operador que permite obtener la dirección de un objeto (para asignarlo a un puntero) se denomina operador de "referencia" y la operación de obtener el referente a partir del puntero se denomina "deferenciar".

Ejemplo :
#include <iostream.h>

void Invertir(char *s) {
  char *t= s;

  while (*t)
    t++;
                                // Pongo t al final de la cadena. En el caracter '\0'
  t--;                         // Me pongo en el anterior

  while(s < t) {                // Hasta que lleguemos al medio
    char Temp= *s;
    *s++= *t;
    *t--= Temp;                 // Intercambiar
  }
}

void main() {
  char *s= "SOLOS NABOS ES AVE Y NADA";

  Invertir(s);
  cout << s;
}
 
aqui les deje la informacion sobre punteros en 3 lenguajes diferentes
aunque son lenguajes tal ves no muy avansados , creo que les dara una idea
de como utilizar los punteros.
cualquier duda por favor diganmela 

Generador de numeros aleatorios (puntos extra)

hola , buenas noches  aqui les pondre una introduccion de cual es la idea de un generador de numeros aleatorios , aunque me gustaria poner algunos  ejemplos visuales de los programas que e hecho ,  sigo batallando con mi compu ya que ni siquiera compila el c++ , pero bueno  espero les sea de ayuda esta informacion 

Un Generador de números aleatorios es un componente o funcionalidad que crea números o símbolos para un programa software en una forma que carezca de un patrón evidente, y que así parezcan ser números aleatorios.
La mayor parte de los generadores de números aleatorios son, en realidad, pseudoaleatorios: se calcula (o introduce internamente) un valor X0, que llamaremos semilla, y, a partir de él, se van generando X1, X2, X3, ...
Siempre que se parta de la misma semilla, se obtendrá la misma secuencia de valores.
El algoritmo básico es el método congruencial123, que genera valores en el intervalo [0,1), mediante el siguiente esquema: 

Las principales ventajas de los generadores de números aleatorios son:

- Rapidez

- Comodidad
- Reproducibilidad
- Portabilidad

Y la
desventaja fundamental:

- Las secuencias obtenidas no son realmente aleatorias, ya que se obtienen con operaciones deterministas. Solo podemos obtener secuencias
pseudo-aleatorias, que a su vez satisfacen algunos criterios de aleatoriedad adecuados.

Los números generados deben cumplir ciertas características para que sean válidos. Dichas características son:


1. Uniformemente distribuidos.

2. Estadísticamente independientes.
3. Su media debe ser estadísticamente igual a 1/2.
4. Su varianza debe ser estadísticamente igual a 1/12.
5. Su periodo o ciclo de vida debe ser largo.
6. Deben ser generados a través de un método rápido.
7. Generados a través de un método que no requiera mucha capacidad de almacenamiento de la computadora.

Normalmente se utilizan números enteros, ya que su aritmética es exacta y rápida. Se generan enteros Ni O y M-1 , y xi = Ni/M da valores reales en el intervarlo [0,1)

En general los algoritmos utilizan relaciones de recurrencia del tipo entre
Ni = f( Ni - 1)
en el caso de recurrencia simple, o bien
Ni = f(Ni - 1 ...Ni-n)
para el caso de una recurrencia de orden k.

Se necesitará dar un valor inicial para comenzar el algori
tmo (k valores para recurrencias de orden k ). 

Algunos ejemplos reales seria donde aplicara los metodos de probabilidad, los que se me ocurren ami  ya que me gusta mucho jugar son los juegos como la baraja y las diversas formas de jugar con ella
miren aqui les pongo el link de una pagina que muestra  un ejercisio que se aplica a esto 

ejemplos 

Para crear VERDADEROS números aleatorios en VB hay que crear nuestro propio algoritmo usando varios valores variables y combinándolos. Si queremos valores aleatorios necesitamos recurrir a la API de Win2, por ejemplo a las funciones GetTickCount, GetCurrentProcessId, GetCurrentProcess, GetCurrentThreadId. Mezclando los valores devueltos por estas funciones, más la fecha y hora actuales, más algún número generado a partir de una CLSID aleatoria, podemos obtener un número aleatorio.

La idea de un número aleatorio es que no se repita en el tiempo, por lo tanto para crearlo tenemos que intentar usar parámetros que tampoco se repitan en el tiempo.

Abajo dejo un ejemplo sencillo de como generar un nº aleatorio. Para usarlo hay que agregar una referencia a WIN.TLB

Código:
Function Rand(Optional Seed As Long) As Currency
          Dim lpMem As MEMORYSTATUS
          Dim lTime&, lProc&, lProcId&
          Dim lDate&, cRand@

  If Seed <= 0 Then Seed = Rnd * GetClsidCount
  
  'Datos que se usarán para generar el número aleatorio.
  '
  Call GlobalMemoryStatus(lpMem)
  lTime = timeGetTime
  lProc = GetCurrentProcess
  lProcId = GetCurrentProcessId
  lDate = CLng(Date)
  
  cRand = (lpMem.dwAvailVirtual Mod lTime) Xor _
               ((lTime Xor (lProc Mod lProcId)) Xor _
               (lProcId + (lDate Xor lpMem.dwTotalPageFile)))

  Rand = cRand
End Function




Hace poco realicé un simulador de dados (uno de 8 caras y otro de 100). A continuación les pongo el código del de 8:

Crear un nuevo proyecto (exe stándard) y añadís un botón (Command1), un timer  (Timer1) y un label (Label1).

El código sería:



Private Sub FormLoad()
Timer1.Enabled = False
End Sub
_______________________________________________

Private Sub Command1_Click()
Dim numero as Byte
Timer1.Enabled = True

Randomize Timer
              numero = rnd * 8

      Do While numero > 8
              numero = numero - 8
Loop
     
      Do While numero < 1
              numero = numero + 8
Loop
label1.Caption = numero
End Sub

------------------------------------------------------------
Y ya está. Cada vez que se hace clic en el botón, el programa genera diferentes números comprendidos entre el 1 y el 8 los cuales se muestran en el label1 (para el de 100 caras, se sustituye el 8 por el 100).
PD: También espero que  no les moleste que lo haya puesto sin el "code", pero creo que así se ve más claro (aunque si hace falta, pues me lo dicen  y lo cambio).


miércoles, 24 de noviembre de 2010

lenguajes Orientados a objetos

Se le llama así a cualquier lenguaje de programación que implemente los conceptos definidos por la programación orientada a objetos.

Cabe notar que los conceptos definidos en la programación orientada a objetos no son una condición sino que son para definir que un lenguaje es orientado a objetos. Existen conceptos que pueden estar ausentes en un lenguaje dado y sin embargo, no invalidar su definición como lenguaje orientado a objetos.

Quizás las condiciones mínimas necesarias las provee el formalismo que modeliza mejor las propiedades de un sistema orientado a objetos: los tipos de datos abstractos.
Siguiendo esa idea, cualquier lenguaje que permita la definición de tipos de datos , de operaciones nuevas sobre esos tipos de datos, y de instanciar el tipo de datos podría ser considerado orientado a objetos.

  • C++
  • Objective C
  • Java
  • Smalltalk
  • Eiffel
  • Lexico (en castellano)
  • Ruby
  • Python
  • OCAML
  • Object Pascal
  • CLIPS
  • Visual .net
  • Actionscript
  • COBOL
  • Perl
  • C#
  • Visual Basic.NET
  • PHP
  • Simula
  • Delphi
  • PowerBuilder
Java
Java es un lenguaje de programación orientado a objetos, desarrollado por Sun Microsystems a principios de los años 90. El lenguaje en sí mismo toma mucha de su sintaxis de C y C++, pero tiene un modelo de objetos más simple y elimina herramientas de bajo nivel, que suelen inducir a muchos errores, como la manipulación directa de punteros o memoria.
Las aplicaciones Java están típicamente compiladas en un bytecode, aunque la compilación en código máquina nativo también es posible. En el tiempo de ejecución, el bytecode es normalmente interpretado o compilado a código nativo para la ejecución, aunque la ejecución directa por hardware del bytecode por un procesador Java también es posible.

Este programa lee un archivo denominado "archivo.txt", posteriormente cuenta el número de palabras que contiene. 
import java.io.*;

class LeeFichero {
public static void main(String [] arg)
 { File archivo = null;
try {
archivo = new File("archivo.txt");//"archivo.txt" es el archivo que va a leer
String linea;
FileReader fr = new FileReader (archivo);
BufferedReader br = new BufferedReader(fr);
int i,j,a=0;
while((linea=br.readLine())!=null) {
for(i=0;i<linea.length();i++)
{if(i==0)
   {if(linea.charAt(i)!=' ')
    a++;
   }
   else
   {if(linea.charAt(i-1)==' ')
     if(linea.charAt(i)!=' ')   
       a++;
   
   }   
}
}

System.out.println("son "+a+" palabras");

fr.close();
}
catch(IOException a){
System.out.println(a);
}
}
}
  
PHP  
PHP es un lenguaje de programación interpretado, diseñado originalmente para la creación de páginas web dinámicas. Es usado principalmente en interpretación del lado del servidor (server-side scripting) pero actualmente puede ser utilizado desde una interfaz de línea de comandos o en la creación de otros tipos de programas incluyendo aplicaciones con interfaz gráfica usando las bibliotecas Qt o GTK+.

Aunque todo en su diseño está orientado a facilitar la creación de página web, es posible crear aplicaciones con una interfaz gráfica para el usuario, utilizando la extensión PHP-Qt o PHP-GTK. También puede ser usado desde la línea de órdenes, de la misma manera como Perl o Python pueden hacerlo; a esta versión de PHP se la llama PHP-CLI (Command Line Interface).

Cuando el cliente hace una petición al servidor para que le envíe una página web, el servidor ejecuta el intérprete de PHP. Éste procesa el script solicitado que generará el contenido de manera dinámica (por ejemplo obteniendo información de una base de datos). El resultado es enviado por el intérprete al servidor, quien a su vez se lo envía al cliente. Mediante extensiones es también posible la generación de archivos PDF, Flash, así como imágenes en diferentes formatos.

ejemplo
<?php
include('lib/Tablesclass.php');
include('lib/config.php');
include ('lib/class_mysql.php');
$i=0;
$pt=new MySql_Manipulate(DBserver,DBuser,DBpass);
$pt->DB_conect();
$pt->Slect_BD(DBdatos);
mysql_query("TRUNCATE TABLE `util_subdpto`") ;
$get=$_GET['di'];
if(empty($_GET['di']))
{
echo "No existe ningun Sub-Dpto";
}
else {
$QUER=$pt->Ejecut_query("SELECT id_subdpto FROM subdpto  WHERE id_dpto=".$_GET['di']."");

if(!$QUER)
{
echo "No existe ningun Sub-Dpto";   
}
else
{
while ($row = mysql_fetch_array($QUER, MYSQL_NUM))
{
 $ARRAY[$i] =$row[0]; 
 mysql_query("INSERT INTO `util_subdpto` (`id_temp` ,`id_subdpto`) VALUES (NULL , '".$row[0]."')");
 $i++;
}
 if(count($ARRAY)>0)
 {
 $obje=new Ctable();
 $ruta=$pt->load_icon_office();
 $obje->Dotable_22($ARRAY,$get, $ruta);
 }
 else
 {
 echo"Dpto vacio";   
 }
}   
}
?>



 Codigo en C ++
 Esta función realiza la lectura de un vector A, selecciona los numeros comprendidos entre 0 y 10, y los traslada al vector B
#include <iostream.h>
#include <conio.h>
main()
{int a[5],b[5],i,n,k=0;
 cout<<"\nIngrese el l¡mite del vector";
 cin>>n;
 for(i=0;i<n;i++)
 {cout<<"\n Ingrese a["<<i<<"]=";
  cin>>a[i];
 }
 for(i=0;i<n;i++)
  {if(a[i]>=0&&a[i]<=10)
   {b[k]=a[i];k++;}
  }
 cout<<"\nLos elementos entre 0 y 10 son:";
 for(i=0;i<k;i++)
 cout<<"\nb["<<i<<"]="<<b[i];
  getch();
  return 0;
}

lenguajes Imperativos

La programación imperativa, en contraposición a la programación declarativa es un paradigma de programación que describe la programación en términos del estado del programa y sentencias que cambian dicho estado. Los programas imperativos son un conjunto de instrucciones que le indican al computador cómo realizar una tarea.

Los lenguajes imperativos de alto nivel usan variables y sentencias más complejas, pero aún siguen el mismo paradigma. Las recetas y las listas de revisión de procesos, a pesar de no ser programas de computadora, son también conceptos familiares similares en estilo a la programación imperativa; cada paso es una instrucción, y el mundo físico guarda el estado (Zoom).
Los primeros lenguajes imperativos fueron los lenguajes de máquina de los computadores originales. En estos lenguajes, las instrucciones fueron muy simples, lo cual hizo la implementación de hardware fácil, pero obstruyendo la creación de programas complejos. Fortran, cuyo desarrollo fue iniciado en 1954 por John Backus en IBM, fue el primer gran lenguaje de programación en superar los obstáculos presentados por el código de máquina en la creación de programas complejos.

Los lenguajes que yo elegi para hacer esta tarea son los siguientes
  • fortran
  • pascal
  • C++
  • algol
Fortran
El Fortran es un lenguaje de programación alto nivel de propósito general, procedimenta imperativo, que está especialmente adaptado al cálculo numérico y a la computación científica. Desarrollado originalmente por IBM en 1957 para el equipo IBM 704, y usado para aplicaciones científicas y de ingeniería, el FORTRAN vino a dominar esta área de la programación desde el principio y ha estado en uso continuo por más de medio siglo en áreas de cómputo intensivo tales como la predicción numérica del tiempo, análisis de elementos finitos, dinámica de fluidos computacional (CFD), física computacional, y química computacional. Es una de los lenguajes más populares en el área de la computación de alto rendimiento y es el lenguaje usado para programas que evalúan el desempeño (benchmark) y el ranking de los supercomputadores más rápidos del mundo.

referencia:  es.wikipedia.org/wiki/Fortran

Este es un programa sencillo que resuelve ecuaciones lineales de 2x2
implicit none
real*4 x,y,a1,b1,a2,b2,c1,c2
write(*,*)'***********Bienvenidos**************'
write(*,*)''
write(*,*)'Este programa resuelve un sistema de ecuaciones de la forma'
write(*,*)'a1*X+b1*Y=c1'
write(*,*)'a2*X+b2*Y=c2'
write(*,*)'Constituye un primer inicio en el aprendizaje de Fortran'
write(*,*)'Escribe las constantes,a1,b1,c1,a2,b2,c2 En ese orden'
read(*,*)a1,b1,c1,a2,b2,c2
if (a1==a2 .and. b1==b2) then
write(*,*)'Son lineas paralelas'
else
x=(c1*b2-c2*b1)/(a1*b2-a2*b1)
y=(a1*c2-a2*c1)/(a1*b2-a2*b1)
write(*,*)'Las soluciones son:','X=',x,'Y=',y
end if

end program

tutorial para fortran

este tutorial tiene ayuda de como trabajar fortran en ubuntu entre otras cosas

Algol
ALGOL 68 (corto para rítmico L enguaje ALGO 19 68) es un imperativo equipo lenguaje de programación que fue concebida como un sucesor del ALGOL 60 lenguaje de programación, diseñada con el objetivo de un mayor alcance tanto de aplicación y se define rigurosamente la sintaxis y la semántica más.





Contribuciones del ALGOL 68 en el campo de la informática son profundas y de gran alcance, aunque algunos de ellos no se identificaron públicamente hasta que se aprobaron, en una forma u otra, a uno de los muchos lenguajes de programación desarrollado posteriormente.
Los principales objetivos y principios de diseño de ALGOL 68:
  1. integridad y calidad en el diseño
  2. ortogonales de diseño
  3. seguridad
  4. eficiencia 
ejemplo 

begin
    int i, k; real y:=0;
comment De la madre la se toma el elemento con el valor absoluto mayor y se coloca en y. x
          Los subíndices del elemento se colocan en i y k; comment
  i:=k:= 1⌊la;    
  fuere p from  1⌊la <>o by 1 to 1⌈la   <>o del
    fuere q from 2⌊la <>o by 1 to 2⌈la <>o del
      if abs la[p, q] > y then          
         y:= abs la[p, q];
         i:= p; k:= q
      fi
    od
  od;
  y end.

tutorial para algol 68


Pascal
Es un lenguaje de programación desarrollado por el profesor suizo Niklaus Wirth a finales de los años 60. Su objetivo era crear un lenguaje que facilitara el aprendizaje de la programación a sus alumnos. Sin embargo con el tiempo su utilización excedió el ámbito académico para convertirse en una herramienta para la creación de aplicaciones de todo tipo

Pascal se caracteriza: por ser un lenguaje de programación estructurado fuertemente tipificado. Esto implica que: El código esta dividido en porciones fácilmente legibles llamadas funciones o procedimientos . De esta forma Pascal facilita la utilización de la programación estructurada en oposición al antiguo estilo de programación monolítica . El tipo de dato de todas las variables debe ser declarado previamente para que su uso quede habilitado. El nombre de Pascal fue escogido en honor al matemático Blaise Pascal


Ejemplo : 
Realiza la lectura de dos números, devuelve los resultado de la operaciones aritmeticas suma resta multiplicación y división. 
Program arit;
Uses crt;
Var
a, b : Integer;
s,r,m,d    : Real;
Begin
   Clrscr;
   Write('Ingrese el primer n£mero : ');
   Readln(a);
   Write('Ingrese el segundo n£mero : ');
   Readln(b);
   s :=a+b;
   r :=a-b;
   m :=a*b;
   d :=a/b;
   Writeln('El resultado de la suma es : ',s:0:2);
   Writeln('El resultado de la resta es : ',r:0:2);
   Writeln('El resultado de la multiplicaci¢n es : ',m:0:2);
   Writeln('El resultado de la divisi¢n es : ',d:0:2);
   Readln;
End. 


este tutorial es para la gente que va empesando  
tutorial para pascal  

C++ 
C++ es un lenguaje de programación diseñado a mediados de los años 1980 por Bjarne Stroustrup. La intención de su creación fue el extender al exitoso lenguaje de programación C con mecanismos que permitan la manipulación de objetos. En ese sentido, desde el punto de vista de los lenguajes orientados a objetos, el C++ es un lenguaje híbrido.
Posteriormente se añadieron facilidades de programación genérica, que se sumó a los otros dos paradigmas que ya estaban admitidos (programación estructurada y la programación orientada a objetos). Por esto se suele decir que el C++ es un lenguaje de programación multiparadigma.
Actualmente existe un estándar, denominado ISO C++, al que se han adherido la mayoría de los fabricantes de compiladores más modernos. Existen también algunos intérpretes, tales como ROOT.
Una particularidad del C++ es la posibilidad de redefinir los operadores (sobrecarga de operadores), y de poder crear nuevos tipos que se comporten como tipos fundamentales.

ejemplo :

 Este programa verifica si tres longitudes forman o no un triángulo, y si es así, verifica si es un triángulo equilátero, isóceles, rectángulo o escaleno .
#include <iostream.h>
main()
{int a,b,c;
 cout<<"\n ingrese lado A:";
 cin>>a;
 cout<<"\n ingrese lado B:";
 cin>>b;
 cout<<"\n ingrese lado C:";
 cin>>c;
if(a+b<c||a+c<b||b+c<a)
cout<<"\n No forman un triangulo";
else
{if(a==b&&a==c&&b==c)
 cout<<"\n Forman un triángulo equilatero";
 else
  {
  if(a==b||a==c||b==c)
  cout<<"\n Forman un triángulo isóceles";
  else
   {if(a*a+b*b==c*c||a*a+c*c==b*b||b*b+c*c==a*a)
    cout<<"\n Forman un triángulo rectángulo";
    else
    cout<<"\n Forman un triángulo escaleno";
   }
  }
 }
return 0;
}

Problema logico

4 personas viajan
 

Cuatro personas están viajando a diferentes lugares en diferentes tipos de transporte.
Sus nombres son: Daniel, Juan, Sr.Jones y Cindy.
se pueden ir  en tren, coche, avión o barco.
pero ...
* Sr.Jones odia volar* Cindy tiene que alquilar su vehículo* Juan se marea en el mar


Bueno a simple vista podemos notar que este problema en realidad es algo muy sencillo

vamos a verlo paso por paso


1.- El problema nos dice que ahi 4 personas y  4 formas diferentes de viajar 

2.- Nos dan las condiciones de 3 personas en las cuales 
  1. El  Sr jones no puede volar
  2. Cindy tiene que ir en carro
  3. Juan no puede ir en barco
3.-  ahi 1 persona que puede ir en cualquier medio de tranporte


4.- como el problema implicitamente nos dice que allemos la mejor solucion  para que las 4 personas puedan ir en el medio de trasnporte que les convenga mas  ,  vamos a ver como quedarian acomodados las personas 


5.- entonces como 
  • Sr jones odia volar lo ponemos en un tren 
  • Cindy a fuerzas se va en su carro 
  • Juan se marea en los barcos asi que lo subimos al avion
  • y Daniel como es muy valiente y no tiene problemas con ningun medio de trasnporte lo pones en el barco.
y listo 

pueden hacer algunas variaciones como por ejemplo 


El sr jones se puede ir en barco , y juan se iria en tren 
o el sr jones en barco y daniel en tren.


creo que ya no hace falta explicar mas

Lenguajes Funcionales (puntos extra)

 Lenguajes Funcionales

Los programas escritos en un lenguaje funcional están constituidos únicamente por definiciones de funciones, entendiendo éstas no como subprogramas clásicos de un lenguaje imperativo, sino como funciones puramente matemáticas, en las que se verifican ciertas propiedades como la transparencia referencial (el significado de una expresión depende únicamente del significado de sus subexpresiones), y por tanto, la carencia total de efectos laterales
 .
Otras características propias de estos lenguajes son la no existencia de asignaciones de variables y la falta de construcciones estructuradas como la secuencia o la iteración (lo que obliga en la práctica a que todas las repeticiones de instrucciones se lleven a cabo por medio de funciones recursivas).
Existen dos grandes categorías de lenguajes funcionales: los funcionales puros y los híbridos. La diferencia entre ambos estriba en que los lenguajes funcionales híbridos son menos dogmáticos que los puros, al admitir conceptos tomados de los lenguajes imperativos, como las secuencias de instrucciones o la asignación de variables. En contraste, los lenguajes funcionales puros tienen una mayor potencia expresiva, conservando a la vez su transparencia referencial, algo que no se cumple siempre con un lenguaje funcional híbrido.
Haskell 

 En los años setenta se produjo lo que se conoce como la crisis del software. La gran mayoría del software que se producía no era fiable. Tenía una gran tasa de errores que ponía en grave peligro la confianza de los usuarios en estos sistemas. Por esta razón se propuso una solución: crear un nuevo modelo programación, lo que se conoce como programación funcional. Dentro de este tipo de programación tenemos lenguajes como: el Haskell, el LISP, el Miranda, el Scheme, etc.

El Haskell nació como lenguaje de programación en el año 1987, desde entonces se ha desarrollado considerablemente como un lenguaje de programación funcional puro, de propósito general. El Haskell tiene todas las innovaciones de los lenguajes funcionales como son: desarrollo de las funciones de orden superior, evaluación perezosa, tipos definidos por el usuario, tipos polimórficos estáticos, definiciones de listas por comprensión, encajes patronales, etc.

Ejemplo :
Aqui les pondre algunos ejemplos que son muy sencillos con la intencion de que las personas que batallan como yo , todavia en codificar , tengan una idea de como se trabaja en este lenguaje

funcion que muestra los numeros desde 1 hasta n 
ser1 ::Integer->Integer->String
ser1 a 0=""
ser1 a n=show(a)++" "++ser1 (a+1) (n-1)
ser ::Integer->String
ser n=(ser1 1 n) 

Programa que devuelve los cuadrados de los números desde 1 hasta n.
cuad1 ::Integer->Integer->String
cuad1 a 0=""
cuad1 a n=show(a*a)++" "++cuad1 (a+1) (n-1)
cuad ::Integer->String
cuad n=(cuad1 1 n)

 Programa que dado un número entero n, devuelve todos los primos que existen desde n hasta 1.
pr::Int->Int->Int
pr n 1=0
pr n a| (rem n a)==0=1+(pr n (a-1) )
     |otherwise=(pr n (a-1))
prim::Int->Int
prim 0=1
prim 1=1
prim 2=0
prim b=pr b (b-1)
primo::Int->String
primo 2=""
primo n|(prim n)==0=show(n)++" "++(primo (n-1))
     |otherwise=(primo (n-1))


Espero que estos ejemplos les ayuden , enseguida pondre un link de una manual  que me ayudo mucho
es un archivo en pdf , espero les ayude igual.
Manual para haskell

Erlang
Erlang es un lenguaje de programación de uso general y un sistema para ejecución. Fue desarrollada por la Ericsson para soportar aplicaciones distribuidas y tolerantes la fallos a ser ejecutadas en un ambiente de tiempo real e interrupto. Ella soporta nativamente hot swapping, de forma que el código puede ser modificado sin la parada del sistema. Originalmente era un lenguaje propietaria de la Ericsson, pero fue lanzada en código abierto en 1998.
La implementación de la Ericsson ejecuta un código interpretado en una máquina virtual, pero también incluye un compilador para código nativo (aunque no soportado para todas las plataformas). 

Ejemplos

hola mundo :

-module(primer).
   -export([hello_world/0]).
  
   hello_world() -> 
          "hello world".



 
espero les sirva esta informacion 

Tablas de dispersion (puntos extras)

¿Que son las tablas de dispersion?
son estructuras de datos que tienen como finalidad realizar la búsqueda o eliminación de un registro con una complejidad constante. La organización ideal de una tabla es aquella en la cual el campo clave de los elementos se corresponde directamente con el índice de la tabla. Si por ejemplo, una compañía tiene 300 empleados, cada uno identificado con un número de empleado de 0 a 999, la forma de organizar la tabla es con un arreglo de 1000 registros.

struct Empleado Tabla[1000];
El elemento Tabla[i] almacena al empleado cuyo número de empleado es i. Con esta organización la búsqueda de un empleado se ha realizado directamente, con un único acceso, debido a que el número de empleado es la posición en la tabla. La eficiencia se puede expresar como tiempo constante, 0(1).


¿Cual es su funcion?

 convierte el dato del campo clave, un entero o una cadena, en un valor entero en el rango de definición del arreglo o vector que va a almacenar los elementos, de tal forma que sea adecuado para indexar el arreglo.
La idea básica es utilizar la calve de un registro para determinar su dirección, pero sin desperdiciar mucho espacio, para lo que hay que realizar una transformación mediante una función hash, del conjunto de K claves sobre el conjunto L de direcciones de memoria:
h(x) : K -> L 
 
referencia : http://www.ie.uia.mx/acad/atortole/progra2/hash.html

Estandar IEEE754 (puntos extra)

El estándar de la IEEE para aritmética en coma flotante (IEEE 754) es el estándar más extendido para las computaciones en coma flotante, y es seguido por muchas de las mejoras de CPU y FPU. El estándar define formatos para la representación de números en coma flotante (incluyendo el cero) y valores desnormalizados, así como valores especiales como infinito y NaN, con un conjunto de operaciones en coma flotante que trabaja sobre estos valores. También especifica cuatro modos de redondeo y cinco excepciones (incluyendo cuándo ocurren dichas excepciones y qué sucede en esos momentos).
IEEE 754 especifica cuatro formatos para la representación de valores en coma flotante: precisión simple (32 bits), precisión doble (64 bits), precisión simple extendida (≥ 43 bits, no usada normalmente) y precisión doble extendida (≥ 79 bits, usualmente implementada con 80 bits). Sólo los valores de 32 bits son requeridos por el estándar, los otros son opcionales. Muchos lenguajes especifican qué formatos y aritmética de la IEEE implementan, a pesar de que a veces son opcionales. Por ejemplo, el lenguaje de programación C, ahora permite pero no requiere la aritmética de la IEEE (el tipo de C float es típicamente usado para la precisión simple de la IEEE y el tipo double usa la precisión doble del la IEEE).
El título completo del estándar es IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985), y también es conocido por IEC 60559:1989, Binary floating-point arithmetic for microprocessor systems (originalmente el número de referencia era IEC 559:1989).

Ejemplo : 
odifiquemos el número decimal -118,625 usando el sistema de la IEEE 754.
Necesitamos obtener el signo, el exponente y la fracción.
Dado que es un número negativo, el signo es "1". Busquemos los demás valores:
Primero, escribimos el número (sin signo) usando notación binaria. Mira el sistema de numeración binario para ver cómo hacer esto. El resultado es 1110110,101.
Ahora, movamos la coma decimal a la izquierda, dejando sólo un 1 a su izquierda.
1110110,101=1,110110101·26 Esto es un número en coma flotante normalizado.
La mantisa es la parte a la derecha de la coma decimal, rellenada con ceros a la derecha hasta que obtengamos todos los 23 bits. Es decir 11011010100000000000000.
El exponente es 6, pero necesitamos convertirlo a binario y desplazarlo (de forma que el exponente más negativo es 0, y todos los exponentes son solamente números binarios no negativos). Para el formato IEEE 754 de 32 bits, el desplazamiento es 127, así es que 6 + 127 = 133.
En binario, esto se escribe como 10000101.

referencia : http://es.wikipedia.org/wiki/IEEE_coma_flotante