Mostrando entradas con la etiqueta Functional Programming. Mostrar todas las entradas
Mostrando entradas con la etiqueta Functional Programming. Mostrar todas las entradas

martes, 27 de febrero de 2018

Programación Funcional en LINQ - 2.19: Teoría de Números: Generar Triángulo de Pascal (Versión Iterativa)

1. Problema

Generar un triángulo de Pascal.

2. Solución

Para la solución de este problema no se usará recursión; a razón de que puede resultar lento y podría ocasionar un desbordamiento de memoria.


Se recurre al uso de la técnica de memorización: almacenamiento externo para guardar cálculos, y que éstos sirvan para las siguientes iteraciones (Mukherjee, 2014).

3. Código C#




Aunque el código anterior incluye comentarios, valdría la pena hacer notas acerca de cómo se generan los nuevos valores:
  • Línea 32-33: El método de extensión First busca la primera coincidencia que cumpla la condición:

    v => v.Item1 == (filaActual - 1) && v.Item2 == (j - 1)

    Esto quiere decir que va a buscar el Item1 que cumpla la condición (filaActual - 1): fila anterior; y además, el Item2 que cumpla condición (filaActual - 1):  columna anterior.

    De forma análoga para el ítem que suma el siguiente valor de la fila anterior y de la columna actual:

    v => v.Item1 == (filaActual - 1) && v.Item2 == j

    Nótese que la expresión v.Item2 == j hace referencia al valor (Item3) que está enseguida de la columna anteriormente encontrada.
Prueba de ejecución:
Triángulo de Pascal con 12 filas.
Figura 1. Triángulo de Pascal con 12 filas.

4. Literatura & Enlaces

Mukherjee, S (2014). Thinking in LINQ Harnessing the Power of Functional Programming in .NET Applications. United States: Apress.

O

lunes, 26 de febrero de 2018

Programación Funcional en LINQ No. 2-18.4: Teoría de Números - Generar Factoriones

1. Problema

Generar factoriones en LINQ.

2. Solución

Un factorión es un número natural que es igual a la suma del factorial de sus dígitos. Algebraicamente, queda expresado como:
Definción algebraica de un factorión

Un ejemplo sería 145:


145 = 1 + 24 + 120 = 1! + 4! + 5!

3. Código C#


En las líneas 12-25 está definido el método de extensión Digitos(): permite descomponer un número dado en sus dígitos.


Por su parte, el método Main() (líneas 1-8) efectúa las siguientes operaciones:
  • Línea 3: Genera un rango de números enteros entre 0 y 1000.
  • Línea 4: Aplica el filtro que comprueba que la suma del factorial de los dígitos de k es igual a k:
    • Línea 5: Un nuevo filtro es aplicado para obtener sólo aquellos digítos que son mayores a 0: n > 0
      • Línea 6: Se hace la proyección que consiste en calcular el factorial de cada uno de los dígitos y luego hallar su suma:

        Select(d => Enumerable.Range(1, d).Aggregate((x, y) => x * y)).Sum()
Prueba de ejecución:
Factoriones
Figura 1. Factoriones.

4. Literatura & Enlaces

Bernard J. (2016). Python Recipes Handbook: A Problem-Solution Approach. Canada: Apress.

O

domingo, 25 de febrero de 2018

Programación Funcional en LINQ No. 2-18.3: Teoría de Números - Obtener Números Suma-Producto

1. Problema

Generar números suma-producto utilizando LINQ.

2. Solución

Un número suma-producto es un entero que se obtiene a partir del producto entre la sumatoria y la productoria de los dígitos. Esta definición se puede expresar así:
Definición algebraica de un número suma-producto

La variable l indica la cantidad de dígitos en el número; y las variables d con índice i o j indican el enésimo dígito del número n.

3. Código C#


En las líneas 14-26 se define el método de extensión Digitos(); este método se usa para obtener cada uno de los dígitos de un número como una secuencia.


Entre las líneas 1-9 está definido el método Main(); aquí ocurren las siguientes operaciones:
  • Línea 3: Se genera una secuencia con valores enteros entre 0 y 1000.
  • Línea 4: Se aplica la aplicación filtro Where.
    • Línea 5: Para el k número de la secuencia se obtienen sus dígitos.
    • Línea 7: Se comprueba el predicado que define un número suma-producto; es decir:

      digitos.Sum() * digitos.Aggregate((x, y) => x * y) == k

      Si el producto entre la sumatoria y la productoria de los l dígitos del k número es igual k, entonces k es un número suma-producto.
