CodeHood uno. función. Un algoritmo para determinar si un número real es mayor que 50 podría ser:

Descargar (0)

Texto completo

(1)

CodeHood  uno    

función      

Un  algoritmo  para  determinar  si  un  número  real  es  mayor  que  50  podría  ser:  

algoritmo:

# si un número real es mayor que 50 x = 107

si x > 50:

escribe 1

La  sentencia  si  permite  verificar  si  una  condición  es  verdadera  y  entonces  ejecutar  a  o  no  una  o  más  sentencias  que  se  indiquen   en  detalle.  Notemos  también  que  se  escribe  un  1,  el  cual  tomaremos  en  lo  adelante  significando  ‘verdadero’,  y  al  valor  0  como   significando  ‘falso’.    Si  asignamos  a  x  el  valor  25,  el  algoritmo  no  escribe  nada,  pues  la  condición  de  la  sentencia  sí  sería  falsa  y     no  se  ejecutaría  la  sentencia  escribe,  que  sólo  se  ejecuta  cuando  la  condición  es  verdadera.  Ampliemos  un  poco  el  algoritmo:  

algoritmo:

# si un número real es mayor que 50 x = 10

si x > 50:

escribe 1 si x >= 50:

escribe 0

Ahora  se  escribe  1,  verdadero,  si  x  es  mayor  que  50  ,  y  0  en  caso  contrario.  Notemos  que  hay  dos  sentencias  si,  que  se  ejecutan   siempre  ambas,  pero  sólo  se  ejecuta  una  de  las  dos  sentencias  escribe,  ya  que  son  lógicamente  complementarias.  Ahora   siempre  el  algoritmo  escribe  algo,  para  cualquier  valor  de  x.  Podemos  combinar  las  dos  sentencias  si  en  una  sola,  evitando   verificar  la  segunda  condición:  

   

algoritmo:

# si un numero real es mayor que 50 x = 10

si x > 50:

escribe 1 sino:

escribe 0

Se  escribe  1  si  x  es  mayor  que  50,  y  0  en  cualquier  otro  caso.  Por  supuesto,  nunca  ocurren  ambas  cosas  y  nos  ahorramos   explicitar  la  condición  complementaria  a  si  x  es  mayor  que  50.  Una  forma,  que  podemos  llamar  ‘el  mantenimiento  de  la   verdad’,  que  usaremos  en  lo  adelante,  es  hacer  una  suposición  y  luego  verificar  si  se  mantiene,  para  negarla  en  caso  de  que  no   sea  así:  

algoritmo:

# si un numero real es mayor que 50 m = 1 # es mayor

x = 10 si x <= 50:

m = 0 escribe m  

A  la  variable  m  se  le  asigna  el  valor  1  para  significar  que  x  es  mayor  que  50  a  menos  que  encontremos  evidencia  en  contra,  en   cuyo  caso  cambiamos  el  valor  de  m  a  0,  ajustando  la  premisa  con  la  evidencia  de  que  x  no  es  mayor  que  50.  Notemos  que  esta   estrategia  simplifica  el  código  y  garantiza  que  siempre  se  escriba  un  resultado,  con  una  sola  sentencia  escribe,  una  salida  y  no   dos,  como  antes.    Una  generalización  d  este  algoritmo,  que  permita  al  usuario  decidir  el  valor  de  x,  podría  ser:  

 

(2)

algoritmo:

# si un número real es mayor que 50 m = 1 # mayor

x = 0.0 lee x

si x <= 50:

m = 0 escribe m  

 Primero  le  asignamos  a  x  el  valor  0.0  para  indicar  que  es  para  alojar  números  reales  y  luego  le  permitimos  al  usuario  que  ingrese   el  número  real  que  desee.    Para  determinar  el  menor  de  tres  números  reales  podemos  tener  el  algoritmo:  

 

algoritmo:  

# menor de tres números reales a = 0.0

b = 0.0 c = 0.0 lee a, b, c

si a < b y a < c:

escribe a si b < a y b < c:

escribe b si c < a y c < b:

escribe c

Es  claro  nada  se  escribe  nada  si  los  tres  a,  b  y  c,  tienen  el  mismo  valor;  no  se  garantiza  una  salida.  Si  creamos  el  ‘puesto’  de  ‘el   menor’  y  ‘sentamos’  al  primer  valor  en  él,  aseguramos  una  salida  y  el  código  se  simplifica:  

 

algoritmo:

# menor de tres números reales m = 0.0

a = 0.0 b = 0.0 c = 0.0 lee a, b, c m = a si b < m:

m = b si c < m:

m = c escribe m

Podemos  generalizar  este  patrón  para  t  números  reales:  

 

algoritmo:

# menor de t números reales m = 0.0 # menor

a = 0.0 # números reales t = 0 # cantidad de números c = 1 # contador

lee m

mientras c < t:

lee a si a < m:

m = a c = c + 1

escribe m  

Las  variables  m  y  a  son  para  números  reales,  m  el  menor  y  primero,  a  para  los  otros,  uno  a  uno,  que  leen  dentro  del  ciclo,  que  se   ejecuta  t-­‐1  veces.  Antes  de  entrar  al  ciclo  se  lee  el  primer  valor  y  se  asigna  a  m,  que  se  asume  menor  hasta  prueba  en  contra.  

