开发者

C# /Linq Yet another Brain Teaser

Friends, there is yet another scenario to solve. I am working it out without applying Linq.But I hope it is good opportunity for me to learn Linq if you share your code in Linq.

It is know as FLAMES

F - Friend

L - Lover

A - Admirer

M - Marry(Husband)

E - Enemy

S - Sister

Problem description:

Two names will be given (male, female).We have to strike out the common letters from both na开发者_如何学Gomes. Then we have to count the number of remaining letters after striking out the common characters from both names. Finally we have to iterate the string FLAMES and striking out the letters in FLAMES until we will reach single character left. The remaining single character shows the relationship. I will explain the process more details in the following example.(Ignore cases and spaces).

Example :

Step 1

Male    : Albert

Female : Hebarna

Letters “a”, “e” ,”b” are common in both names.

( Strike those letters from both string , even the name “Hebarna” contains two “a” you are allowed to strike single “a” from both string because The name “Albert” has only single “a”).

The resultant string is

Male :     $  l    $     $   r   t

Female:    H  $    $     $   r  n    a

Step 2:

Count the remaining letters from both strings.

Count : 7

Step 3:

Using the count we have to iterate the string “FLAMES” in the following manner

F       L           A        M        E           S

1       2           3         4       5           6

7

(Here the count 7 ends at F ,so strike F)

you will get

$       L         A         M         E         S

(Again start your count from immediate next letter (it should not already be hit out) if it is the last letter (“S”) then start from first letter “F” if ‘F” is not already hit out.

 $              L         A          M             E             S

 (igonre)        1         2          3              4            5

 (ignore)       6         7

During counting never consider hit out letters.

$          L         $               M           E         S

                                    1           2          3      

ignore     4       ignore           5           6          7       

"s" will be hit out.

$            L         $           M          E        $

ignore       1         ignore      2           3       

             4         ignore      5           6 

             7

"L" will be hit out

$           $          $            M             E           $

                      ignore        1             2          ignore

ignore     ignore     ignore        3             4          ignore

                                    5             6  

                                    7 

Finally "M" will be hit out. Then only remaining letter is "E" So albert is enemy to herbana.

Update : Lettter "r" is also common in both names.I forgor to hit it out.Anyhow the process is same as explained.Thanks for pointing it out.


Step1 and Step2

var firstLookup = firstName.ToLookup(c => c.ToLower());
var secondLookup = secondName.ToLookup(c => c.ToLower());
var allChars = firstLookup.Keys.Union(secondLookup.Keys);
int count =
(
  from c in allChars
  let firstCount = firstLookup[c].Count()
  let secondCount = secondLookup[c].Count()
  select
    firstCount < secondCount ? secondCount - firstCount :
    firstCount - secondCount
).Sum()

Step3 (untested)

List<char> word = "FLAMES".ToList();

while (word.Count > 1)
{
  int wordCount = word.Count;
  int remove = (count-1) % wordCount;
  word =
    word.Select( (c, i) => new {c, i =
      i == remove ? 0 :
      i < remove ? i + wordCount + 1 : 
      i})
    .OrderBy(x => x.i)
    .Select(x => x.c)
    .Skip(1)
    .ToList();
}

char result = word.Single();


var count = male.Length + female.Length - male.Intersect( female ).Count();

while (flames.Length > 1)
{
     flames = string.Join( '', flames.Where( (c,i) => i != (count % flames.Length) -1 ).ToArray() );
}


That last calculation part that iterates through the flames-letters and removing one after another can be precalculated.

public static Char GetChar(int diff) {
    var idx = (diff - 1) % 60;
    return "efefmeaelmaafmfaflefefeemsasamfmfallslslesmsasmmaelmlaslslfs"[idx];
}

Some things can be done without linq... unless I totally messed something up.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