public async Task Spreadsheet_AddRow_CellWithVeryLongFormulaAndCachedValue(int length)
    {
        // Arrange
        var formulaText = FormulaGenerator.Generate(length);
        var cachedValue = new string('c', length);

        using var stream = new MemoryStream();
        var options = new SpreadCheetahOptions {
            BufferSize = SpreadCheetahOptions.MinimumBufferSize
        };

        await using (var spreadsheet = await Spreadsheet.CreateNewAsync(stream, options))
        {
            await spreadsheet.StartWorksheetAsync("Sheet");

            var formula = new Formula(formulaText);
            var cell    = new Cell(formula, cachedValue);

            // Act
            await spreadsheet.AddRowAsync(cell);

            await spreadsheet.FinishAsync();
        }

        // Assert
        SpreadsheetAssert.Valid(stream);
        using var workbook = new XLWorkbook(stream);
        var worksheet  = workbook.Worksheets.Single();
        var actualCell = worksheet.Cell(1, 1);

        Assert.Equal(formulaText, actualCell.FormulaA1);
        Assert.Equal(cachedValue, actualCell.Value);
    }
        public static void Main(string[] args)
        {
            Console.WriteLine("Importar moléculas de arquivos JSON?");
            Console.Write("(S)Sim (N)Não: ");
            var key = Console.ReadKey();

            if (key.KeyChar.ToString().ToUpper() == "S")
            {
                try
                {
                    GetServices();
                    var fg         = new FormulaGenerator();
                    var JsonLoader = new JsonDataSet();
                    new Thread(() =>
                    {
                        JsonLoader.ConsumeJsonFiles();
                    }).Start();

                    var counter = 1;
                    while (JsonLoader.FormulasQueue.Count > 0 || !JsonLoader.Finished)
                    {
                        if (JsonLoader.FormulasQueue.Count > 0)
                        {
                            var molecule = JsonLoader.GetMolecule();
                            var formula  = fg.GetFormulaFromMolecule(molecule);
                            if (moleculeService.GetByNomenclature(formula).Count == 0 && molecule.Sum(x => x.Value) >= 2 && molecule.Sum(x => x.Value) <= 50)
                            {
                                Console.WriteLine(string.Format("{0} - Salvando molécula {1}", counter++, formula));
                                moleculeService.Create(new Molecule()
                                {
                                    AtomsCount         = molecule.Sum(x => x.Value),
                                    DiferentAtomsCount = molecule.Count,
                                    SimpleAtoms        = string.Empty,
                                    SimpleLinks        = string.Empty,
                                    Nomenclature       = formula,
                                    IdStructure        = string.Empty,
                                    Energy             = 0,
                                    FromDataSet        = true
                                });
                            }
                        }
                        else
                        {
                            Thread.Sleep(1000);
                        }
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
        }
        public static void Main(string[] args)
        {
            GetServices();
            int counter = 0;

            Console.Write("Quantidade MÍNIMA de átomos na molécula: ");
            var min = Convert.ToInt32(Console.ReadLine());

            Console.Write("Quantidade MÁXIMA de átomos na molécula: ");
            var max = Convert.ToInt32(Console.ReadLine());

            Console.Write("\n");
            Console.WriteLine("Procurar por estruturas: ");
            Console.WriteLine("1 - Moléculas existentes");
            Console.WriteLine("2 - Moléculas aleatórias");
            Console.Write("Opção: ");
            var tipo = Convert.ToInt32(Console.ReadLine());

            Console.WriteLine("\n");

            if (min >= 2 && min <= 50 && max >= 2 && max <= 50 && min <= max && (tipo == 1 || tipo == 2))
            {
                while (true)
                {
                    string           formula            = string.Empty;
                    int              atomsCount         = 0;
                    int              diferentAtomsCount = 0;
                    int              searchCounter      = 0;
                    bool             fromDataSet        = false;
                    var              resultCounter      = 0;
                    var              idStructure        = string.Empty;
                    Molecule         saved = null;
                    FormulaGenerator fg    = new FormulaGenerator();
                    try
                    {
                        if (tipo == 1)
                        {
                            var moleculeAtoms = _moleculeService.GetRandomToSearch(min, max);
                            formula            = moleculeAtoms.Nomenclature;
                            atomsCount         = moleculeAtoms.AtomsCount;
                            diferentAtomsCount = moleculeAtoms.DiferentAtomsCount;
                            fromDataSet        = moleculeAtoms.FromDataSet;
                            searchCounter      = _logService.GetCounter(formula);
                        }
                        else if (tipo == 2)
                        {
                            var moleculeAtoms = fg.GenerateFormula(min, max);
                            formula            = fg.GetFormulaFromMolecule(moleculeAtoms);
                            atomsCount         = moleculeAtoms.Sum(x => x.Value);
                            diferentAtomsCount = moleculeAtoms.Count;
                            fromDataSet        = false;
                            searchCounter      = _logService.GetCounter(formula);
                        }

                        if (!string.IsNullOrEmpty(formula))
                        {
                            Console.WriteLine(string.Format("Iniciando busca para {0}", formula));

                            var ga = new StructureGenerator(
                                formula,
                                GetPopulationSize(atomsCount, diferentAtomsCount, searchCounter),
                                GetMaxGenerations(atomsCount, diferentAtomsCount, searchCounter),
                                GetMutationRate(atomsCount, diferentAtomsCount, searchCounter)
                                );
                            ga.FindSolutions();
                            if (ga.Finished)
                            {
                                var foundIds = new List <string>();
                                while (ga.ResultList.Count > 0)
                                {
                                    var molecule = ga.ResultList.Dequeue();
                                    if (molecule != null)
                                    {
                                        molecule.ReorganizeLinks();
                                        molecule.SetEnergy();
                                        molecule.FromDataSet = fromDataSet;
                                        molecule.IdStructure = _linkService.GetIdStructure(molecule.LinkEdges);
                                        idStructure          = molecule.IdStructure;

                                        if (!string.IsNullOrEmpty(idStructure) && !foundIds.Contains(idStructure) && _moleculeService.GetByIdStructure(molecule.Nomenclature, molecule.IdStructure) == null)
                                        {
                                            foundIds.Add(idStructure);
                                            saved = _moleculeService.Create(molecule);

                                            if (saved != null)
                                            {
                                                counter++;
                                                var empty = _moleculeService.GetByIdStructure(saved.Nomenclature, string.Empty);
                                                if (empty != null)
                                                {
                                                    _moleculeService.Delete(empty);
                                                }

                                                resultCounter++;
                                                Console.WriteLine(string.Format("Encontrado {0}", saved.IdStructure));
                                            }
                                        }
                                    }
                                }
                                Console.WriteLine(string.Format("Finalizado busca para {0}", formula));
                            }
                            _logService.NewSearch(formula);
                            Console.Write("\n");
                            Console.Write(string.Format("Você já encontrou {0} moléculas!", counter));
                            Console.Write("\n\n");
                        }
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("\n" + ex.Message + "\n");
                    }
                }
            }
        }
        private void timerSearch_Tick(object sender, EventArgs e)
        {
            if (ThreadSearch.Count < (Environment.ProcessorCount / 2))
            //if (ThreadSearch.Count < (1))
            {
                ThreadSearch.Add(new Thread(() =>
                {
                    string formula         = string.Empty;
                    int atomsCount         = 0;
                    int diferentAtomsCount = 0;
                    int searchCounter      = 0;
                    bool fromDataSet       = false;
                    FormulaGenerator fg    = new FormulaGenerator();
                    try
                    {
                        if (FromEmpty)
                        {
                            var molecule       = _moleculeService.GetRandomToSearch(2, 50);
                            formula            = molecule.Nomenclature;
                            atomsCount         = molecule.AtomsCount;
                            diferentAtomsCount = molecule.DiferentAtomsCount;
                            fromDataSet        = molecule.FromDataSet;
                            searchCounter      = _logService.GetCounter(formula);
                        }
                        else if (FromRandom)
                        {
                            var moleculeAtoms  = fg.GenerateFormula();
                            formula            = fg.GetFormulaFromMolecule(moleculeAtoms);
                            atomsCount         = moleculeAtoms.Sum(x => x.Value);
                            diferentAtomsCount = moleculeAtoms.Count;
                            searchCounter      = _logService.GetCounter(formula);
                        }

                        if (!string.IsNullOrEmpty(formula))
                        {
                            if (fromDataSet)
                            {
                                _logService.NewSearch(formula);
                            }
                            lock (listObjectLock)
                            {
                                SearchList.Add(formula);
                                ShowSearchDataSource();
                            }
                            var ga = new StructureGenerator(
                                formula,
                                GetPopulationSize(atomsCount, diferentAtomsCount, searchCounter),
                                GetMaxGenerations(atomsCount, diferentAtomsCount, searchCounter),
                                GetMutationRate(atomsCount, diferentAtomsCount, searchCounter)
                                );
                            new Task(() => ga.FindSolutions()).Start();
                            string idStructure = string.Empty;
                            int resultCounter  = 0;
                            while (!ga.Finished)
                            {
                                if (ga.ResultList.Count > 0)
                                {
                                    var molecule = ga.ResultList.Dequeue();
                                    if (molecule != null)
                                    {
                                        resultCounter++;
                                        molecule.ReorganizeLinks();
                                        molecule.SetEnergy();
                                        molecule.FromDataSet = fromDataSet;
                                        idStructure          = _linkService.GetIdStructure(molecule.LinkEdges);
                                        molecule.IdStructure = idStructure;
                                        if (!Ids.Contains(molecule.IdStructure))
                                        {
                                            Ids.Add(molecule.IdStructure);
                                            lock (queueObjectLock)
                                            {
                                                ResultQueue.Enqueue(molecule);
                                                ShowQueueDataSource();
                                            }
                                        }
                                    }
                                }
                            }
                            if (!fromDataSet && resultCounter > 0)
                            {
                                _logService.NewSearch(formula);
                            }
                            Ids.RemoveAll(x => x == idStructure);

                            lock (listObjectLock)
                            {
                                SearchList.RemoveAll(x => x == formula);
                                ShowSearchDataSource();
                            }
                        }
                    }
                    catch (Exception) { }
                    finally
                    {
                        if (SearchList.Contains(formula))
                        {
                            SearchList.RemoveAll(x => x == formula);
                        }
                        ShowSearchDataSource();
                    }
                }));
            }

            ThreadSearch.Where(x => x.ThreadState == ThreadState.Unstarted).ToList().ForEach(x => x.Start());
            var deleteThreads = ThreadSearch.Where(x => !x.IsAlive).ToList();

            foreach (var thread in deleteThreads)
            {
                ThreadSearch.Remove(thread);
            }

            txtProcess.Text          = ThreadSearch.Count.ToString();
            txtQuantityDatabase.Text = DatabaseCount.ToString();
            txtFound.Text            = SearchCount.ToString();
        }
 public FormulasController()
 {
     formulaAnalizer  = new FormulaAnalizer();
     formulaGenerator = new FormulaGenerator();
 }