Losowanie niepowtarzających się liczb

0

Witam! Wczoraj zabrałem się za rozbudowanie mojej gierki toto-lotka, aby był prawdziwym symulatorem Multi-Multi. System losuje 20 liczb z przedziału 1-80, potem pyta nas o ilość kuponów chybił- trafił, potem wypisuje n kuponów po 6 liczb i porównuje ile się trafiło. Problem polega na tym, że nie do końca umiem zrobić, żeby liczby w danym kuponie się nie powtarzały. Z liczbami wylosowanymi jakoś mi poszło, bo poczytałem sobie o kolekcjach i zamieniłem tablicę jednowymiarową na listę. Sprawa była wtedy prosta. Z kuponami jest ciężej, bo możemy sobie wybrać ilość kuponów, co daje nam tablicę dwuwymiarową [n kuponów,6]. Jak jakłatwiej zrobić, żeby w jednym kuponie nie powtarzały się liczby?

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

namespace Loteria
{
    class Program
    {
        public static int k;
        public static string q;
        public static List<int> losowane2 = new List<int>();
        public static int[] losowane = new int[20];
        public static int[,] kupony;
        public static int[] trafione;
        public static int[] jedynkidwojki=new int[6];
        public static int mnoznik;
        public static Random r=new Random();
        public static void LosowanieLiczb()//   LOSOWANIE LICZB KONKURSOWYCH
        {
            for(int i=0;i<20;i++)
            {
                losowane[i]=r.Next(1,80);
            }
        }
        public static void LosowanieLiczb2()// NOWY SPOSÓB LOSOWANIA
        {
            while (losowane2.Count != 20)
            {
                int i = r.Next(1, 80);
                if (losowane2.Contains(i)) continue;
                else losowane2.Add(i);
            }
        }
        public static void WypisywanieLiczb()// WYPISYWANIE LICZB KONKURSOWYCH
        {
            Console.WriteLine("Wylosowane liczby to: ");
            for (int i = 0; i < 20; i++)
            {
                Console.Write(losowane[i]+" ");
            }
            Console.WriteLine("\n");
        }

        public static void PobieranieIlosciKuponow()// POBIERANIE ILOŚCI KUPONÓW
        {
            Console.WriteLine("Podaj ilość kuponów chybił-trafił");
            k = int.Parse(Console.ReadLine());
        }
        public static void LosowanieKuponow()//LOSOWANIE LICZB Z KUPONÓW1

        {
            kupony = new int[k, 6];
            for (int i = 0; i < k; i++)
            {
                Console.Write("Kupon nr. " + (i + 1) + " to:");
                for (int n = 0; n < 6; n++)
                {
                    kupony[i, n] = r.Next(1,49);
                    Console.Write(kupony[i, n]+" ");
                }
                Console.WriteLine();
            }
            Console.WriteLine();
        }
        public static void SprawdzenieKuponow()//SPRAWDZENIE TRAFIEŃ W KUPONACH
        {
            trafione = new int[k];
            for (int i = 0; i < k; i++)
            {
                for (int n = 0; n < 6; n++)
                {
                    for (int z = 0; z < 20; z++)
                    {
                        if (kupony[i, n] == losowane[z]) trafione[i] = trafione[i] + 1;
                    }
                }
            }
        }
        public static void WypisanieTrafien()//WYPISANIE ILOŚCI TRAFIONYCH LICZB
        {
            Console.WriteLine("Twoja ilość wytypowanych: ");
            for (int i = 0; i < k; i++)
            {
                Console.WriteLine("kupon nr. "+(i+1)+" : "+trafione[i]);
            }
            Console.WriteLine();
        }
        public static void JedynkiDwojkiTrojki()//SPRAWDZENIE ILOŚCI POSZCZEGÓLNYCH TRAFIEŃ(ILE JEDYNEK, DWÓJEK ITP.)
        {
            for (int i = 0; i < 6; i++)
            {
                for (int n = 0; n < k; n++)
                {
                    if (trafione[n] == (i + 1)) jedynkidwojki[i] = jedynkidwojki[i] + 1;
                }
                Console.WriteLine("Ilość trafionych " + (i + 1) + " to : " + jedynkidwojki[i]);
            }
        }
        public static void SprawdzenieWygranej()//SPRAWDZENIE KWOTY WYGRANEJ
        {
            int wygrana = (mnoznik * 2 * jedynkidwojki[2]) + (mnoznik * 8 * jedynkidwojki[3]) + (mnoznik * 120 * jedynkidwojki[4]) + (mnoznik * 1300 * jedynkidwojki[5]);
            double cena=mnoznik*2.5*k;
            double zarobek = wygrana - cena;
            Console.WriteLine("\nCena kuponów to: "+cena+" zł.");
            Console.WriteLine("Twoja wygrana to: " + wygrana + " zł!");
            Console.WriteLine("Twój zarobek: " + zarobek + " zł!");
        }
        public static void Kontynuacja()//SPRAWDZENIE, CZY CHCE SIĘ KONTYNUOWAĆ
        {
            do
            {
                Console.WriteLine("Czy chcesz kontynuować? 't' - tak, 'n' - nie.");
                q = Console.ReadLine();
                switch (q)
                {
                    case "t":
                        break;

                    case "n":
                        break;

                    default:
                        Console.WriteLine("Użyto innego znaku!");
                        Thread.Sleep(1000);
                        break;
                }
                Console.Clear();
            } while (q != "t" && q != "n");
        }
        public static void Main()
        {
            do
            {
                Console.WriteLine("Podaj mnożnik kwoty: ");
                mnoznik = int.Parse(Console.ReadLine());
                PobieranieIlosciKuponow();
                LosowanieLiczb2();
                WypisywanieLiczb();
                LosowanieKuponow();
                SprawdzenieKuponow();
                WypisanieTrafien();
                JedynkiDwojkiTrojki();
                SprawdzenieWygranej();
                Kontynuacja();
                Console.Clear();
            } while (q != "n");

        }
    }
}
0
bnbnowacki napisał(a):