(3)

Dentro  del  ciclo  se  leen  los  siguientes  t-­‐1  valores  de  a,  y  cada  uno  se  va  comparando  con  el  menor  valor  hasta  el  momento   alojado  en  m.  Si  algún  valor  recién  leído  es  menor  que    m,  se  actualiza  el  valor  de  m  con  el  de  a,  pues  ha  aparecido  uno  valor   menor  al  menor  hasta  ahora.  Al  abandonar  el  ciclo,  en  m  queda  el  menor  de  todos  los  valores  leídos.  

 

Para  obtener  la  suma  de  los  dígitos  de  un  número  entero  positivo  podemos  redactar:  

 

algoritmo:

# suma de los dígitos de un numero natural s = 0

n = 123

mientras n > 0:

s = s + n%10 n = n/10 escribe s  

Se  inicia  la  suma  en  cero  para  que  la  primera  vez  que  se  use  dentro  del  ciclo  tenga  un  primer  valor  apropiado.  Notemos  que   n%10  nos  da  el  último  digito  actual  de  n,  pues  %  es  el  operador  residuo  de  la  división,  que  para  123%10  da  3,  el  último  dígito   actual  de  123.  También  vemos  que  n/10  ‘corta’  el  último  dígito  actual  de  n,  por  lo  que  123  queda  en  12.  

Dentro  del  ciclo  se  van  sumando  los  dígitos  de  n,  de  derecha  a  izquierda,  en  s,  y  se  va  reduciendo  n  en  un  dígito  cada  vez.  El  ciclo   se  ejecuta  tantas  veces  dígitos  tenga  n,  y  cuando  n  se  hace  0,  se  abandona  el  ciclo  y  se  escribe  a  s,  la  suma  buscada.  Podemos  

‘empacar’  este  código  para  reusarlo  en  la  solución  de  problemas  futuros  que  lo  incluyan  como  una  parte,  dándole  una  forma   genérica,  tipo  ‘a  quien  pueda  interesar’:  

 

 sumaDigi(n):

# suma de los dígitos de un número natural s = 0

mientras n > 0:

s = s + n%10 n = n/10 retorna s

Decimos  que  sumaDigi,  pues  recibe  un  valor,  n,  y  retorna  otro  valor,  s,  encapsulando  u  ocultando  al  exterior  los  detalles  de   cómo  obtiene  el  valor  de  s  a  partir  de  n.  Para  usarla  le  enviamos  un  valor  y  ella  nos  retorna  otro  valor.  Esto  nos  permite   descomponer  la  solución  de  un  problema  en  partes  mas  pequeñas,  aplicando  el  principio  ‘divide  y  vencerás’.  

 

Así  que  en  programación  implementamos  las  dos  formas  de  la  formas  de  la  abstracción,  a  saber,  generalizar  y  modularizar.  

Generalizamos  con  los  conceptos  de  variable,  valor,  expresión,  sentencia,  ciclo,  decisión;  y  modularizamos  definiendo  e   invocando  funciones.  Una  versión  del  algoritmo  del  algoritmo  para  obtener  la  suma  de  los  dígitos  de  un  natural,  invocando  la   función  sumaDigi  podría  ser:  

 

algoritmo:  

# suma de los dígitos de un número natural s = sumaDigi(123)

escribe s

A  s  se  le  asigna  el  valor  que  retorna  la  función  sumaDigi  luego  de  ejecutarse  con  el  valor  123,  por  lo  que  s  pasa  a  ser  6,  el  se     escribe  a  seguidas.  Notemos  en  la  función  n  concreto  123.  Decimos  que  n  es  un  parámetro,  porque  la  función  esta  redactada   para  una  amplia  variedad  de  valores  de  n,  pero  cada  vez  que  se  ejecuta,  n  toma  un  valor  especifico,  ‘la  unidad  en  la  diversidad’.  

Un  algoritmo  que  escriba  la  suma  de  los  dígitos  de  los  naturales  menores  que  t:  

   

(4)

algoritmo:

# suma de los dígitos de los naturales menores que t t = 0

c = 1 lee t

mientras c < t:

escribe sumaDigi(c), c = c + 1

 

El  ciclo  se  ejecuta  para  cada  uno  de  los  números  naturales  menores  que  t  y  la  sentencia  escribe  hace  que  se  invoque  a  la  función   sumaDigi,  pasándole  el  valor  actual  de  c  y  escribiendo  el  valor  que  retorne.  

 

Las  funciones  nos  permiten  reducir  la  complejidad  de  un  problema  y  reutilizar  partes  genéricas  de  soluciones  obtenidas  en   problemas  futuros.  En  este  sentido,  una  forma  función  es  una  solución  general  a  un  problema  particular.    

 

Podemos  redactar  directamente  una  función  sin  que  provenga  de  la  descomposición  de  un  problema  mayor.  Por  ejemplo,  una   función  que  obtenga  la  suma  de  los  factores  propios  de  un  natural:  

 

sumaFact(n):

