using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Tételek_LINQ
{
    class Program
    {
        static public List<int> egyik = new List<int>();
        static public List<int> másik = new List<int>();
        static public void generál(int méret)
        {   //adatbeolvasás helyett egy véletlenszámokat generálunk
            Random r = new Random();
           
            for (int i = 0; i < méret; i++)
            {
                egyik.Add(r.Next(20));
                másik.Add(r.Next(20));
            }
            egyik.Distinct(); //egyszeres előfordulás
            másik.Distinct();
            
        }
        static public int összegzés_hagyományosan()
        {
            int s = 0;
            for (int i = 0; i < egyik.Count; i++)
                s += egyik[i];
            return s;
        }
        static public int összegzés_LINQ()
        {
            return egyik.Sum();
        }
        static public bool eldöntés_hagyományosan(Func<int,bool> T) //delegált használat
        {
            int i= 0;
            while (i < egyik.Count && !T(egyik[i]))
                i++;
            return i<egyik.Count();
        }
        static public bool eldöntés_LINQ(Func<int, bool> T)
        {
            return egyik.FindIndex(x=>T(x)==true)>=0; //-1, ha nincs
        }
        static int megszámolás_hagyományosan(Func<int, bool> T)
        {
            int db = 0;
            for(int i=0;i<egyik.Count;i++)
            {
                if (T(egyik[i])) db++;
            }
            return db;
        }
        static int megszámolás_LINQ(Func<int, bool> T)
        {
            return egyik.Where(x=>T(x)==true).Count();
        }
        static int kiválasztás_hagyományosan(Func<int, bool> T)
        {
            int i = 0;
            while (!T(egyik[i]))
                i++;
            return egyik[i];
        }
        static int kiválasztás_LINQ(Func<int, bool> T) //értéket adunk vissza
        {
            return egyik.Where(x => T(x) == true).First();
        }
        static int maximumkiválasztás_hagyományosan(Func<int, bool> T)
        {
            int maxérték = egyik[0];
            for (int i=1;i<egyik.Count();i++)
            {
                if (maxérték < egyik[i]) maxérték = egyik[i];
            }
            return maxérték;
        }
        static int maximumkiválasztás_LINQ(Func<int, bool> T)
        {
            return egyik.Max();
        }
        static (bool,int) keresés_hagyományosan(Func<int, bool> T)
        {
            int i = 0;
            while (i < egyik.Count && !T(egyik[i]))
                i++;
            return (i < egyik.Count, egyik[i]);
        }
        static (bool, int) keresés_LINQ(Func<int, bool> T) //tuple
        {
            return egyik.Where(x => T(x) == true).Select(x => (egyik.IndexOf(x) > -1,  x )).First();
        }
        static List<int> kiválogatás_hagyományosan(Func<int, bool> T)
        {
            List<int> eredmény = new List<int>();
            for (int i=0;i<egyik.Count();i++)
            {
                if (T(egyik[i]))
                    eredmény.Add(egyik[i]);
            }
            return eredmény;
        }
        static List<int> kiválogatás_LINQ(Func<int, bool> T)
        {
            return egyik.Where(x => T(x) == true).ToList();
        }
        static public void rendez_hagyományosan()
        {
            int csere;
            for (int i = 0; i < egyik.Count - 1; i++)
            {
                for (int j = i+1; j < egyik.Count; j++)
                {
                    if (egyik[i] > egyik[j])
                    {
                        csere = egyik[i]; egyik[i] = egyik[j]; egyik[j] = csere;
                    }
                }
            }
        }
        static public void rendez_LINQ()
        {
             egyik.Sort(); //elemhez tartozó alapértelmezett reláció
        }
        static public List<int> unio_hagyományosan()
        {
            List<int> eredmény = egyik; //swallow copy
            for (int i = 0; i < másik.Count(); i++)
            {
                int j = 0;
                while (j < egyik.Count()-1 && egyik[j] != másik[i])
                    j++;
                if (j >= egyik.Count())
                    eredmény.Add(másik[i]);
            }
            return eredmény;
        }
        static public List<int> unio_LINQ()
        {
            egyik.AddRange(másik);
            return egyik.Distinct().ToList();
        }

        static void kiírás(List<int> lista)
        {
            foreach (int elem in lista)
            {
                Console.Write(elem + ",");
            }
            Console.WriteLine();
        }
        static void Main(string[] args)
        {
            generál(10);
            kiírás(egyik);
            kiírás(másik);

            Console.WriteLine("Hagyományos, Az elemek összege: {0}",összegzés_hagyományosan());
            Console.WriteLine("LINQ-s, Az elemek összege: {0}", összegzés_LINQ());

            if (eldöntés_hagyományosan(x => x > 5)) { Console.WriteLine("Hagyományosan, Eldöntés:  Van"); }
            else { Console.WriteLine("Hagyományosan, Eldöntés: Nincs"); }
            if (eldöntés_LINQ(x => x > 5)) { Console.WriteLine("LINQ-val, Eldöntés:  Van"); }
            else { Console.WriteLine("LINQ-val, Eldöntés: Nincs"); }

            Console.WriteLine("Hagyományos, megszámolás 5-nél nagyobb: {0}", megszámolás_hagyományosan((x => x > 5)));
            Console.WriteLine("LINQ-s, megszámolás 5-nél nagyobb: {0}", megszámolás_LINQ((x => x > 5)));

            Console.WriteLine("Hagyományos, kiválasztás első 5-nél nagyobb: {0}", kiválasztás_hagyományosan((x => x > 5)));
            Console.WriteLine("LINQ-s, kiválasztás első 5-nél nagyobb: {0}", kiválasztás_LINQ((x => x > 5)));

            Console.WriteLine("Hagyományos, maximumkiválasztás: {0}", maximumkiválasztás_hagyományosan((x => x > 5)));
            Console.WriteLine("LINQ-s, maximumkiválasztás: {0}", maximumkiválasztás_LINQ((x => x > 5)));

            (bool van, int elem) = keresés_hagyományosan((x => x > 5));
            Console.Write("Hagyományosan, keresés van-e 5-nél nagyobb és melyik: ");
            if (van) { Console.WriteLine(" Van és {0}", elem); }
            else { Console.WriteLine("Nincs"); }
            (van, elem) = keresés_LINQ((x => x > 5));
            Console.Write("LINQ-val, keresés van-e 5-nél nagyobb és melyik: ");
            if (van) { Console.WriteLine(" Van és {0}", elem); }
            else { Console.WriteLine("Nincs"); }

            List<int> eredmény = kiválogatás_hagyományosan(x => x > 5);
            Console.WriteLine("Hagyományos, kiválogatás 5-nél nagyobbak: ");
            kiírás(eredmény);
            eredmény = kiválogatás_LINQ(x => x > 5);
            Console.WriteLine("LINQ-val, kiválogatás 5-nél nagyobbak: ");
            kiírás(eredmény);

            rendez_hagyományosan();
            Console.Write("Hagyományosan, rendezve: ");
            kiírás(egyik);

            rendez_LINQ(); //kommenteljük ki az egyik rendezést, mert a 2. már rendezett sorozatot kap
            Console.Write("LINQ-val rendezve: ");
            kiírás(egyik);

            Console.WriteLine("Unióhoz az adatok:");
            kiírás(egyik);
            kiírás(másik);
            Console.WriteLine("Hagyományosan:");
            List<int> unio1 = unio_hagyományosan();
            kiírás(unio1);
            Console.WriteLine("LINQ:");
            List<int> unio2 = unio_LINQ();
            kiírás(unio2);

        }
    }
}