Jak jakłatwiej zrobić, żeby w jednym kuponie nie powtarzały się liczby?

Dla Dużego Lotka:

powtarzaj 6 razy:
{
      powtarzaj 
      {
            wylosuj liczbę;
      }  dopóki wylosowana nie jest w tablicy wylosowanych;
      dodaj liczbę do kuponu;
      dodaj liczbę do tablicy wylosowanych;
}

:)

0

@fourfour Kurde, skopiowałem ten kawałek kodu, co napisałeś, i mi wywala pełno błędów :/ Coś tam, że "The name wylosuj liczbę does not exist in current content."

Hueh, hueh. Dzięki! bardzo fajny i przejrzysty algorytm, tylko nie wiem jak sprawdzić, czy liczba nie jest w tablicy wylosowanych. To jest właśnie mój główny problem.

0
bnbnowacki napisał(a):

tylko nie wiem jak sprawdzić, czy liczba nie jest w tablicy wylosowanych. To jest właśnie mój główny problem.

Hehe, to znowu przelatuj foreach i sprawdzaj, czy nie ma w kuponie tego, co wylosowałeś :)

Można to zrobić inaczej: np. lista 49 elementów od 1 do 49. Losujesz element, wrzucasz do kuponu, usuwasz z listy, i znowu losujesz, tym razem już z 48 pozostałych elementów listy.

Wymyśl jak to chcesz zrobić, a zakodowanie będzie łatwiejsze... :D

0
        private static int[] allnumbers=null;
        public static void shufle(int max)
        {
            if(allnumbers==null)
            {
                allnumbers=new int[49];
                for(int i=0;i<49;++i) allnumbers[i]=i+1;
            }
            for(int i=0;i<max;++i)
            {
                int p=i+r.Next(0,49-i);
                int swap=allnumbers[i];
                allnumbers[i]=allnumbers[p];
                allnumbers[p]=swap;
            }
        }
        public static void LosowanieLiczb()//   LOSOWANIE LICZB KONKURSOWYCH
        {
            shufle(20);
            for(int i=0;i<20;++i) losowane[i]=allnumbers[i];
        }
0
using System;
using System.Linq;
using System.Collections.Generic;

static class EnumerableExtensions
{
	private static Random _rng = new Random();
	
    public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action)
    {
        foreach(var elem in enumerable)
        {
            action(elem);
        }
    }
 
    public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> enumerable)
    {
        return enumerable.OrderBy(_ => _rng.Next());
    }
}

