C# - Number to String Mapping - Tough Logic - c#

My TL asked me to implement this:
If we have the alphabets in english numbered as
a 1
b 2
c 3
d 4
e 5
f 6
g 7
h 8
i 9
j 1
k 2
l 3
m 4
n 5
o 6
p 7
q 8
r 9
s 1
t 2
u 3
v 4
w 5
x 6
y 7
z 8
the vowels would be
a 1
e 5
i 9
o 6
u 3
The User would enter :
Number of Vowels
Sum
Number of Characters
Now I need to display a string of length : number of Characters entered by user.
The String would have two Parts:
The first Part would have the Vowels with sum entered by the user.
The second part would be of length [Number of Chars entered by user - Vowels as per the first half of string above] and the sum would be the same entered by user.
Can any body write C# code for this. I tried real hard but could not figure it out.
Any help would be greatly appreciated.
Here's my code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace VowelsAndConsonants
{
class Program
{
static void Main(string[] args)
{
//Gather Info from the User
Console.WriteLine("Please Enter Number of Vowels");
string numVowels = Console.ReadLine();
Console.WriteLine("Please Enter the Total");
string total = Console.ReadLine();
Console.WriteLine("Please Enter the Number of Chars");
string numChars = Console.ReadLine();
//Convert the Strings entered by User to int
int inNumVowels = Convert.ToInt16(numVowels);
int intTotal = Convert.ToInt16(total);
int intNumChars = Convert.ToInt16(numChars);
//Populate the Array with all the alphanets
string[,] arr = new string[,] { { "a", "1" }, { "b", "2" }, { "c", "3" }, { "d", "4" }, { "e", "5" }, { "f", "6" }, { "g", "7" }, { "h", "8" }, { "i", "9" }, { "j", "1" }, { "k", "2" }, { "l", "3" }, { "m", "4" }, { "n", "5" }, { "o", "6" }, { "p", "7" }, { "q", "8" }, { "r", "9" }, { "s", "1" }, { "t", "2" }, { "u", "3" }, { "v", "4" }, { "w", "5" }, { "x", "6" }, { "y", "7" }, { "z", "8" } };
string[] resArr= new string[20];// = null;
for (int i = 0; i < intNumChars; i++)
{
//The logic you guys would suggest goes here
resArr[0]=arr[,];
//Display the string
Console.WriteLine("");
}
}
}
}

The hard part isn't writing the code. The hard part is figuring out what the algorithm is that solves this problem. Once you have the algorithm solid, turning it into code will be straightforward.
What are your thoughts on the algorithm? Start with some contrived examples. For instance, suppose you are given 1/9/2. A solution to that is IR. How would you, as a human, come up with that solution? Can you describe a method whereby you, a human, could always come up with the answer?

I think that you are on the wrong track with using mod.
It seems to me that this is a variation to a "greedy algorithm" problem, normaly associated with working out efficient change with coins in homework questions, but I think this seems to be a variant of it.
Wikipedia has a page on it, and I am sure googling greedy algorithm will help you out.

Related

Discord.net send DMs to a specific user?

