Beispiel #1
0
            //must clone self so for deep cloning
            public object Clone()
            {
                CharMapper clone = new CharMapper(0);

                clone.count      = this.count;
                clone.finalCount = this.finalCount;
                clone.indexes    = this.indexes;
                return(clone);
            }
Beispiel #2
0
        private string MapCharacters(string variation)
        {
            var result = new StringBuilder(variation);

            for (var i = 0; i < result.Length; i++)
            {
                if (CharMapper.TryGetLetter(variation[i], out var convertedChar))
                {
                    result[i] = convertedChar;
                }
            }
            return(result.ToString());
        }
Beispiel #3
0
        static string reverseShuffleMerge(string s, string t)
        {
            //create map of all characters, their counts, and indexes
            Dictionary <char, CharMapper> charMap = new  Dictionary <char, CharMapper>();

            for (int i = 0; i < s.Length; i++)
            {
                char c = s[i];
                if (!charMap.ContainsKey(c))
                {
                    charMap[c] = new CharMapper(i);
                }
                else
                {
                    charMap[c].count++;
                    charMap[c].indexes.Add(i);
                }
            }

            //divide each count in the dictionary by 2 to get character counts for A
            List <char> keys      = new List <char>(charMap.Keys);
            List <char> ListChars = new List <char>();

            foreach (char c in keys)
            {
                charMap[c].finalCount = charMap[c].count / 2;
                for (int i = 0; i < charMap[c].finalCount; i++)
                {
                    ListChars.Add(c);
                }
            }

            //create an ordered char array to show alphebetic hierarchy of letters to encounter
            char[] orderedChars = ListChars.ToArray();
            Array.Sort(orderedChars);

            //create ordered distinct list
            // char[] orderdistinctchars = ListChars.Distinct().ToArray();
            // Array.Sort(orderdistinctchars);

            //instantiate result string
            string result    = "";
            int    strLength = s.Length / 2;

            //start iterating backwards
            for (int i = s.Length - 1; i >= 0; i--)
            {
                char c = s[i];
                //did we encounter the best possible character, if so add it and remove that character from order array
                //and from dictionary of needed character counts
                if (c == orderedChars[0])
                {
                    result                += c;
                    orderedChars           = orderedChars.Skip(1).ToArray();
                    charMap[c].count      -= 1;
                    charMap[c].finalCount -= 1;
                }

                //is this character unskippable?
                //if so we need to add it regardless, and remove it from order array
                else if (charMap[c].count == charMap[c].finalCount)
                {
                    result                += c;
                    charMap[c].count      -= 1;
                    charMap[c].finalCount -= 1;
                    int numidx = Array.IndexOf(orderedChars, c);
                    orderedChars = orderedChars.Where((val, idx) => idx != numidx).ToArray();
                }

                //is this character skippable at first glance?
                //are there more characters of this string left than we need in the final string
                else if (charMap[c].count > charMap[c].finalCount && charMap[c].finalCount != 0)
                {
                    //next idx of best character
                    int nextBestIdx = charMap[orderedChars[0]].indexes.Where(idx => idx < i).Max();

                    //next unskippable idx
                    int nextUnskippableIdx = -1;

                    //iterate from current point till next best
                    int j = i - 1;

                    //*************************************THIS IS THE IMPORTANT PART TO LOOK AT************************

                    //i want to copy the mapping object here, so i can manipulate it to simulate characters being skipped
                    //COPY ONLY SHALLOW COPIES THE DICTIONARY, MEANING THE CHARMAPPER OBJECTS ARE STILL REFERENCING THE ORGIONAL
                    // Dictionary<char, CharMapper> copy = new Dictionary<char, CharMapper>(charMap);

                    //DEEP CLONE, charMapper Objects are now independant and not a reference
                    Dictionary <char, CharMapper> clone = charMap.ToDictionary(kv => kv.Key, kv => kv.Value.Clone() as CharMapper);

                    while (j != nextBestIdx)
                    {
                        char charToCheck = s[j];
                        //if there are only enough left to fulfill final count then its unskippable
                        if (clone[charToCheck].count == clone[charToCheck].finalCount)
                        {
                            nextUnskippableIdx = j;
                            break;
                        }
                        clone[charToCheck].count--;
                        j--;
                    }
                    //*************************************THIS IS THE IMPORTANT PART TO LOOK AT************************
                    j = i - 1;
                    bool breakFlag = false;
                    //for tracking purposes
                    char nextUnskippableChar = nextUnskippableIdx != -1 ? s[nextUnskippableIdx] : 'z';
                    //if the next best is closer than unskippable, or current character is worse than next unskippable
                    //THERE IS A CHARACTER THAT WILL BECOME UNSKIPPABLE BEFORE NEXT BEST, AND THIS CHARACTER IS BETTER THAN IT
                    //THE REASON ITS NOT FOUND IS THAT THERE ARE MULTIPLE INSTANCES WHAT WILL BECOME THE NEXT UNSKIPPABLE (SO ITS NOT THINKING THAT IT IS UNSKIPPABLE)
                    if (nextBestIdx >= nextUnskippableIdx || c > nextUnskippableChar)
                    {
                        breakFlag = true;
                    }
                    else
                    {
                        //we want to look for a better character than current character before we hit the idx of next best option or an unskippable
                        while (j > nextBestIdx && j > nextUnskippableIdx)
                        {
                            char charToCheck = s[j];
                            //is this character better choice? if yes we can stop looking and skip this character
                            if (charToCheck < c && charMap[charToCheck].finalCount > 0)
                            {
                                breakFlag = true;
                                break;
                            }
                            j--;
                        }
                    }
                    //we've determiend there are better characters before next best or next unskippable, so lets skip this one
                    if (breakFlag)
                    {
                        charMap[c].count--;
                    }
                    //there are not better characters bef
                    else
                    {
                        result                += c;
                        charMap[c].count      -= 1;
                        charMap[c].finalCount -= 1;
                        int numidx = Array.IndexOf(orderedChars, c);
                        orderedChars = orderedChars.Where((val, idx) => idx != numidx).ToArray();
                    }
                    //********************************************************borken part */
                }
                // the only condition left is that we found lexagraphical better character that we don't need any more of
                else
                {
                    charMap[c].count--;
                }
                //if we've completd the string, stop looping
                if (result.Length == strLength)
                {
                    break;
                }
            }
            return(result);
        }