How to implement a function to return the sum of squares of the proposed form?

0

I did not quite understand the one proposed here. The whole doubt is in combiner, by statement, I understand to be a delegate. You see, they do not need to post codes, I would just like a way forward. Below the statement. The whole part marked with the tag code, is the statement, including the texts. Doing a function that returns the sum of squares I have already done and is working, but I need now the form proposed by this exercise.

function acumular(combiner, nullValue, list)
{
    if (list.length == 0) {
        return nullValue;
    }
    var primeiro = list.removePrimeiro();
    return combiner(primeiro, acumular (combiner, nullValue, list));
}

Implemente a função somaDeQuadrados que retorna a soma de quadrados de uma lista.

somaDeQuadrados([1,2,3,4,5])
retorna o número 55.

Neste caso a função acumular deve ser utilizada. A variável “combiner” é um “ponteiro para função”. A implementação da função “combiner” faz parte da solução.

What I really need is a path and not a code, because I want to do, as I have done the others.

My big question is in the implementation of Combine. I did not fully understand what the dcastro posted. If someone understood or the dcastro itself, can, thank you with any additional help.

My biggest difficulty lies in implementing the Build function, because it takes an argument of the type of a method (Combiner). My Combiner method is implemented as follows:

private int Combiner(int primeiro, int acc)
        {
            acc += primeiro * primeiro;

            return acc;
        }

And the accumulate method I'm catching like this:

public int acumular(int combiner, int? nullValue, List<int> list)
        {            
            if (list.Count == 0)
                return 0;
            var primeiro = list.First();
            list.RemoveAt(0);

            return Combiner(primeiro, acumular(Combiner(primeiro,1),null,list));
        }

The return 0 is out of the proposed and the parameters in the recursive call to accumulate.

I thought I was wrong, but it worked out the sum of the squares in the way above. I made the call like this:

int[] inteiros = {1,2,3,4,5,6,7};
List<int> lista = new List<int>(inteiros);
lblFat.Text = f.acumular(1,null,lista).ToString();

As the array already exists, I just assign the array to the list, so it does not fill, so it has array and list in the call, but the call does not go to the test.

    
asked by anonymous 06.07.2015 / 17:51

2 answers

3

acumular is a function that traverses a list, from left to right, and calling the function combine by passing 2 arguments:

  • The value that is currently being examined
  • The accumulator of the rest of the list
  • Therefore, combiner must have the following signature:

    int combine(int x, int acc)
    

    In the end, it will be called this:

    combine(1, combine(2, combine(3, combine(4, combine(5, nullValue)))))
    

    I think these tips should be enough to solve the exercise.

    (Note: this acumular function is usually called foldRight / fold in functional programming languages, or Aggregate " in the specific case of C #)

    Update

    Some things wrong with your current code:

  • The combiner parameter of the acumular function should be a pointer to a function (as it says in the statement), not a int . Then it should be of type Func<int, int, int> - that is, combiner is a delegate that accepts two integers and returns another integer.
  • nullValue e 'type int , not int?
  • The value of nullValue is not null - I think the parameter name was badly chosen. The value of nullValue is the integer that will be combined with 5 at the beginning. What integer do you think it should be?
  • The last line of the acumular function is wrong: you can not call the function Combiner , only the delegate combiner .
  • In fact, the last line of the acumular function can be copied from the statement without changes: return combiner(primeiro, acumular (combiner, nullValue, list))
  • If you still have questions, I can put the full answer here, but I think you can get there with just these tips;)

    Solution

    public int Acumular(Func<int, int, int> combiner, int nullValue, List<int> list)
    {            
        if (list.Count == 0)
            return 0;
    
        var primeiro = list.First();
        list.RemoveAt(0);
    
        return combiner(primeiro, Acumular(combiner, nullValue, list));
    }
    
    public int Combiner(int x, int acumulador)
    {
        return (x*x) + acumulador;    
    }
    
    var list = new List<int> {1,2,3,4,5};
    
    Acumular(Combiner, 0, list);
    

    As combiner will be called recursively, so it will be called like this:

    combiner(1, combiner(2, combiner(3, combiner(4, combiner(5, nullValue)))))
    

    Replacing combiner with formula x*x + acumulador , and nullValue with 0:

    1*1 + (2*2 + (3*3 + (4*4 + (5*5 + 0))))
    

    What equals 55

    Fiddle: link

        
    06.07.2015 / 18:28
    2

    You can also use a online function

        List<int> list = new List<int> {1,2,3,4,5};
    

    Using the proposed list:

        Func<List<int>, int> Qd = null;
        Qd = 
            x => 
            (x.Count == 0) ? 0 : x.Last() * x.Last() + Qd(x.Take(x.Count-1).ToList<int>());
    
    
        var resultado = Qd(list);
    

    Still using Linq

        Func<List<int>, int> Qd = 
            x => 
            x.Select(i => i*i).Sum();
        var resultado = Qd(list);
    

    Using the function pass, as proposed by the statement

        Func<Func<int, int, int>, List<int>, int> Qd = null;
        Qd = 
            (a, c) => 
            (c.Count == 0) ? 0 : a(c.Last(), Qd(a, c.Take(c.Count-1).ToList<int>()));
        Func<int, int, int> QdS = 
            (a, b) => 
            b + (a*a);
    
        //neste caso a chamada deve ser feita assim:
        var resultado = Qd(QdS, list);
    

    The two examples are on DotNetFiddle

        
    08.07.2015 / 00:54