Otros ejemplos

function sumAcum(sequence a)  -- Devuelve la suma acumulada de los átomos de 'a'
sequence resultado
   resultado = repeat(0, length(a))

   resultado[1] = a[1]

   for i = 2 to length(a) do
     resultado[i] = resultado[i - 1] + a[i]
   end for

  return resultado

end function
 

function prodEscalar(sequence a, sequence b)   -- 'a' y 'b' han de tener el mismo tamaño
atom total
sequence resultado
   resultado = a * b   -- multiplicamos los átomos de 'a' con los de 'b' ¡en un sólo paso!
  total = 0

   for i = 1 to length(resultado) do
     total += resultado[i]   -- sumamos todos los átomos de la secuencia resultado
  end for

  return total

end function
 

function pares(sequence lista)  -- devuelve los números pares de la secuencia 'lista'
sequence resultado
   resultado = {}

   for i = 1 tolength(lista) do
     if not remainder(lista[i], 2) then    -- es par si lista[i] / 2 = 0
        resultado = append(resultado, lista[i])
     end if
  end for

  return resultado

end function
 

function inserta(object x, sequence lista)

   for i = 1 to length(lista) do
     if compare(x, lista[i]) = -1 then -- si 'x' es menor que 'lista[i] ...
        returnlista[1..(i - 1)] & x & lista[i..length(lista)] -- ... lo insertamos
     end if
  end for

  return lista & x   -- 'x' va al final o es el primer elemento a insertar

end function
 

function MayorMenor(object x, sequence lista)   -- devuelve dos listas con los objetos que son
sequence mayor, menor
-- mayores (o iguales) y menores que 'x'
  mayor = {}
   menor = {}

   for i = 1 to length(lista) do
     if compare(x, lista[i]) = -1 then
        mayor &= lista[i]
     else
        menor &= lista[i]
     end if
  end for

  return {mayor, menor}

end function
 

La funcionalidad de comprime es la de generar una secuencia cuyos elementos tienen la forma {y, cont}, donde cont indica el número de veces consecutivas que se repite y. Por ejemplo, si la secuencia de entrada fuese : {1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 1, 1, 1, 1, 4, 4, 4}; el resultado sería: {{1, 6}, {2, 4}, {3, 5}, {1, 4}, {4, 3}}.

function comprime(sequence x)
integer cont
object y
sequence resultado

   if equal({}, x) then
     return {}
   end if

  resultado = {}
   y = x[1]
   cont = 1

   for i = 2 to length(x) do
     if equal(x[i], y) then
        cont += 1
     else
        resultado = append(resultado, {y, cont})
--         resultado &= {{y, cont}}                -- otra manera de hacerlo
        y = x[i]
         cont = 1
     end if
  end for

  return append(resultado, {y, cont})

end function
 

El árbol de datos es una estructura bien conocida en programación, y muy adecuada para ser manejada mediante métodos recursivos.

-- rama -> {7, {}, {}}
-- arbol -> inicialmente, es igual a {{}, {}, {}}

constant DAT = 1, IZQ = 2, DER = 3, NIL = {}, SI = 1, NO = 0

function insertaEnArbol(sequence arbol, sequence rama)
integer opcion

   if equal(arbol, NIL) then
     arbol = rama
     return arbol
   elsif rama[DAT] < arbol[DAT] then
     opcion = IZQ
   else
     opcion = DER
   end if

  arbol[opcion] = insertaEnArbol(arbol[opcion], rama)
  return arbol

end function
 

function listaAarbol(sequence lista)  -- convierte una secuencia de objetos en un árbol
sequence resultado
   resultado = NIL

   for i = 1 to length(lista) do
     resultado = insertaEnArbol(resultado, {lista[i], NIL, NIL})
   end for

  return resultado

end function
 

function existeEnArbol(sequence arbol, object x)   -- busca un elemento en un árbol
integer respuesta

   if equal(arbol, {}) then   -- el árbol está vacio
     return NO
   elsif equal(arbol[DAT], x) then   -- ¡lo encontramos!
     return SI
   else
     respuesta = existeEnArbol(arbol[IZQ], x)   -- buscamos a través de la rama izquierda
     if respuesta then   -- esta es una forma abreviada de escribir 'if respuesta = SI then'
        return SI
     else
        return existeEnArbol(arbol[DER], x)   -- buscamos a través de la rama derecha
     end if
  end if

end function
 

'Alisar' es una función que da como resultado una lista símple de átomos a partir de una secuencia de secuencias. Por ejemplo, de una secuencia con la siguiente forma: {5, 4, 7, {78.3, {9, {2}}}}; obtendríamos el siguiente resultado: {5, 4, 7, 78.3, 9, 2}.

function alisar(sequence secuencia)
sequence lista
   lista = {}

   for i = 1 to length(secuencia) do
     if sequence(secuencia[i]) then   -- si el elemento i es a su vez una secuencia ...
        lista &= alisar(secuencia[i])   -- ... invocamos recursivamente la función 'alisar'
     else
        lista &= secuencia[i]   -- si no es una secuencia, es que es un átomo
     end if
  end for

  return lista

end function

Como curiosidad, vamos a ver la forma en que Prolog resuelve este problema..

concat([], Ys, Ys).
concat([X|Xs], Ys, [X|Zs]) :- concat(Xs, Ys, Zs).

alisar([], []).
alisar([X|Xs], Ls) :- list(X), alisar(X, Ls1), alisar(Xs, Ls2), concat(Ls1, Ls2, Ls).
alisar([X|Xs], [X|Ls]) :- atomic(X), alisar(Xs, Ls).

Imitemos este procedimiento en Euphoria.

function alisar_2(object x)
sequence resultado

   if atom(x) then
     return x
   elsif equal(x, {}) then
     return {}
   else
     resultado = {}
      resultado &= alisar_2(x[1])
      resultado &= alisar_2(x[2..length(x)])
   end if
  return resultado

end function

Probablemente, un veterano de los lenguajes declarativos preferiría esta segunda manera de enfocar la tarea, pero qué duda cabe que un habitual de los lenguajes imperativos optará por la primera. Ambas formas funcionan, así que ¡a gusto de cada cual!
 



(anterior)             (siguiente)