# suma de los factores propios de un número natural s = 0

d = 1

mientras d <= n/2:

si n%d = 0:

s = s + d d = d + 1 retorna s  

Los  factores  propios  de  un  numero  natural  son  los  números  naturales  que  dividen  exactamente  al  numero  y  son  menores  que  él.  

La  función  sumaFact  recibe  un  natural  y  retorna  la  suma  de  sus  factores  propios.  Para  ello  inicia  la  suma,  s,  en  0  y  en  1  al  divisor   d,  luego  recorre  todos  los  posibles  divisores  de  n  hasta  la  mitad  de  n,  y  no  busca  mas  allá  porque  la  mitad  de  n  es  su  máximo   divisor  propio.  En  el  siglo  se  verifica  si  d  es  factor  de  n,  en  cuyo  caso  se  suma  d  a  s,  pero  pase  lo  pase  se  incrementa  en  1  a  d.  Al   abandonar  el  ciclo  se  retorna  a  s,  la  suma  de  los  divisores  propios  de  n.  Un  algoritmo  que  determine  si  un  numero  natural  es   perfecto,  igual  a  la  suma  de  sus  factores  propios  podría  ser:  

 

algoritmo:

# si un natural es perfecto p = 0

n = 0 lee n

si n = sumaFact(n):

p = 1 escribe p

Un    numero  natural  n  es  perfecto  si  la  suma  de  sus  factores  propios  es  igual  a  n.  Este  algoritmo  asume  que  n  no  es  perfecto   asignando  0  a  p,  pero  cambia  p  a  1,  verdadero,  si  resulta  que  el  valor  que  retorna  la  función  sumaFact  enviándole  a  n  coincide   con  n,  pues  significa  que  n  es  perfecto.  Una  función  que  determine  si  la  suma  de  los  factores  propios  de  un  natural  n  es  menor  (-­‐

1),  igual  (0),  o  mayor  (1)  que  n,  podría  ser:  

 

perfeccion(n):

# perfección de un natural: -1, 0, 1 p = -1

si sumaFact(n) = n:

p = 0

(5)

p = 1 retorna p

Notemos  que  se  asume  que  n  es  deficiente  (p  =  -­‐1)  y  si  resulta  perfecto,  sumaFact(n)  =  n,  se  cambia  a  0  (p  =  0),  o  a  1  (p  =  1)  si   resulta  ser  mayores.  De  manera  que    un  algoritmo  que  encuentre  los  primeros  4  números  perfectos,  invocando  esta  función,   podría  ser:  

 

algoritmo:

# primeros 4 naturales perfectos c = 1

cp = 0

mientras cp < 4:

si perfeccion(n) = 0:

escribe n, cp = cp + 1 c = c + 1

Notemos  que  la  variable  cp  solo  se  incrementa  cuando  la  perfección  de  n  es  0,  mientras  que  c  se  incrementa  indefinidamente.  A   c  se  le  incrementa  en  1  cada  vez  que  se  ejecuta  el  ciclo,  por  lo  que  eventualmente  llega  a  un  valor  para  el  cual  cp  se  incremente   por  cuarta  vez,  y  el  ciclo  se  abandona,  habiendo  escrito  los  primeros  4  naturales  perfectos.  

 

Una  versión  en  lenguaje  C  de  este  algoritmo  que  obtiene  los  primeros  4  naturales  perfectos  podría  ser:  

 

// primeros 4 naturales perfectos

#include <stdio.h>

long sumaFact(long n)

{ // suma de los factores propios de un número natural

long s = 0, d = 1;

while (d <= n/2) {

if (n%d == 0) s += d;

d++;

}

return s;

}

long perfeccion(long n) {

// perfección de un natural: -1, 0, 1 long p = -1; // perfeccion

if (sumaFact(n) == n) p = 0;

if (sumaFact(n) > n) p = 1;

return p;

}

int main() {

// primeros 4 naturales perfectos

(6)

long c = 1, cp = 0;

while (cp < 4) {

if (perfeccion(n) == 0) {

printf("%ld ", n);

cp++;

} c++;

}

return 0;

}

Una  versión  en  Python  podría  ser:  

 

# primeros 4 naturales perfectos def sumaFact(n):

# suma de los factores propios de un número natural s = 0

d = 1

while d <= n/2:

if n%d is 0:

s += d d+= 1;

return s

def perfeccion(n):

# perfección de un natural: -1, 0, 1 p = -1 // perfeccion

if sumaFact(n) == n:

p = 0

if sumaFact(n) > n:

p = 1 return p

# primeros 4 naturales perfectos c = 1

cp = 0

while cp < 4:

if perfeccion(n) is 0:

print n, cp += 1 c = c + 1

La  versión  Python  es  más  flexible  y  corta,  pero  la  versión  C  es  más  robusta  y  rápida  en  la  ejecución.  Cada  lenguaje  tiene  sus   ventajas  en  aquello  para  lo  que  fue  creado.  No  es  que  alguno  sea,  en  sentido  absoluto,  mejor  que  otro.  

   

ecabrera,  sdqdr,  febrero  2015  

Figure

Actualización...

Referencias

Related subjects :