C# Beautiful Strings Test case for failed case [closed] - c#

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have an issue with this:
When John was a little kid he didn't have much to do. There was no internet, no Facebook, and no programs to hack on. So he did the only thing he could... he evaluated the beauty of strings in a quest to discover the most beautiful string in the world.
Given a string s, little Johnny defined the beauty of the string as the sum of the beauty of the letters in it. The beauty of each letter is an integer between 1 and 26, inclusive, and no two letters have the same beauty. Johnny doesn't care about whether letters are uppercase or lowercase, so that doesn't affect the beauty of a letter. (Uppercase 'F' is exactly as beautiful as lowercase 'f', for example.)
You're a student writing a report on the youth of this famous hacker. You found the string that Johnny considered most beautiful. What is the maximum possible beauty of this string?
Input sample:
Your program should accept as its first argument a path to a filename. Each line in this file has a sentence. E.g.
ABbCcc
Good luck in the Facebook Hacker Cup this year!
Ignore punctuation, please :)
Sometimes test cases are hard to make up.
So I just go consult Professor Dalves
Output sample:
Print out the maximum beauty for the string. E.g.
152
754
491
729
646
And here is my code in C#:
static void Main(string[] args)
{
StreamReader myR = new StreamReader(args[0]);
List<string> myL = new List<string>();
while (!myR.EndOfStream)
{
myL.Add(myR.ReadLine());
}
foreach (string item in myL)
{
int maxBeautifulNum = 0;
string temp = item.ToLower();
char[] myC = temp.ToCharArray();
string[] tempS = new string[myC.Length];
string tempCount;
for (int i = 0; i < myC.Length; i++)
{
if ((myC[i] >= 'a' && myC[i] <= 'z') || (myC[i] >= 'A' && myC[i] <= 'Z'))
{
tempS[i] = myC[i].ToString();
}
}
tempS = tempS.Where(w => !string.IsNullOrWhiteSpace(w)).ToArray();
List<string> myCounterList = new List<string>();
while(tempS.Length >= 1)
{
int count = 0;
tempCount = tempS[0];
for (int j = 0; j < tempS.Length; j++)
{
if (tempS[j] == tempCount)
{
count++;
}
}
myCounterList.Add(count.ToString());
tempS = tempS.Where(w => w != tempCount).ToArray();
}
string[] myCounterString = myCounterList.ToArray();
Array.Sort(myCounterString);
Array.Reverse(myCounterString);
for (int i = 0; i < myCounterString.Length; i++)
{
maxBeautifulNum += (26 - i) * int.Parse(myCounterString[i]);
}
Console.WriteLine(maxBeautifulNum);
}
}
It run right with only some tests, but I can't find out else test for it runs failed.
Any one can show me test for my code run failed.

Here's a basic LINQPad program that calculates the "beauty" of a string:
void Main()
{
string[] inputs =
{
"a",
"z",
"A test",
"A TEST",
"a test"
};
foreach (var input in inputs)
{
var beauty =
(from c in input
let C = char.ToUpper(c)
where C >= 'A' && C <= 'Z'
select (int)(C - 'A') + 1).Sum();
beauty.Dump(input);
}
}
All the magic is in that single LINQ statement inside the loop there.
Also, to read all the lines from a file, use this:
string[] lines = File.ReadAllLines(fileName);

Related