public class Test
{
	public static void Main()
	{
		Enumerable.Range(1, 49).Shuffle().ForEach(Console.WriteLine);
	}
}
0

C# i Java to podobno języki wysokopoziomowe.

numbers = sample(range(1,80),12)
0

Ok, wyszło troszkę zawile, no ale może się rozczytacie. Mimo moich starań, w wynikach nieraz zdarzają się dwie takie same liczby pod rząd w tym samym kuponie. Co zrobiłem źle?

        public static void LosowanieKuponow2()//NOWE LOSOWANIE LICZB Z KUPONÓW
        {
            kupony=new int[k,6];
            for(int i=0;i<k;i++)
            {

                Console.Write("Kupon nr. " + (i + 1) + " to:");
                for(int n=0;n<6;n++)
                {
                int schowek=r.Next(1,80);
                    bool sprawdzacz=false;
                    do
                    {
                        for (int a = 0; a < 6; a++)
                        {
                            if (schowek == kupony[i, a]) sprawdzacz = true;
                            else { };
                        }
                    } while (sprawdzacz = false);
                    kupony[i,n]=schowek;
                    Console.Write(kupony[i, n] + " ");
                }
                Console.WriteLine("");
            }
            Console.WriteLine();
        } 
1
  1. Znowu mieszasz funkcjonalność z interfacem.
  2. Może nie wiesz, else nie musi być przy każdym if'ie
  3. Zmienna składowa klasy o jednoliterowej nazwie k - sam prosisz się o błędy.
  4. Sprawdzasz w pętle po a to czego jeszcze tam nie wpisałeś.
  5. while (sprawdzacz = false); wpisujesz false w zmienną sprawdzacz
0

Wywaliłem else'a. Jeśli chodzi o k - kojarzę to z liczbą k-kuponów, nie pogubiłem się w tym segmencie. Nie wiem dalej o czym mówisz.. Wiem, że jest skopanie, bo czytając kod, teraz to powinno działać tak, że jeżeli liczba się powtórzy, to program cały czas wykonuje pętlę do while, bo nie zmienia już wtedy boola na false. W takim razie dziwne w ogóle, że kupony się wypisują do końca. Przed do while'em postawiłem samą deklarację sprawdzacza, oraz schowka, żeby w pętli po niespełnionym warunku mógł znowu przypisać false i wylosować nową liczbę.
Lepiej? :) Wydaje się działać dobrze....

         public static void LosowanieKuponow2()//NOWE LOSOWANIE LICZB Z KUPONÓW
        {
            kupony=new int[k,6];
            for(int i=0;i<k;i++)
            {

                Console.Write("Kupon nr. " + (i + 1) + " to:");
                for(int n=0;n<6;n++)
                {
                    int schowek;
                    bool sprawdzacz;
                    do
                    {
                        schowek = r.Next(1, 80);
                        sprawdzacz = false;
                        for (int a = 0; a < 6; a++)
                        {
                            if (schowek == kupony[i, a]) sprawdzacz = true;
                        }
                    } while (sprawdzacz = false);
                    kupony[i,n]=schowek;
                    Console.Write(kupony[i, n] + " ");
                }
                Console.WriteLine("");
            }
            Console.WriteLine();
        }