Prueba de ejecución:
Números suma-producto entre 0 y 1000.
Figura 1. Números suma-producto entre 0 y 1000.

4. Literatura & Enlaces

Mukherjee, S (2014). Thinking in LINQ Harnessing the Power of Functional Programming in .NET Applications. United States: Apress.

O

Programación Funcional en LINQ No. 2-18.2: Teoría de Números - Generar Números de Dudeney

1. Problema

Generar números de Dudeney usando programación funcional.

2. Solución

El cubo perfecto de un número entero positivo se conoce como número de Dudeney: consiste en sumar cada uno de los dígitos y luego elevarlo al cubo; el resultado será el número original (Mukherjee, 2014).


Por ejemplo:

Número de Dudeney

3. Código C#


El método de extensión Digitos() (líneas 12-24) permite descomponer un número en sus dígitos.


En el bloque de código del método Main() (líneas 1-6) se lleva a cabo las siguientes operaciones:
  1. Línea 3: a través de la función generadora Range() se crea una secuencia de números entre 0 y 1000.
  2. Línea 4: Se aplica la función filtro Where() para obtener sólo los números que cumplan con el predicado que define un número de Dudeney representando por e:
    1. La suma de los dígitos de e al cubo es igual al número e; en otras palabras:

      Math.pow(e.Digitos().Sum(), 3) == e
Prueba de ejecución:
Números de Dudeney entre 0 y 1000
Figura 1. Números de Dudeney entre 0 y 1000.

4. Literatura & Enlaces

Mukherjee, S (2014). Thinking in LINQ Harnessing the Power of Functional Programming in .NET Applications. United States: Apress.

O

Programación Funcional en LINQ No. 2-18.1: Teoría de Números - Generar Números de Armstrong

1. Problema

Generar números de Armstrong utilizando los elementos de programación funcional que dispone LINQ.

2. Solución

Un número de Armstrong es número que se obtiene a partir de la suma de los dígitos elevados al cubo (Mukherjee, 2014); es decir:
Número de Armstrong

3. Código C#

Archivo C# numeros-armstrong.cs [enlace alternativo]:



El método de extensión Digitos() (líneas 4-16) es el que permite descomponer un número dado en sus dígitos.


En el método Main() (líneas 19-24) se realizan las siguientes operaciones:
  • Se genera el rango 0-1000: Enumerable.Range(0, 1000)
  • Se utiliza la función filtro Where para comprobar que la suma de los dígitos (cada uno elevado al cubo) es igual al número actual k.
    • Por cada número k del rango (0-1000) se realiza la proyección de elevar al cubo cada dígito (obtenidos con la método de extensión Digitos()); y finalmente aplicar la función estadística de Sum() para sumar todos los cubos.
Prueba de ejecución:
Números de Armstrong entre 0 y 1000.
Figura 1. Números de Armstrong entre 0 y 1000.

4. Literatura & Enlaces

Mukherjee, S (2014). Thinking in LINQ Harnessing the Power of Functional Programming in .NET Applications. United States: Apress.

O

viernes, 23 de febrero de 2018

Programación Funcional en LINQ No. 2-17: - Colecciones - Encontrar el Valor Mínimo y Máximo por Índice

1. Problema

Encontrar el valor mínimo y máximo por índice en distintas sequencias.

2. Solución

El operador Zip se aplica a una sequencia que recibe como argumento otra secuencia, y luego, como segundo argumento los valores de los índices 0, 1, etc. de cada una de las secuencias. Estos valores son comparados con los métodos Math.Min(val1, val2) y Math.Max(val1, val2) (Mukherjee, 2014).

3. Código C#

Archivo C# minimos-maximos-por-indice-secuencias.cs [enlace alternativo]:

Prueba de ejecución en LINQPad:
Mínimos y máximos por índice en secuencias
Figura 1. Mínimos y máximos por índice en secuencias.

4. Literatura & Enlaces

Mukherjee, S (2014). Thinking in LINQ Harnessing the Power of Functional Programming in .NET Applications. United States: Apress.

O

lunes, 5 de diciembre de 2016