how to get words from string without SPLIT in c# [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
I'm stack with a task which ask for "read from console" (C#) a text (string) and get words separated by spaces.
for example: phrase=**"i love this world love"** BUT I need to try this WITHOUT methods or functions like SPLIT or REGEX or similar.
I need to compare 2 words and I dont know how to catch 'em in separated word1 word2 fullphrase.
What i want is word1="this" word2= "world" AND CHECK if there are 2 words REPEATED
string frase, palabra1="",pal2="";
bool si = false;
Console.WriteLine("Entra frase");
frase = Console.ReadLine();
int j = 0;
for (int i = 0; i < frase.Length; i++)
{
if (frase[i] != ' ')
{
palabra1 += frase[i];
if (pal2 == palabra1) si = true;
}
else
{
pal2 = palabra1;
palabra1 = "";
}
}
if (si == true) Console.WriteLine($" SI HAY palabras seguidamente
repetidas ");
else Console.WriteLine($"NO HAY PALABRAS REPETIDAS AQUI");
If you can't use any functions(split, regex, indexOf, etc), then what you should do is loop through each character of the text, and push the currently processed segment into your word list when you reach a (white)space.
String testString = "This is a test string ";
ArrayList words = new ArrayList();
string currentWord = "";
foreach(char c in testString)
{
if(Char.IsWhiteSpace(c))
{
if(currentWord.Length > 0)
{
words.Add(currentWord);
currentWord = "";
}
}
else
{
currentWord+=c;
}
}

Need help finding n amount of Excel Ranges

So I have this situation:
At work I need to make an Excel AddIn which can collect some data from user surveys and show them in a neat little Excel Report. I have the format down however I have trouble figuring out how I find the Excel Ranges needed to showcase the questions that were asked in the survey.
Every question needs to take up three cells each since there are three stats associated with each and that's fine until you reach Z and have to start over with AA, AB, AC, etc. I can't quite wrap my head around it and I feel my current solution is being needlessly complicated. I know that right now there are 13 questions. That's 39 cells I need for the questions total but that could change in the future, or I might have to find smaller reports than all of the 13 questions. I need to make sure my algorithm can take care of both scenarios.
Currently I have this:
const String ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int alphabetCounter = 0;
int alphabetIndex = 1;
for (int i = 0; i < dict["questions"].Length; i++)
{
String start = "";
String end = "";
if ((alphabetIndex + 1) > ALPHABET.Length)
{
alphabetCounter++;
alphabetIndex = 0;
start += ALPHABET[alphabetCounter - 1] + ALPHABET[alphabetIndex];
}
else
{
start += ALPHABET[alphabetIndex];
alphabetIndex++;
}
if ((alphabetIndex + 1) > ALPHABET.Length)
{
alphabetCounter++;
alphabetIndex = 0;
end += ALPHABET[alphabetIndex];
}
else
{
alphabetIndex++;
end += ALPHABET[alphabetIndex];
}
Excel.Range range = sheet.get_Range(start + "7", end + "7");
questionRanges.Add(range);
}
It's not finished because I ran into a wall here. So just to explain:
ALPHABET is just that. The alphabet. I use that to get the cell letters.
AlphabetCounter is how many times I have gone through the alphabet so in the event that I need to add an extra letter in front of my cells letter (Like the A in AB) I can get that from the ALPHABET string
AlphabetIndex is where in the alphabet I currently am.
I hope you can help me.
How would I go about getting all the ranges I need to accompany the n amount of questions I can get details about?
The trivial solution would be to change
const string ALPHABET = "ABC..."
to
const string[] ColumnNames = { "A", "B", "C", ..., "Z", "AA".. }
But this doesn't scale well. Think about what happens when you need to add a column. You'd have to add another item in the array, and eventually you'd have 26^2 array entries. Certainly not ideal.
A better solution would be to treat the column index as a base 26 number and convert it using a function like the following:
string GetColumnName(int index)
{
List<char> chars = new List<char>();
while (index >= 0)
{
int current = index % 26;
chars.Add((char)('A' + current));
index = (int)((index - current) / 26) - 1;
}
chars.Reverse();
return new string(chars.ToArray());
}
The function here converts the base by repeatedly calculating the remainder (also known as modulus or %).
just another idea of implementation, maybe it can be useful:
...
List<char> start = new List<char>();
List<char> end = new List<char>();
start = Increment(end);
Increment(end);
Increment(end);
Excel.Range range = sheet.get_Range(new String(start.ToArray())+ "7",
new String(end.ToArray())+ "7");
}
private List<char> Increment(List<char> listColumn, int position=0)
{
if (listColumn.Count > position)
{
listColumn[position]++;
if (listColumn[position] == '[')
{
listColumn[position] = 'A';
Increment(listColumn, ++position);
}
}
else
{
listColumn.Add('A');
}
return listColumn;
}

