Friday Programming Quiz [modified]
-
type *.in | sort > CP.out
Unless, by "(the number)", you mean "the numerical value of the id".Are you sure that TYPE works with wildcards?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
-
Dictionary<int, string> cpians = new Dictionary<int, string>();
List<int> keylist = new List<int>();string strLine = "";
foreach (System.IO.FileInfo fi in new System.IO.DirectoryInfo(@"C:\quiz\").GetFiles())
{
using (System.IO.StreamReader sr = fi.OpenText())
{
while (sr.Peek() >= 0)
{
strLine = sr.ReadLine();
cpians.Add(Int32.Parse(strLine.Split(',')[0]), strLine.Split(',')[1]);
keylist.Add(Int32.Parse(strLine.Split(',')[0]));
}
}
}keylist.Sort();
using (System.IO.FileStream file = new System.IO.FileStream(@"C:\TotalList.txt", System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(file))
{
foreach (int key in keylist)
{
sw.WriteLine(key + "," + cpians[key]);
}
}
}The items in the file need not be sorted for this solution.
Modified version using
SortedList<>
.SortedList<int, string> cpians = new SortedList<int, string>();
string strLine = "";foreach (System.IO.FileInfo fi in new System.IO.DirectoryInfo(@"C:\quiz\").GetFiles())
{
using (System.IO.StreamReader sr = fi.OpenText())
{
while (sr.Peek() >= 0)
{
strLine = sr.ReadLine();
cpians.Add(Int32.Parse(strLine.Split(',')[0]), strLine.Split(',')[1]);
}
}
}using (System.IO.FileStream file = new System.IO.FileStream(@"C:\TotalList.txt", System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(file))
{
foreach (KeyValuePair<int, string> kvp in cpians)
{
sw.WriteLine(kvp.Key + "," + kvp.Value);
}
}
} -
Looks like a job for merge sort.
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
Take a look at my "on-the-fly" solution for a merge sort solution that requires memory only linear to the number of files, independent from the file size.
-
"Computer" I shout. "Yes Master?" "Create a file for me!" "All right. What do you want in the file?" "Names, and an ID number. Can you do that brainiac?" "Cut the crap Boss. Sure thing. Anything else?" "Yeah, keep the file sorted by ID, in ascending order." "Fine. Done. Where do I get the names from?" "They are in another file, it's text, and comma delimited. The first thing on a line is a number, the ID, followed by a name." "Are there multiple entries in a file?" "Yep." "OK, ready to rock and roll."
¡El diablo está en mis pantalones! ¡Mire, mire! Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF! VCF Blog
I think I need to adopt this style of programming :)
"It was the day before today.... I remember it like it was yesterday." -Moleman
-
Oh, now that's got me thinking of Douglas Adams again, Dirk Gently in fact: The program
kgvclsg lgzszsil gvhzxido;vzxdl'vcbx gcb ;klh gjl;ghilsfdghb kZG l gh
will perform the task, we just need to find a compiler for it! :laugh:Surely you'd only get a suffusion of yellow given the inputs?
"It was the day before today.... I remember it like it was yesterday." -Moleman
-
Modified version using
SortedList<>
.SortedList<int, string> cpians = new SortedList<int, string>();
string strLine = "";foreach (System.IO.FileInfo fi in new System.IO.DirectoryInfo(@"C:\quiz\").GetFiles())
{
using (System.IO.StreamReader sr = fi.OpenText())
{
while (sr.Peek() >= 0)
{
strLine = sr.ReadLine();
cpians.Add(Int32.Parse(strLine.Split(',')[0]), strLine.Split(',')[1]);
}
}
}using (System.IO.FileStream file = new System.IO.FileStream(@"C:\TotalList.txt", System.IO.FileMode.Create, System.IO.FileAccess.Write))
{
using (System.IO.StreamWriter sw = new System.IO.StreamWriter(file))
{
foreach (KeyValuePair<int, string> kvp in cpians)
{
sw.WriteLine(kvp.Key + "," + kvp.Value);
}
}
}Infact you don't even need fi.OpenText. You can directly supply the file names to the StreamReader and StreamWriter.
Co-Author ASP.NET AJAX in Action
-
Are you sure that TYPE works with wildcards?
"A good athlete is the result of a good and worthy opponent." - David Crow
"To have a respect for ourselves guides our morals; to have deference for others governs our manners." - Laurence Sterne
Yes, it works.
-
Infact you don't even need fi.OpenText. You can directly supply the file names to the StreamReader and StreamWriter.
Co-Author ASP.NET AJAX in Action
Oh yeah, for the
StreamWriter
, I could have directly given the filename :doh:. In theStreamReader
, I useFileInfo
to get a list of files in the particular directory, since I have it declared I am usingfi.OpenText()
which returns to me aStreamReader
-
My first solution requires loading everything into memory (ReadAllLines/WriteAllLines uses arrays, OrderBy requires having the whole list in memory). Here is another LINQ solution that uses a custom functions for reading/writing files and merging the enumerables:
using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
static class Program {
public static void Main(string[] args) {
SortedMerge(args.Select(
fileName => FileReadLines(fileName).Select(
line => new { ID = int.Parse(line.Split(',')[0]), Name = line.Split(',')[1]}
)), a=>a.ID)
.Select(a=>string.Format("{0},{1}", a.ID, a.Name))
.WriteToFile("output.txt");
}static IEnumerable<string> FileReadLines(string fileName) { using (StreamReader reader = new StreamReader(fileName)) { string line; while ((line = reader.ReadLine()) != null) { Console.WriteLine("read " + line + " from " + fileName); yield return line; } } } static void WriteToFile(this IEnumerable<string> lines, string fileName) { using (StreamWriter writer = new StreamWriter(fileName)) { foreach (string line in lines) { Console.WriteLine("write " + line + " to " + fileName); writer.WriteLine(line); } } } static IEnumerable<T> SortedMerge<T, K>(IEnumerable<IEnumerable<T>> inputs, Func<T, K> keySelector) where K : IComparable<K> { var enumerators = inputs.Select(o=>o.GetEnumerator()).ToList(); var disposables = enumerators.ToList(); // make copy of enumerators for disposing them later try { // move all enumerators on the first element enumerators.RemoveAll(e=>!e.MoveNext()); while (enumerators.Count > 0) { int smallest = 0; for (int i = 1; i < enumerators.Count; i++) { // the the element of the current enumerator smaller than the best found so far? if (keySelector(enumerators\[i\].Current).CompareTo(keySelector(enumerators\[smallest\].Current)) < 0) { smallest = i; } } yield return enumerators\[smallest\].Current; if (!enumerators\[smallest\].MoveNext()) enumerators.RemoveAt(smallest); } } finally { disposables.ForEach(d => d.Dispose()); } }
}
The debug output shows that the program is writing as soon as possible; written lines will be collected by the GC, so this solution can merge multi-GB files without running out of memory. Output:
C:\temp\SharpDevelop Projects\CPQ
I guess you are the winner. Will you like a copy of ASP.NET AJAX in Action?
Co-Author ASP.NET AJAX in Action
-
Rama Krishna Vavilala wrote:
Of course it can be done in language of your choice
Give a couple of hours and I'll have the COBOL version slapped together for you. :)
Chris Meech I am Canadian. [heard in a local bar]
that's not funny, I mainly do COBOL. It makes me sad to think about how this would be done in COBOL.
"If you really want something in this life, you have to work for it. Now, quiet! They're about to announce the lottery numbers..." - Homer Simpson
-
"Computer" I shout. "Yes Master?" "Create a file for me!" "All right. What do you want in the file?" "Names, and an ID number. Can you do that brainiac?" "Cut the crap Boss. Sure thing. Anything else?" "Yeah, keep the file sorted by ID, in ascending order." "Fine. Done. Where do I get the names from?" "They are in another file, it's text, and comma delimited. The first thing on a line is a number, the ID, followed by a name." "Are there multiple entries in a file?" "Yep." "OK, ready to rock and roll."
¡El diablo está en mis pantalones! ¡Mire, mire! Real Mentats use only 100% pure, unfooled around with Sapho Juice(tm)! SELECT * FROM User WHERE Clue > 0 0 rows returned Save an Orange - Use the VCF! VCF Blog
Picard: "Data, do something with these files."