public long f(int n) { WordSequence mainSeq = this.WordSeqs[this.MainID]; while (mainSeq.Counts.Count <= n) { this.AllNextCounts(); } return(mainSeq.Counts[n]); }
private void NextCount(WordSequence wordSeq) { int index = wordSeq.Counts.Count - 1; long nextTerm = 0; int parentID; long parentTerm; int terms = wordSeq.Recursion.IDs.Count; for (int i = 0; i < terms; i++) { parentID = wordSeq.Recursion.IDs[i]; parentTerm = this.WordSeqs[parentID].Counts[index]; nextTerm += wordSeq.Recursion.Coefficients[i] * parentTerm; } wordSeq.Counts.Add(nextTerm); //if (index>7)// && wordSeq.KeywordCount>0) // Console.WriteLine($"i={index+1} id={wordSeq.ID} ending={wordSeq.Ending} #keys={wordSeq.KeywordCount} count(i)={nextTerm}"); }
// Generates the list of word-sequences, one for each pair (keyword subset, subkeyword), // starting with (empty set, empty word). // Returns the ID of the main sequence, with all Keywords present and no specific ending. private int GenerateWordSeqs() { this.WordSeqs = new List <WordSequence>(); // First generate the bare counters. int iD; bool[] keywordPresence; int numberOfSubsets = (int)Math.Pow(2, this.Keywords.Length); int mainID = (numberOfSubsets - 1) * this.SubKeywords.Count; WordSequence newWordSeq; for (int i = 0; i < numberOfSubsets; i++) { keywordPresence = this.intToBools(i, this.Keywords.Length); foreach (string subkey in this.SubKeywords) { iD = this.WordSeqs.Count; newWordSeq = new WordSequence(subkey, keywordPresence, iD); this.WordSeqs.Add(newWordSeq); } } // Then generate the recurrence relations. // WARNING: Assumes no keyword is a final subword of another // (i.e., no two keywords can be completed simultaneously with the addition of 1 letter). WordSequence child; WordSequence parent; string primaryParentEnding; int primaryParentCoefficient; int primaryParentKeyInt; bool[] possibleKeys; List <string> possibleKeysSansEnd; int missingKeywordIndex; string missingKeyword; for (iD = 0; iD < this.WordSeqs.Count; iD++) { child = this.WordSeqs[iD]; primaryParentEnding = string.Empty; primaryParentCoefficient = this.Alphabet.Length; primaryParentKeyInt = this.boolsToInt(child.KeywordPresence); possibleKeys = new bool[this.Keywords.Length]; possibleKeysSansEnd = new List <string>(); /*if (iD == 0) * child.Recursion.AddRecurranceTerm(iD, primaryParentCoefficient); * else {*/ if (child.Ending != string.Empty) { primaryParentCoefficient = 1; if (child.Ending.Length > 1) { primaryParentEnding = child.Ending.Substring(0, child.Ending.Length - 1); } } // Identify which /*counted*/ keywords are completed with the current child's Ending. for (int i = 0; i < this.Keywords.Length; i++) { if (/*child.KeywordPresence[i] &&*/ this.HasFinalSubstring(this.Keywords[i], child.Ending)) { possibleKeys[i] = true; possibleKeysSansEnd.Add(this.Keywords[i].Substring(0, this.Keywords[i].Length - 1)); } } for (int j = 0; j < this.WordSeqs.Count; j++) { parent = this.WordSeqs[j]; if (parent.Ending == primaryParentEnding) { // First recurrence case is the primary parent, with: // * the same set of keywords // * ending keyword same as child's without it's final letter removed. if (this.boolsToInt(parent.KeywordPresence) == primaryParentKeyInt) { child.Recursion.AddRecurranceTerm(j, primaryParentCoefficient); } } else if (possibleKeysSansEnd.Contains(parent.Ending)) { // Second recurrence case is subtracted to cancel unwanted new words. if (this.boolsToInt(parent.KeywordPresence) == primaryParentKeyInt) { child.Recursion.AddRecurranceTerm(j, -1); } // Third recurrence case has exactly one keyword missing from the set of keywords, // and that keyword is terminated by the child's ending, // and with ending word that keyword without it's final letter. else { missingKeywordIndex = this.MissingIndex(child.KeywordPresence, parent.KeywordPresence); if (missingKeywordIndex >= 0 && possibleKeys[missingKeywordIndex]) { missingKeyword = this.Keywords[missingKeywordIndex]; if (missingKeyword.Substring(0, missingKeyword.Length - 1) == parent.Ending) { child.Recursion.AddRecurranceTerm(j, 1); } } } } } /*}*/ //Console.WriteLine($"iD={iD} #keywords={child.KeywordCount} ending={child.Ending} #possible={possibleKeysSansEnd.Count} #parents={child.Recursion.IDs.Count} primaryParentPresence={primaryParentKeyInt} primaryParentEnding={primaryParentEnding} primaryParentCoef={primaryParentCoefficient}"); /*if (possibleKeysSansEnd.Count == this.Keywords.Length) { * foreach (int recID in child.Recursion.IDs) Console.WriteLine(recID); * foreach (int recCoef in child.Recursion.Coefficients) Console.WriteLine(recCoef); * }*/ } return(mainID); }