EDIT: Jednak nie działa. Znalazłem kupon z powtórzoną liczbą. Pomocy! :((

0

Proste losowanie bez powtórzeń: Zapełniasz listę liczbami do wylosowania, po wylosowaniu usuwasz tą liczbę z listy.

            List<int> Pula = new List<int>();
            List<int> Wylosowane = new List<int>();
            for (int i = 1; i < 81; i++)
                Pula.Add(i);
            for (int i = 0; i < 6; i++)
            {
                int index = rand.Next(0, Pula.Count);
                Wylosowane.Add(Pula[index]);
                Pula.RemoveAt(index);
            }
            foreach (int i in Wylosowane)
            {
                Console.Write(i + ", ");
            }
0

A ja się tak pobawiłem chwilę (bałagan w zmiennych trochę, wybaczcie :D):

        static void Main(string[] args)
        {
            int i = 1;
            foreach (List<int> kupon in wydajKupony(6))
            {
                Console.Write("\nKupon {0} to: ", i);
                foreach (int a in kupon) Console.Write("{0:00} ", a);
                i++;
            }
            Console.ReadKey();
        }

        static List<int> [] wydajKupony(int ile)
        {
            int i, j;
            Random r = new Random();
            List<int> pulaLiczbWLosowaniu = new List<int>();
            List<int> pulaLiczb = new List<int>();
            List<int>[] kupony = new List<int>[ile];
            for (i = 1; i < 81; i++) pulaLiczb.Add(i);
            for (int x = 0; x < 6; x++)
            {
                pulaLiczbWLosowaniu = new List<int>(pulaLiczb); 
                kupony[x] = new List<int>();
                for (i = 0; i < 6; i++)
                {
                    j = r.Next(0, 79 - i);
                    kupony[x].Add(pulaLiczbWLosowaniu[j]);
                    pulaLiczbWLosowaniu.Remove(pulaLiczbWLosowaniu[j]);
                }
                kupony[x].Sort();
            }
            return kupony;
        } 
0

C# znam tak sobie, ale myślę, że to będzie najłatwiejsze rozwiązanie:

 
List<int> kupon = new List<int>();
int numerek;
						
Random rnd = new Random();	
do {			
	numerek = rnd.Next(1,80);
	if (kupon.IndexOf(numerek) == -1) 
		kupon.Add(numerek);								
} while(kupon.Count != 6);	

W łatwy sposób można to przerobić tak, aby sprawdzało liczby nie tylko w jednym, ale również w wielu kuponach. I może to wydajnością by nie grzeszyło, ale autor pewnie nie będzie generował tysięcy kuponów ;)

0

@puk , a żebyś się nie zdziwił :D Sprawdzaliśmy z tatą, czy jak wyślemy 50,000 kuponów, to czy będziemy na - i ile :DD
Mam do was prośbę. Moglibyści zadać mi jakiś projekcik do zrobienia w ramach ćwiczeń? Nie mam już pomysłów.. Coś minimalnie trudniejszego z wykorzystaniem czegoś, czego jeszcze nie umiem.. (umiem: to co w tym projekcie, raczej żadnych innych składni/metod nie znam z konsolowego c#)

0

Zwykły kalkulator windows'owy.

2

Odnośnie braku pomysłów na projekty: https://github.com/ashier/martyrs-mega-project

Można się czegoś nauczyć.

0

@bnbnowacki - jeśli chcesz poćwiczyć implementacje różnych algorytmów i przy okazji nauczyć się tworzyć wydajne kodu, to zaglądanij na takie serwisy jak SPOJ czy Project Euler; Jest tam bardzo dużo zadań - od bardzo prostych, bo bardzo trudne, które mało kto kiedykolwiek rozwiązał z poprawnym wynikiem i okreslonym czasem wykonania;

Sam kiedyś się bawiłem w Project Euler, ale z braku czasu porzuciłem ćwiczenia.

0

@puk nie daj sobie wmówić, że Twoje rozwiązanie jest najgorsze. :) Twoje rozwiązanie jest kilka raz wydajniejsze od tego zaproponowanego przez @n0name_l

Nie jest idealne, a to z tego względu, że:

  1. Nie jest opakowane w metodę.
  2. Masz magiczne wartości (6, 1, 80) stwórz funkcję która przyjmuje ile kul wylosować i z jakiego przedziału mogą one być. Dzięki temu możesz wywołać LosowanieMultilotka(20, 1, 80), LosowanieDuzegoLotka(6, 1, 49). .
  3. Twoja funkcja może się nigdy nie skończyć, jeżeli miałbyś pecha i ciągle losował te same wartości, no ale to jest bardziej teoretyczny problem. :)
2
dlaczegotak napisał(a):

Twoja funkcja może się nigdy nie skończyć, jeżeli miałbyś pecha i ciągle losował te same wartości, no ale to jest bardziej teoretyczny problem. :)

Nie, napisanie nieskończonej pętli, gdy nie jest potrzebna, to jest akurat problem praktyczny, za który grozi miesiąc z karną lamą.

0