Programación Funcional en LINQ No. 1-2: Declaración de Métodos Funcionales en C#

Resumen

En este vídeotutorial se exploran los delegados estándar y genéricos con los que es posible definir métodos funcionales. Se demuestra a través de ejemplos las diferencias entre estos dos tipos de delegados; por otra parte, también se implementa la composición gof=g(f(x)) usando delegados Func.

Videotutorial

Literatura & Enlaces

Mukherjee, S (2014). Thinking in LINQ Harnessing the Power of Functional Programming in .NET Applications. United States: Apress.
Delegates (C# Programming Guide) (2016). Recuperado desde: https://msdn.microsoft.com/en-us/library/ms173171(v=vs.110).aspx
Delegados en C# - Parte 5: Delegados Func y Action de .NET Framework (2016). Recuperado desde: https://ortizol.blogspot.com.co/2014/05/delegados-en-csharp--parte-5-delegados-func-y-action-de-dotnet-framework.html
Composition of Functions (2016). Recuperado desde: https://www.mathsisfun.com/sets/functions-composition.html


O

miércoles, 13 de julio de 2016

LINQ Recipe No. 2-17: Collections - How to Find the Larger or Smaller Value of Sequences at Each Element Index

Contents

1. Introduction
2. Keywords
3. Problema
4. Solution
5. Discussion
5.1 Zip() standard query operator
6. Pratice: Denoting Bidding Values
7. Conclusions
8. Literature & Links

1. Introduction

With this new LINQ recipe the programmer will learn how to find the larger or smaller value from several given sequences. These sequences have the same length and are composed of numeral values. Particularly, the programmer is going to use, once again, the Zip() standard query operator from LINQ to accomplish this computation. In the practice section, the reader will know how to find the maximum and minimum bid values from the given sequences. LINQ is amazing!

2. Keywords

  • Collection
  • LINQ
  • Sequence
  • Standard query operator
  • Zip()

3. Problem

Find the minimum or maximum value of several sequences at each element index.

4. Solution

In LINQ we find the Zip() standard query operator to apply some specified function to a sequence of elements; the function uses each index as input values.

5. Discussion

5.1 Zip() standard query operator

Zip() is a standard query operator; it's useful to apply some specified function to each element index of a sequence. Visually, it can viewed as 
Zip visual operation schema
Illustration 1. Zip() visual operation schema.
Notice that each index from seq1 has its corresponding index on seq2: the function operates over each index.

To exemplify it, this code concatenates the symbol and literal representations for numbers: 

int[] numbers = { 1, 2, 3 };
string[] words = { "One", "Two", "Three"};

var numbersAndWords = numbers.Zip(words, (n, w) =>
String.Format("{0} - {1}", n, w));

numbersAndWords.Dump("Numbers and Words");

Once executed in LINQPad, this is the result: 
Zip() example
Illustration 2. Zip() example.

6. Practice: Denoting Bidding Values

Suppose we have two collections to represent the bidding values for different items.

The purpose with this recipe is to learn how, by means of LINQ, to find the smaller and larger of bidding values.

LINQ file MinMaxBids.cs [Mirror 1][Mirror 2]: 
Lines 2 and 3 define two list of bid values as integer elements. Next, lines 6-8, we call Zip() function to find the maximum bids from sequence's indexes. Observe how the Math.Max() function is used to find the maximum between the two parameters bid1 and bid2.


Analogally, lines 11-13, compute the Math.Min() function to find the minimum of the two parameters -bid1 and bid2.


The output in LINQPad
Minimum and maximum bids
Illustration 1. Minimum and maximum bids.

An extended version of this solution consists on multiple bid sequences (it's a generalized approach): 

LINQ file MinMaxBidsGeneralApproach.cs [Mirror 1][Mirror 2]: 

Four sequences are defined to contain bid values (lines 2-5). All these sequences are added to a list of lists (lines 8-12). Its purpose is to find the smaller and larger bid values using the Aggregate ("Enumerable.Aggregate(TSource) Method", 2016); basically, what this method does is apply an accumulator over a sequence.


Once executed, this is the resultant output in LINQPad
Minimum and maximum bids (general approach)
Illustration 3. Minimum and maximum bids (general approach).
Video tutorial: 

7. Conclusions

We have used the Zip() as programmatic mechanism to find the smaller or larger values from two sequences. This knowledge is useful for many applications which require this kind of computation for some type of values.


Next LINQ recipe is going to explain how to generate Armstrong Numbers and similar number sequences.

8. Literature & Links

Mukherjee, S (2014). Thinking in LINQ Harnessing the Power of Functional Programming in .NET Applications. United States: Apress.
Enumerable.Zip(TFirst, TSecond, TResult) Method (System.Linq) (2016, julio 13). Retrieved from: https://msdn.microsoft.com/en-us/library/dd267698%28v=vs.100%29.aspx?f=255&MSPPError=-2147217396
Enumerable.Aggregate(TSource) Method (IEnumerable(TSource), Func(TSource, TSource, TSource)) (System.Linq) (2016, julio 13). Retrieved from: https://msdn.microsoft.com/en-us/library/bb548651(v=vs.110).aspx


O

jueves, 7 de julio de 2016

LINQ Recipe No. 2-16: How to Pick Every nth Element from a Collection

Contents

1. Introduction
2. Keywords
3. Problem
4. Solution
5. Discussion
5.1 Range(int, int) method
5.2 Skip() method
6. Practice: Picking Every nth Element from a Collection
7. Conclusions
8. Literature & Links

1. Introduction

A task like element selection, or more particularly pick every nth element, from a collection is a common problem that frequently appears in other problems such as randomizing, listing, or load distribution. In this LINQ recipe will demonstrate to the programmer how to write an idiomatic LINQ program to query a collection for finding every nth element.

2. Keywords

  • Collection
  • LINQ
  • List
  • Load distribution
  • Query

3. Problem

Pick every nth element from a given sequence (without dividing the index to determine whether to include an element from the collection).

4. Solution

First, it's possible to divide the sequence's count property by the nth element, and then use Skip() method to bypass a specified number of elements in the sequence.

5. Discussion

5.1 Range(int, int) method

Range() method generates a sequence of number for a range. ("Enumerable.Range Method", 2016). For example: 

IEnumerable<int> cubes = Enumerable.Range(1, 10).Select( x => x * x * x);

Here, Range generates the range of numbers from 1 to 10 as counting, i.e., 10 numbers. Then Select() produces the 3rd power for each number from 1 to 10.

5.2 Skip() method

This method is used to bypass a given number of elements, and it returns the remaining elements of the sequence ("Enumerable.Skip(TSource)", 2016).

int[] grades = {53, 61, 97, 91, 89, 71};

IEnumerable lowerGrades = grades.OrderByDescending(g => g)
.Skip(3);

What we get with this expression is lower grades: in the first place, the sequence is sorted in descending order, then with Skip(3) the higher grades -97, 91, and 89- are skipped.

6. Practice: Picking Every nth Element from a Collection

Now it's time to write an idiomatic LINQ query in LINQPad to pick every nth element in a sequence.

With int n = 10; (line 2) we specify the nth element: in this case we will pick every 10th element. In line 5 we request a list of 100 numbers -range 1 to 100.


It's required a data structure, in this case a list, to store the nth elements; that is define in line 8List<int> nthElements = new List<int>();.


With this in mind, we got lines 11-13: here the expression Enumerable.Range(0, numbers.Count()/n) produces a range from 0 to 9; its purpose is allow the iteration of each nth element in the numbers list.


Now the code numbers.Skip(k*n).First() skips the k*n elements in numbers, and chooses the first element of the remaining elements generated by Skip(k*n).


Let's play an execution for this amazing LINQ code: 

7. Conclusions

An operation like pick an element from a collection is a common task; this recipe has showed us how to pick every nth element from a sequence by using the Skip() and First() methods.

The next recipe, the LINQ programmer will learn how to find the larger or smaller of several sequences at each index.

8. Literature & Links

Mukherjee, S (2014). Thinking in LINQ Harnessing the Power of Functional Programming in .NET Applications. United States: Apress.
Enumerable.Range Method (Int32, Int32) (System.Linq) (2016, July 7). Retrieved from: https://msdn.microsoft.com/en-us/library/system.linq.enumerable.range(v=vs.110).aspx
Enumerable.Skip(TSource) Method (IEnumerable(TSource), Int32) (System.Linq) (2016, July 7). Retrieved from: https://msdn.microsoft.com/en-us/library/bb358985%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396


V