So i've been searching for all day for a method that sends to a specific user a private message. I'm making a ticket system and I need to print all tickets in DM to the person that executed the command.
[Command("createtickets")]
[Description("Creates tickets")]
public async Task createtickets(CommandContext ctx)
{
var interactivity = ctx.Client.GetInteractivity();
string filepath = #"C:\Users\Administrator\Desktop\test.txt";
List<string> lines = new List<string>();
lines = File.ReadAllLines(filepath).ToList();
foreach (string line in lines)
{
Console.WriteLine(line);
}
string[] chars = new string[] { "a", "b", "c", "d", "e", "f", "g", "h", "k", "z", "n", "u", "r", "1", "2", "3", "4", "5", "6", "7", "8", "9" };
Random rnd = new Random();
for (int i=0; i< 9; i++)
{
string randomString = "";
for (int j = 0; j<12; j++)
{
randomString = randomString + chars[rnd.Next(0, 21)];
}
lines.Add(randomString);
}
File.WriteAllLines(filepath,lines);
await ctx.Channel.SendMessageAsync("10 Tickets were written");
var user = ctx.User;
As you can see there is a list with all the tickets and that is the thing i need to send via DM. I've tried searching on youtube, Discord.net Docs, DSharpplus Docs, every forum on the internet but they all list functions that were probably removed on the recent versions. Can anyone help me with this? I just need a way to DM the user

How to calculate the sum of column score and time

I have a 2-dimensional array like below.
If I want to sum all time and score of rows of Each ID that start from lesson startpoint=E and ends by lesson endspoint=I. In the case below, for ID 1 it become (time=190+195+200=585 and score=3+3+4=10) and ID 3 that (time=190+210+160=560 and score=5+4+4=13).
I already came up with following loop.
ID Lesson Time Score
1 C 165 4
1 E 190 3
1 H 195 3
1 I 200 4
2 A 100 2
2 B 150 5
2 D 210 2
2 E 110 4
3 D 130 5
3 E 190 5
3 H 210 4
3 I 160 4
3 J 110 4
4 E 120 3
4 H 150 4
4 J 170 4
-
for (int i=0; i<SizeofDataGrid;i++)//save datatable into array
{
for (int j=0; j<4;j++)
{
FILTERED[i,j]=Convert.ToString(interaction.Rows[i][j]);
}
}
for (int i = 0; i < FILTERED.GetLength(0); i++)
{
string UNIQUEID = UniqueUserId[i];
for (int j = 0; j < SizeofDataGrid; j++)
{
if (UNIQUEID == FILTERED[j,0])// match ID
{
for (int x = 0; x < SizeofDataGrid; x++)
{
if (startpoint == FILTERED[j, 1]) //Match start Lesson
{
TotalTime[1, i] = TotalTime[1, i] + Convert.ToUInt16(FILTERED[j, 2]);
TotalTime[0, i] = i;
TotalScore[1, i] = TotalScore[1, i] + Convert.ToUInt16(FILTERED[j, 3]);
TotalScore[0, i] = i;
}
}
}
}
}
Try this:
// this method does the calculations then puts the values in the totalScore and totaltime variables
public void DoCalculations(string[,] data, string id, out int totalScore, out int totalTime)
{
totalTime = 0;
totalScore = 0;
for (int i = 0; i < data.GetLength(0); i++)
{
if (data[i, 0] != id) continue;
// modify this string to contain the lessons between E and I
if (!"EFGHI".Contains(data[i, 1])) continue;
// do proper error checking unless you're sure they'll always be integers
totalTime += int.Parse(data[i, 2]);
totalScore += int.Parse(data[i, 3]);
}
}
And this is the usage example:
string[,] data = new string[,]
{
{"1", "C", "165", "4"},
{"1", "E", "190", "3"},
{"1", "H", "195", "3"},
{"1", "I", "200", "4"},
{"2", "A", "100", "2"},
{"2", "B", "150", "5"},
{"2", "D", "210", "2"},
{"2", "E", "110", "4"},
{"3", "D", "130", "5"},
{"3", "E", "190", "5"},
{"3", "H", "210", "4"},
{"3", "I", "160", "4"},
{"3", "J", "110", "4"},
{"4", "E", "120", "3"},
{"4", "H", "150", "4"},
{"4", "J", "170", "4"}
};
// will store the total score
int totalScore = 0;
// will store the total time
int totalTime = 0;
// calling the function for the id=3
DoCalculations(data, "3", out totalScore, out totalTime);
Console.WriteLine(totalTime); // will output: 560
Console.WriteLine(totalScore); // will output: 13
Do you know about the break statement? You should be able to create a conditional statement that checks for your condition, then put break; at the bottom of it and you will exit the loop.
I would try to avoid using string[,] FILTERED to store your data. You really can easily create strong data types instead. However, if you must use it then I would convert to a strong data type and then do the calculations.
So, starting with the raw data:
string[,] FILTERED = new string[16, 4]
{
{ "1", "C", "165", "4" },
{ "1", "E", "190", "3" },
{ "1", "H", "195", "3" },
{ "1", "I", "200", "4" },
{ "2", "A", "100", "2" },
{ "2", "B", "150", "5" },
{ "2", "D", "210", "2" },
{ "2", "E", "110", "4" },
{ "3", "D", "130", "5" },
{ "3", "E", "190", "5" },
{ "3", "H", "210", "4" },
{ "3", "I", "160", "4" },
{ "3", "J", "110", "4" },
{ "4", "E", "120", "3" },
{ "4", "H", "150", "4" },
{ "4", "J", "170", "4" },
};
I would first turn this into strongly-type data:
var data =
FILTERED
.Cast<string>()
.Select((x, n) => new { x, n })
.GroupBy(xn => xn.n / 4, xn => xn.x)
.Select(xs => new
{
ID = int.Parse(xs.ElementAt(0)),
Lession = xs.ElementAt(1),
Time = int.Parse(xs.ElementAt(2)),
Score = int.Parse(xs.ElementAt(3)),
});
This gives:
I would then do this query:
var result =
data
.GroupBy(x => x.ID)
.Select(xs => new
{
ID = xs.Key,
Lessions = xs
.Where(x => x.Lession.Intersect("EFGHI").Any())
.ToArray(),
})
.Select(x => new
{
x.ID,
Time = x.Lessions.Sum(y => y.Time),
Score = x.Lessions.Sum(y => y.Score),
})
.ToArray();
That gives me this result:
Now, just as an alternative to mucking around with the intermediate FILTERED array you could just get the data directly from the DataTable like this:
var data =
from row in interaction.Rows.Cast<DataRow>()
select new
{
ID = row.Field<int>(0),
Lession = row.Field<string>(1),
Time = row.Field<int>(2),
Score = row.Field<int>(3),
};

How to describe new array with a certain name after running the code?

I am building up some easy stuff but already got an error.
In summary : when my code running user will write some sentence to the cmd and my code will separate it to words.
It is alright so far. After separating, I want to make arrays for each word
for example :
cmd screen =" hello world "
seperating to words = hello , world
making them arrays (program should do these aoutomatically)
string[] hello = new string[5]
and
string[] world = new string[5]
Here is where the problem starts. I want to name those new arrays after running. You will write "apple" to cmd and new array with name "apple" should pop out. Already asked for my teacher about this and he says it can be done with dynamic valuables (with var etc). But I don't know how. Here my codes so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Text.RegularExpressions;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
List<string> tümkelimeler = new List<string>();
for (int i = 1; i < 100; i++)
{
tümkelimeler.Insert(i, "null");
}
int ü = 0;
while (ü == 0)
{
string s = Console.ReadLine();
string[] kelimeler = s.Split(' ');
// this is where i seperate words from sentence .
}
Console.ReadKey() ;
}
}
}
#Complete Code
I'm showing one way of doing it using dynamic ExpandoObject. We keep adding dynamic properties with string name and array values.
Showing for one sentence, you can run a loop and do it for as many sentences you want.
using System.Dynamic;
string s = "hello world"; //example
IDictionary<string, object> dynamicArrays = new ExpandoObject();
string[] words = s.Split(' '); //hello, world
foreach(var word in words)
{
dynamicArrays[word] = word.Select(c => new String(new char[] { c })).ToArray();
}
What it does in the loop is: For each word, it creates a new property in the object with the word (e.g. "hello") as the name. Then it breaks down the same word as a letter (string) array (h, e, l, l, o) and adds that as the value of the same property.
If you see the dynamic object dynamicArrays, it will have following properties
hello: ['h', 'e', 'l', 'l', 'o']
world: ['w', 'o', 'r', 'l', 'd']
See the ExpandoObject reference here.
Update
If you want to do that for multiple user input, you can do like this.
static void Main(string[] args)
{
string s = string.Empty;
IDictionary<string, object> dynamicArrays = new ExpandoObject();
Console.WriteLine("Keep entering words/sentences. Enter blank/empty line to end.");
s = Console.ReadLine();
while (!string.IsNullOrEmpty(s))
{
string[] words = s.Split(' '); //hello, world
foreach (var word in words)
{
dynamicArrays[word] = word.Select(c => new String(new char[] { c })).ToArray();
}
Console.WriteLine("Enter next sentence : ");
s = Console.ReadLine();
}
// do something with dynamicArrays
return;
}
Here, if you enter three values : hello world, apple, green tiger then this is what you'll get in dynamicArrays object.
{
"hello": [ "h", "e", "l", "l", "o" ],
"world": [ "w", "o", "r", "l", "d" ],
"apple": [ "a", "p", "p", "l", "e" ],
"green": [ "g", "r", "e", "e", "n" ],
"tiger": [ "t", "i", "g", "e", "r" ]
}