Benchmarka poprosze

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Duzy lotek");
        TestPerformance(Noname, 6, 49);
        TestPerformance(Puk, 6, 49);

        Console.WriteLine("Multilotek:");
        TestPerformance(Noname, 20, 80);
        TestPerformance(Puk, 20, 80);

        Console.ReadLine();
    }

    static void TestPerformance(Func<int, int, int, IEnumerable<int>> method, int howMany, int rangeCount)
    {
        const int length = 1000 * 250;

        Stopwatch timer = Stopwatch.StartNew();
        for (int i = 0; i < length; i++)
        {
            foreach (var item in method(howMany, 1, rangeCount))
                ;
        }
        timer.Stop();

        Console.WriteLine("{0,-8} = {1,5:0.00} sekund dla losowania {2} kuli sposrod {3}", method.Method.Name, timer.Elapsed.TotalSeconds, howMany, rangeCount);
    }

    private static Random _random = new Random();
    public static IEnumerable<int> Noname(int howMany, int rangeStart, int rangeCount)
    {
        return Enumerable.Range(rangeStart, rangeCount)
                         .OrderBy(_ => _random.Next())
                         .Take(howMany);
    }

    public static IEnumerable<int> Puk(int howMany, int rangeStart, int rangeCount)
    {
        List<int> kupon = new List<int>();
        int numerek;

        do
        {
            numerek = rangeStart + _random.Next(rangeCount);
            if (kupon.IndexOf(numerek) == -1)
                kupon.Add(numerek);
        } while (kupon.Count != howMany);

        return kupon;
    }
}

user image

Nie, napisanie nieskończonej pętli, gdy nie jest potrzebna, to jest akurat problem praktyczny, za który grozi miesiąc z karną lamą.

Głównym problemem jest to, że ta metoda będzie wolna dla wielu zestawów danych. Do liczenia mutlilotka/dużego lotka jest jak najbardziej w porządku. :)

0

Znajomy opowiadał jak studenci (informatyki!) podeszli do takiego zadania. Utwórz n-elementową, pseudolosową tablicę dwuwartościową (0 lub 1), w której jest dokładnie k (k<n) jedynek. Otóż większość stosowała algorytm @puk'a, losując pozycje jedynek, również dla danych typu n = 1 000 000, k = n-1. Czas wykonania był niewiele krótszy od nieskończoności.

0

@dlaczegotak

To teraz zmierz szybkosc algorytmu, a nie wywolywania lambd w c#.

0

To teraz zmierz szybkosc algorytmu, a nie wywolywania lambd w c#.

Mnie benchmarka (o którego sam prosiłeś) wystarcza.

1
@localhost ~/Desktop $ cat test.cs                                                                                                                                                                                                                              [16:24:42]
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
 
class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Duzy lotek");
        TestPerformance(Noname, 6, 49);
        TestPerformance(Puk, 6, 49);
 
        Console.WriteLine("Multilotek:");
        TestPerformance(Noname, 50000, 1204000);
        TestPerformance(Puk, 50000, 1204000);
 
        Console.ReadLine();
    }
 
    static void TestPerformance(Func<int, int, int, IEnumerable<int>> method, int howMany, int rangeCount)
    {
        Stopwatch timer = Stopwatch.StartNew();
        foreach (var item in method(howMany, 1, rangeCount));
        timer.Stop();
 
        Console.WriteLine("{0,-8} = {1,5:0.00} sekund dla losowania {2} kuli sposrod {3}", method.Method.Name, timer.Elapsed.TotalSeconds, howMany, rangeCount);
    }
 
    private static Random _random = new Random();
    public static IEnumerable<int> Noname(int howMany, int rangeStart, int rangeCount)
    {
        return Enumerable.Range(rangeStart, rangeCount)
                         .OrderBy(_ => _random.Next())
                         .Take(howMany);
    }
 
    public static IEnumerable<int> Puk(int howMany, int rangeStart, int rangeCount)
    {
        List<int> kupon = new List<int>();
        int numerek;
 
        do
        {
            numerek = rangeStart + _random.Next(rangeCount);
            if (kupon.IndexOf(numerek) == -1)
                kupon.Add(numerek);
        } while (kupon.Count != howMany);
 
        return kupon;
    }
}
@localhost ~/Desktop $ gmcs test.cs                                                                                                                                                                                                                             [16:24:44]
@localhost ~/Desktop $ mono test.exe                                                                                                                                                                                                                            [16:24:48]
Duzy lotek
Noname   =  0.01 sekund dla losowania 6 kuli sposrod 49
Puk      =  0.00 sekund dla losowania 6 kuli sposrod 49
Multilotek:
Noname   =  0.58 sekund dla losowania 50000 kuli sposrod 1204000
Puk      =  5.17 sekund dla losowania 50000 kuli sposrod 1204000