Minesweeper(simple) in c# [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
so I'm working on some small thing and I'm kind of lost. This is what I have so far.
static void izris()
{
Random bombe = new Random();
int[,] polje = new int[7, 7];
string stolpci = " ABCDEFG";
int vrstice=1;
foreach (char c in stolpci)
{
Console.Write(c);
Console.Write(" ");
}
Console.WriteLine();
for (int i = 0; i < 7; i++)
{
for (int j = 0; j < 7; j++)
{
polje[i, j] = bombe.Next(0, 2);
}
}
//izris polja
for(int i=0;i<7;i++)
{
Console.Write(vrstice);
vrstice++;
Console.Write(" ");
for (int j = 0; j < 7; j++)
{
Console.Write(polje[i,j]);
Console.Write(" ");
}
Console.WriteLine();
}
}
So what this does is, it prints a field of 7x7 that contains random numbers from 0 to 1. Now 1 means it is a mine, and 0 means it's not a mine. Now if you look, there are characters marking the columns(ABCDEFG) and numbers from 1-7 marking the rows. Now what I want to do is, for example the user would enter a string and the string would be B4. Then the program would check that and see if the field that the user selected is a mine(0) or a bomb(1). If it is a bomb it would also say how many bombs(1's) are nearby. I have no idea how to do this.
I was thinking of transforming the A-F characters into 0,6 numbers so I could index easier, but I don't know.
So I made this to check if the input is correct.
static void vnospolja()
{
string lokacija;
string nekaj = "A";
int nekaj2 = nekaj[0] - 'A';
lokacija = Convert.ToString(Console.ReadLine());
while (lokacija.Length < 2)
{
string pravilnalokacija=lokacija.Substring(0,1);
int pravilnalokacijaint = pravilnalokacija[0];
if(pravilnalokacijaint>65 && pravilnalokacijaint<72)
{
Console.Write("input ok");
}
string drugiznak = lokacija.Substring(1, 1);
int drugiznakint = drugiznak[0];
if(drugiznakint>0 && drugiznakint<8)
{
Console.Write("input ok");
}
}
}
Now I need some ideas on how I would do this, for instance user enters A4, so the input is correct. So how do I actually move accros my 7,7 field and check for A4? I don't understand this, my friend told me something about a second indexer in my multidimensional field but I have no clue.
to just convert the users input into 0 based coordinates you could use this.
static int[] GetInput()
{
string input = Console.ReadLine();
//validate input here..
int x = input[0] - 'A'; //converts char to int
int y = int.Parse(input.Substring(1)) - 1;
return new int[]{ x, y };
}
You could use this method by doing...
var selected = GetInput();
if(polje[selected[0]][selected[1]] == 1)
{
//its a bomb
}
What about using a Dictionary instead of using an Array?
Dictionary<string, bool> p = new Dictionary<string, bool>();
if (p.ContainsKey("a1"))
{
//do something
}
else { } // not a bomb/mine
So you can easily check wether the field is a bomb.
If you want to translate a user input, such as B4 into row and column, here is a simple way you could do it. Since you already have a collection of column names stolpci, you can use string.IndexOf, which will find the position of a character in a string. For example, B is found in place 2 (using 0-based indexing)
01234567
" ABCDEFG"
Since you would want B to map to column number 1, rather than 2 in the minesweeper array, you would need to subtract one.
As far as the number part goes, you can use int.Parse to read the number. Once again, the number is going to be off by one, because row number 4 actually corresponds to row number 3 in the 0-based indexing for the minesweeper array. So your final result might look something like this:
var input = "B4"; // this would come from the user, hard-coding for example
var column = stolpci.IndexOf(entry.Substring(0, 1)); // 2
var row = int.Parse(entry.Substring(1, 1)); // 4
var isBomb = polje[row - 1, col - 1] == 1; // offset by 1 for 0-based indexing
// do something with this