how do I replace numbers using regex?

I am using C# regex library to do some text find and replace.
I would like to change the following:
1 -> one
11 -> one one
123 -> one two three
for example, here's my code to replace ampersand:
string pattern = "[&]";
string replacement = " and ";
Regex rgx = new Regex(pattern);
string result = rgx.Replace(text, replacement);
Edit
I found some great examples of .NET RegEx on MSDN:
http://msdn.microsoft.com/en-us/library/kweb790z.aspx
Since you're specifically asking for a regex, you could do something like this
var digits = new Dictionary<string, string> {
{ "0", "zero" },
{ "1", "one" },
{ "2", "two" },
{ "3", "three" },
{ "4", "four" },
{ "5", "five" },
{ "6", "six" },
{ "7", "seven" },
{ "8", "eight" },
{ "9", "nine" }
};
var text = "this is a text with some numbers like 123 and 456";
text = Regex.Replace(text, #"\d", x => digits[x.Value]);
which will give you
this is a text with some numbers like onetwothree and fourfivesix

How to create Alphabetical list with letters?

Hi all I trying to implement alpha ordered list by columns
as shown on picture
But my algorithm is not clear and maybe someone could help me within
string[] letters = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X",
"Y", "Z", "Å", "Ä", "Ö", "0-9" };
int j = 0, s = 0, i = 1;
var fullServices = (from se in EntityBase.db.Services
orderby se.Name
select se).ToList();
int total = fullServices.Count;
var grouped = (from l in letters
select new ServiceInfo
{
Letter = l,
Services = EntityBase.db.Services.Where(se => se.Name.StartsWith(l)).ToList(),
Total = EntityBase.db.Services.Where(se => se.Name.StartsWith(l)).Count()
}).ToList();
Dictionary<int, List<ServiceInfo>> result = new Dictionary<int, List<ServiceInfo>>();
changecell:
List<ServiceInfo> item = new List<ServiceInfo>();
while (j < letters.Count())
{
letterchange:
List<Service> _services = new List<Service>();
while (s < total)
{
if ((s == (5 + (total % 5 > i ? 1 : 0)) * i))
{
item.Add(new ServiceInfo() { Letter = letters[j], Services = _services });
result.Add(i, item);
if (i == 6)
goto exit;
i++;
goto changecell;
}
//start render services
if (fullServices.ElementAt(s).Name.StartsWith(letters[j]))
{
_services.Add(fullServices.ElementAt(s));
s++;//increment service in list
}
else //letter switch
{
item.Add(new ServiceInfo() { Letter = letters[j], Services = _services });
j++;
goto letterchange;
}
}//end render services
}
exit:
return View(result);
In a result of my code I see missed letters X Y Z Å Ä Ö
and it's looks like this
Here comes code that renders dictionary
<% foreach (KeyValuePair<int, List<BL.Models.Infos.ServiceInfo>> col in Model)
{ %>
<ul class="col">
<% foreach (var item in col.Value)
{ %>
<% if (!item.Services.Any())
{%>
<li class="disabled">
<h1>
<%= item.Letter %></h1>
</li>
<%}
else
{ %>
<li>
<h1>
<%= item.Letter %>
</h1>
</li>
<% foreach (var service in item.Services)
{ %>
<li><%= service.Name %></li>
<%}
}
}%>
</ul>
<%} %>
Please help...
Well, you're certainly right that the code's not particularly clear :)
I don't really follow the main loop of your code, but here's a simpler starting point. Note that it won't group 0-9 properly (it only deals with 0 at the moment): I'm not sure the best way to approach that, to be honest. You might want to put that off until you get some entries which don't match any of the normal letters...
using System;
using System.Linq;
class Test
{
static void Main(string[] args)
{
ShowGroups();
}
private static readonly char[] Letters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ0".ToCharArray();
// This is taking the place of EntityBase.db.Services
// for the purposes of the test program
public static string[] Services = { "Blogger", "Delicious",
"Digg", "Ebay", "Facebook", "Feed", "Flickr",
"Friendfeed", "Friendster", "Furl", "Google",
"Gosupermodel", "Lastfm", "Linkedin", "Livejournal",
"Magnolia", "Mixx", "Myspace", "NetOnBuy", "Netvibes",
"Newsvine", "Picasa", "Pownce", "Reddit", "Stumbleupon",
"Technorati", "Twitter", "Vimeo", "Webshots",
"Wordpress" };
public static void ShowGroups()
{
var groupedByLetter =
from letter in Letters
join service in Services on letter equals service[0] into grouped
select new { Letter = letter, Services = grouped };
// Demo of how to access the groups
foreach (var entry in groupedByLetter)
{
Console.WriteLine("=== {0} ===", entry.Letter);
foreach (var service in entry.Services)
{
Console.WriteLine (" {0}", service);
}
Console.WriteLine();
}
}
}
I don't know how you intend to split the results into 5 equal columns though...
This might be way off - I've just done this in Notepad (don't have access to an IDE right now). It looks like you're trying to populate the Dictionary<int, List<ServiceInfo>> result instance and I'm assuming that your View method understands how to layout the results in columns.
Here goes:
string[] letters = new string[] { "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
"U", "V", "W", "X", "Y", "Z", "Å", "Ä", "Ö", "0-9" };
var result = new Dictionary<int, List<ServiceInfo>>();
foreach (var letter in letters)
{
var services = (from se in EntityBase.db.Services
where se.Name.StartsWith(letter)
orderby se.Name
select select new ServiceInfo
{
Letter = letter,
Services = EntityBase.db.Services.Where(se => se.Name.StartsWith(letter)).ToList(),
Total = EntityBase.db.Services.Where(se => se.Name.StartsWith(letter)).Count()
}).ToList();
result.Add(i, services);
}
If it's correct, it probably won't be the fastest implementation, but it's more readable.

Categories

Resources