@localhost ~/Desktop $                                                                                                                                                                                                                                          [16:24:59]

Wiem. Przeciez lubisz manipulowac danymi.

0

Nie manipuluje danymi. Napisałem, że jego rozwiązanie jest szybsze, bo jest szybsze w przypadku w którym używa go OP. :) Oczywiste jest, że dla pewnych danych jego rozwiązanie będzie gorsze. Im więcej kuli losujemy, tym trudniej wybrać te ostatnie. Jednak nie jest to sortowanie przez losowanie które praktycznie nigdy się nie skończy.

Te logi które wkleiłeś trochę mnie zaskoczyły, bo u mnie dla podobnych wymagań (powtórzonych 10 razy) otrzymałem 12.5s dla Twojej funkcji, a 25s dla funkcji Puka, kompilujesz w trybie release? Tak swoją drogą jakby zrobić małą modyfikację, to otrzymuję 0.1s wobec Twoich 12s.

    public static IEnumerable<int> Puk2(int howMany, int rangeStart, int rangeCount)
    {
         HashSet<int> set = new HashSet<int>();

        while (set.Count != howMany)
            set.Add(_random.Next(rangeCount) + rangeStart);

        return set;
    }

Nawet dla danych typu

TestPerformance(Noname, 1204000-4000, 1204000);
        TestPerformance(Puk2, 1204000-4000, 1204000);

Rozwiązanie z HashSet jest tylko wolniejsze o 30-40%. :)

Tak przy okazji, nie testowałem tej funkcji dla większych liczby kul, bo przecież i Twoje nie znalazłoby się w kodzie produkcyjnym. To rozwiązanie które zaprezentowałeś jest popularne, bo jest krótkie i sprytne. :)

0

Wiem, w kodzie "produkcyjnym" bys umiescil wstawke asma. Juz to ustalilismy w poprzednim watku.

0

Hej dwaj manipulatorzy @n0name_l i @dlaczegotak może wstawilibyście w swoje benchmarki tak dla porównania jakiś sensowny kod, np ten:
http://4programmers.net/Forum/Newbie/163647-losowanie_niepowtarzajacych_sie_liczb?p=1040869#id1040869

0

Nie, zapewne wziąłbym coś w stylu Dragona, czyli tasujemy elemenety a potem wybieramy n-elementów. Na pewno ich bym nie sortował jak to robisz Ty. :) Tak swoją drogą kod który wkleiłem jest dość elegancki, spokojnie możesz przeczytać go jako "dopóki w zbiorze nie mamy n-elementów, dodaj losowy element". Proste, naturalne podejście. Jeżeli chciałby dodać "optymalizację", to wtedy...

    public static IEnumerable<int> NaivePuk(int howMany, int rangeStart, int rangeCount)
    {
        HashSet<int> set = new HashSet<int>();

        while (set.Count != howMany)
            set.Add(_random.Next(rangeCount) + rangeStart);

        return set;
    }

    public static IEnumerable<int> SmartPuk(int howMany, int rangeStart, int rangeCount)
    {
        if (howMany < rangeCount / 2)
            return NaivePuk(howMany, rangeStart, rangeCount);

        var randomed = NaivePuk(rangeCount - howMany, rangeStart, rangeCount);

        return Enumerable.Range(rangeStart, rangeCount)
                         .Except(randomed);
    }

Oczywiście należałoby przetestować dla ilu % rangeCount lepiej jest robić odejmowanie zbiorów.
user image
Przy okazji dalej mnie zaskakuje jak dobre jest naiwne losowanie do bólu. :)

@_13th_Dragon, bo oczywiste (dla mnie) jest, że ani moje ani jego rozwiązanie nie jest optymalne, dlatego ze dwa posty temu napisałem, że żadnego z nich nie użyłbym do kodu produkcyjnego. :)

0

A dla mnie oczywiste jest premature optimization is the root of all evil.

0

http://pastebin.com/LAfAK599 - bałagan w kodzie, ale cóż, nie będę kombinował. :)
user image

Zaletą Twojego kodu jest niewątpliwie to, że ma lepszą złożoność pesymistyczną. :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1