Find longest substring in an array of strings and remove it from all the elements in the array [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I have this array, for example (the size is variable):
x = ["10111", "10122", "10250", "10113"]
I need to find the longest string that is a substring of each array element ("10" in this case) (it need not to be a prefix of the strings). I have to remove it from all the strings. The output for this example would be:
x=["111","222","250","113"] //common value = "10"
This extension finds the longest most common substring(s). Note that "1" is also contained in every string even more often than "10". (C# only):
public static class StringExtensions
{
public static IEnumerable<string> GetMostCommonSubstrings(this IList<string> strings)
{
if (strings == null)
throw new ArgumentNullException("strings");
if (!strings.Any() || strings.Any(s => string.IsNullOrEmpty(s)))
throw new ArgumentException("None string must be empty", "strings");
var allSubstrings = new List<List<string>>();
for (int i = 0; i < strings.Count; i++)
{
var substrings = new List<string>();
string str = strings[i];
for (int c = 0; c < str.Length - 1; c++)
{
for (int cc = 1; c + cc <= str.Length; cc++)
{
string substr = str.Substring(c, cc);
if (allSubstrings.Count < 1 || allSubstrings.Last().Contains(substr))
substrings.Add(substr);
}
}
allSubstrings.Add(substrings);
}
if (allSubstrings.Last().Any())
{
var mostCommon = allSubstrings.Last()
.GroupBy(str => str)
.OrderByDescending(g => g.Key.Length)
.ThenByDescending(g => g.Count())
.Select(g => g.Key);
return mostCommon;
}
return Enumerable.Empty<string>();
}
}
Now it's easy:
string[] x = new[] { "10111", "10122", "10250", "10113" };
string mostCommonSubstring = x.GetMostCommonSubstrings().FirstOrDefault();
if (mostCommonSubstring != null)
{
for (int i = 0; i < x.Length; i++)
x[i] = x[i].Replace(mostCommonSubstring, "");
}
Console.Write(string.Join(", ", x));
output:
111, 122, 250, 113
DEMO
Edit: If you just want to find the longest common substring without taking the frequency of occurrence into account you can use this optimzed approach(O(n) operation) using a HashSet<string>:
public static string GetLongestCommonSubstring(this IList<string> strings)
{
if (strings == null)
throw new ArgumentNullException("strings");
if (!strings.Any() || strings.Any(s => string.IsNullOrEmpty(s)))
throw new ArgumentException("None string must be empty", "strings");
var commonSubstrings = new HashSet<string>(strings[0].GetSubstrings());
foreach (string str in strings.Skip(1))
{
commonSubstrings.IntersectWith(str.GetSubstrings());
if (commonSubstrings.Count == 0)
return null;
}
return commonSubstrings.OrderByDescending(s => s.Length).First();
}
public static IEnumerable<string> GetSubstrings(this string str)
{
if (string.IsNullOrEmpty(str))
throw new ArgumentException("str must not be null or empty", "str");
for (int c = 0; c < str.Length - 1; c++)
{
for (int cc = 1; c + cc <= str.Length; cc++)
{
yield return str.Substring(c, cc);
}
}
}
Use it in this way:
string[] x = new[] { "101133110", "101233210", "102533010", "101331310" };
string longestCommon = x.GetLongestCommonSubstring(); // "10"
Try this: (I suppose the common string should be at the beginning):
string[] x = {"10111","10222","10250","10113"};
string common = x[0];
foreach(var i in x){
while(!i.StartsWith(common)){
common = common.Substring(0,common.Length-1);
if(common == "") break;
}
}
x = x.Select(a=>a.Substring(common.Length)).ToArray();
Find the maximum number of times a substring of length 1 appears. This is a simple O(n^2) search. Call this maximum number of occurrence K.
In your example, this is "1", "0", and K=5.
Now you know that all substrings of length 2 cannot appear in more than K input strings. Also, any substring that occurs K times must be made of the length 1 substrings that occured K times. Search the length 1 substrings for substrings of length 2 that exist K times, this is again a simple O(n^2) search.
Repeat for longer lengths until no more substrings exist in K inputs.

Char/String comparison

I'm trying to have a suggestion feature for the search function in my program eg I type janw doe in the search section and it will output NO MATCH - did you mean jane doe? I'm not sure what the problem is, maybe something to do with char/string comparison..I've tried comparing both variables as type char eg char temp -->temp.Contains ...etc but an error appears (char does not contain a definition for Contains). Would love any help on this! 8)
if (found == false)
{
Console.WriteLine("\n\nMATCH NOT FOUND");
int charMatch = 0, charCount = 0;
string[] checkArray = new string[26];
//construction site /////////////////////////////////////////////////////////////////////////////////////////////////////////////
for (int controlLoop = 0; controlLoop < contPeople.Length; controlLoop++)
{
foreach (char i in userContChange)
{
charCount = charCount + 1;
}
for (int i = 0; i < userContChange.Length; )
{
string temp = contPeople[controlLoop].name;
string check=Convert.ToString(userContChange[i]);
if (temp.Contains(check))
{
charMatch = charMatch + 1;
}
}
int half = charCount / 2;
if (charMatch >= half)
{
checkArray[controlLoop] = contPeople[controlLoop].name;
}
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////
Console.WriteLine("Did you mean: ");
for (int a = 0; a < checkArray.Length; a++)
{
Console.WriteLine(checkArray[a]);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
A string is made up of many characters. A character is a primitive, likewise, it doesn't "contain" any other items. A string is basically an array of characters.
For comparing string and characters:
char a = 'A';
String alan = "Alan";
Debug.Assert(alan[0] == a);
Or if you have a single digit string.. I suppose
char a = 'A';
String alan = "A";
Debug.Assert(alan == a.ToString());
All of these asserts are true
But, the main reason I wanted to comment on your question, is to suggest an alternative approach for suggesting "Did you mean?". There's an algorithm called Levenshtein Distance which calculates the "number of single character edits" required to convert one string to another. It can be used as a measure of how close two strings are. You may want to look into how this algorithm works because it could help you.
Here's an applet that I found which demonstrates: Approximate String Matching with k-differences
Also the wikipedia link Levenshtein distance
Char type cannot have .Contains() because is only 1 char value type.
In your case (if i understand), maybe you need to use .Equals() or the == operator.
Note: for compare String correctly, use .Equals(),
the == operator does not work good in this case because String is reference type.
Hope this help!
char type dosen't have the Contains() method, but you can use iit like this: 'a'.ToString().Contains(...)
if do not consider the performance, another simple way:
var input = "janw doe";
var people = new string[] { "abc", "123", "jane", "jane doe" };
var found = Array.BinarySearch<string>(people, input);//or use FirstOrDefault(), FindIndex, search engine...
if (found < 0)//not found
{
var i = input.ToArray();
var target = "";
//most similar
//target = people.OrderByDescending(p => p.ToArray().Intersect(i).Count()).FirstOrDefault();
//as you code:
foreach (var p in people)
{
var count = p.ToArray().Intersect(i).Count();
if (count > input.Length / 2)
{
target = p;
break;
}
}
if (!string.IsNullOrWhiteSpace(target))
{
Console.WriteLine(target);
}
}

Categories

Resources