I'm making a demo program for a job interview and I'd like to know if there is anything I can make work faster in my current solution. It's a C# console application that accepts input in form of a single string with the words delimited by ,
symbol. The task is to find the most commonly encountered combination of three characters throughout all the words. It's not specified what I should do if there are multiple triplets with the same rate of appearance, so I'm just returning whatever ends up sorted to the first place. Here is my take on this:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static void Main(string[] args)
{
string input = args.Length > 0 ? args[0] : null;
if (input == null) // demo input
input = "Lorem,ipsum,etiam,habitasse,conubia,sed,habitasse,tristique,,erat,varius,vitae,nunc,vulputate,etiam,proin,,interdum,malesuada,nam,curabitur,nibh,pharetra,ultricies,elit,elementum,viverra,vehicula,lacinia,vestibulum,dapibus,,bibendum,vestibulum,quisque,potenti,dictum,ad,curabitur,neque,,taciti,consequat,malesuada,quisque,ultrices,scelerisque,in,fermentum,fringilla,per,ad.Tortor,habitasse,auctor,consequat,imperdiet,vel,iaculis,suscipit,torquent,,porta,eget,cubilia,cras,quisque,sociosqu,auctor,neque,,ac,dictum,elit,rhoncus,ornare,augue,cras,quis,tempor,sodales,congue,nulla,dictum,quisque,iaculis,magna,mattis,odio,,elementum,varius,turpis,pretium,consequat,gravida,ut,hendrerit,metus,,pulvinar,scelerisque,eu,et,neque,cubilia,mauris,elementum,porttitor,eleifend,vestibulum,luctus,id,diam,pellentesque,convallis,nisi,libero,ante,aliquam,maecenas,facilisis.Suscipit,posuere,gravida,luctus,cursus,erat,eleifend,,magna,tempor,iaculis,arcu,rutrum,viverra,lorem,,posuere,ipsum,leo,aenean,donec,praesent,mollis,phasellus,sociosqu,orci,magna,potenti,donec,curabitur,feugiat,,ultricies,integer,lacus,mollis,porta,consectetur,fames,dolor,,himenaeos,enim,quisque,dapibus,viverra,maecenas,nam,ac,eget,est,sed,conubia,ad,aliquet,sed,consequat,augue,,quisque,bibendum,luctus,id,tempus,lacinia,facilisis,,fames,eget,ut,taciti,nullam,malesuada,integer.Massa,egestas,enim,urna,magna,ultrices,placerat,at,,adipiscing,taciti,bibendum,sodales,consequat,mollis,tempus,platea,,lorem,nisi,congue,vehicula,lacinia,fusce.Donec,gravida,interdum,malesuada,vel,erat,velit,massa,pulvinar,fringilla,potenti,,habitasse,ullamcorper,varius,vel,lobortis,proin,risus,nulla,senectus,,amet,pharetra,quam,elit,convallis,quis,laoreet,vestibulum,rhoncus,eget,lectus,hendrerit,elementum,etiam,viverra,sit,porttitor,etiam,sollicitudin,porta,nibh,non,,nibh,ipsum,inceptos,pellentesque,placerat,conubia,neque,donec,id,vivamus,sed,eget,suscipit,tristique,orci,id,ipsum,ligula,morbi,aliquam,eros,inceptos,leo,curabitur,vehicula,aliquam,aenean,porta,tempor,cras,aenean,nostra,sapien,,ac,lacus,donec,ut,placerat,bibendum,potenti,pellentesque,cubilia,,nunc,nisi,tristique,nam,tristique,varius,ultrices.Maecenas,bibendum,himenaeos,ut,a,ornare,sociosqu,integer,mi,scelerisque,congue,dolor,suspendisse,mattis,eu,,pulvinar,maecenas,etiam,fermentum,leo,eleifend,quis,semper,hac,cursus,aenean,ornare,at,potenti,class,donec,dapibus,dictum,vitae,id,suspendisse,taciti,,placerat,sem,elementum,id,metus,vehicula,nostra,curae,aliquet,,inceptos,quisque,massa,augue,sollicitudin,porta,cras,senectus.Aliquam,sit,nec,vulputate,mauris,lorem,inceptos,volutpat,hac,quisque,,iaculis,blandit,vel,erat,condimentum,orci,massa,luctus,placerat,,fermentum,facilisis,purus,eget,potenti,sem,nec,hendrerit,tempus,habitant,eros,sit,curabitur,congue,porttitor,curabitur,praesent,tortor,,mattis,donec,vehicula,massa,a,donec,fames,lacinia,,est,sodales,fringilla,aliquam,lacus,class,nisi,hac.Hac,venenatis,himenaeos,volutpat,a,at,semper,aenean,erat,etiam,dapibus,quis,diam,,erat,mi,curabitur,nisl,proin,praesent,suspendisse,bibendum,nibh,erat,mollis,consequat,congue,etiam,feugiat,rhoncus,tempor,libero,pellentesque,duis,id,eu,,mattis,in,integer,lectus,non,sed,sapien,eu,felis,donec,,taciti,purus,vulputate,tellus,massa,malesuada,litora,nisl,feugiat,sollicitudin,accumsan,porta,ligula,lobortis,vitae,suspendisse,varius,,in,lorem,habitant,arcu,pellentesque,blandit,,viverra,nulla,class,molestie,pharetra,duis,ac,eu,tempus,aliquam,eros,tristique,quam,a,tempor,netus,neque,vel,tincidunt.Inceptos,porta,id,nunc,platea,aptent,orci,litora,maecenas,vivamus,,at,consequat,convallis,tempus,pharetra,lorem,enim,est,,ultrices,nunc,velit,urna,gravida,sem,molestie,sem,faucibus,habitasse,feugiat,id,pulvinar,etiam,pretium,,a,donec,eu,sapien,suscipit,pretium,nam,,elit,nam,sagittis,suspendisse,fermentum,bibendum,sed,adipiscing,scelerisque,id,et,faucibus,adipiscing,aenean,nostra,,duis,purus,odio,feugiat,fringilla,eu,primis,donec,,ultrices,lacinia,justo,euismod,nullam,class,litora,est,tempus,tortor,phasellus,massa,praesent,sit,vehicula,eu,consectetur,felis,dapibus,interdum.Class,fringilla,luctus,a,semper,hendrerit,quisque,mattis,,netus,potenti,pellentesque,risus,scelerisque,mi,pulvinar,morbi,,aenean,eros,posuere,rhoncus,semper,aliquam,eget,mi,aliquam,sapien,sem,scelerisque,ornare,ultricies,,sem,tempus,aliquet,potenti,nulla,vel,bibendum,,ornare,accumsan,varius,at,himenaeos,suscipit,netus,nisi,fermentum,habitant.Volutpat,at,iaculis,nam,a,habitasse,dictum,ipsum,hac,quisque,aliquam,vestibulum,gravida,vehicula,arcu,donec,dolor,faucibus,consequat,vivamus,,curabitur,luctus,justo,vivamus,duis,accumsan,tellus,,blandit,commodo,etiam,vivamus,ultricies,fermentum,curabitur,pretium,sociosqu,in,praesent,vulputate,dictumst,aptent,,tempor,porttitor,ligula,duis,nulla,non,platea,consequat,fermentum,,platea,tortor,convallis,feugiat,tincidunt,donec,scelerisque,ultricies,convallis,pulvinar,porta,nam,porttitor,lacus,,aenean,euismod,cubilia,magna,ut,,tortor,dolor,dui,nam,egestas.Dui,eros,nisi,in,habitasse,vulputate,bibendum,pulvinar,fusce,,platea,integer,rutrum,mattis,varius,cras,lorem,,etiam,nisi,lectus,nullam,egestas,consectetur,at,non,eros,nostra,pellentesque,hac,nullam,curabitur,consequat,nunc,,inceptos,lacinia,quisque,donec,porta,placerat,potenti,non,nam,tempor,et,odio,lectus,netus,auctor,,sollicitudin,sodales,erat,etiam,arcu,ligula,faucibus,,aenean,mauris,vel,elementum,duis,mollis,convallis.Suscipit,lobortis,purus,gravida,euismod,duis,luctus,eu,lacus,condimentum,,duis,vitae,leo,lacinia,proin,laoreet,vehicula,sollicitudin,,feugiat,ut,viverra,per,mattis,integer,quisque,erat,semper,scelerisque,inceptos,neque,lacinia,varius,vehicula,ac,,hac,mauris,rutrum,pulvinar,cursus,amet,,eros,ullamcorper,ad,non,facilisis,eu,primis,venenatis,commodo,phasellus,enim,fringilla,maecenas,convallis,eget,duis,ornare,lacinia,id,eros,class,malesuada,aenean,proin,etiam,aliquam,faucibus,tempor,,at,arcu,pretium,luctus,ut,curae,iaculis,varius,,lorem,tempus,a,fermentum,duis,ut,erat,sollicitudin,id,tincidunt,quisque,cursus,sed,imperdiet,volutpat,torquent,mattis,placerat,quis.Lectus,class,vulputate,ut,lacus,litora,,dictum,sollicitudin,sociosqu,platea,vivamus,,fermentum,libero,quam,commodo.Sollicitudin,blandit,urna,quam,egestas,risus,condimentum,varius,semper,,magna,enim,pharetra,molestie,rhoncus,tempus,interdum,,ad,taciti,malesuada,lobortis,felis,class,a,tincidunt,duis,convallis,netus,vitae,per,orci,viverra.Morbi,nibh,tincidunt,aenean,nulla,sapien,volutpat,tellus,interdum,facilisis,potenti,aliquam,ante,mauris,,varius,neque,ultrices,nisl,tempus,est,risus,vehicula,pretium,maecenas,class,sollicitudin,blandit,a,sodales,per,tincidunt,viverra,eros,,torquent,cras,curae,volutpat,torquent,sociosqu,,luctus,nibh,lacus,tincidunt,vulputate.Auctor,sapien,vivamus,sapien,aenean,ligula,cursus,cubilia,vehicula,aliquam,,neque,purus,ultricies,mauris,fringilla,varius,ante,proin,etiam,neque,odio,habitasse,curabitur,id,magna,diam,tincidunt,fringilla,,vulputate,fermentum,taciti,vel,quisque,volutpat,eget,vehicula,per,quisque,eleifend,aenean,risus,torquent,quisque,,risus,netus,torquent,accumsan,netus,,sodales,habitant,malesuada,tempor.Consectetur,lobortis,molestie,senectus,pharetra,rhoncus,,amet,pellentesque,eleifend,proin,porttitor,etiam,,congue,pellentesque,iaculis,nibh,cubilia,velit,leo,per,fringilla,risus,class,augue,netus,,placerat,habitant,integer,mollis,scelerisque,aenean,pulvinar,,molestie,leo,iaculis,posuere,eget,dictum,lobortis,commodo,ac,elementum,ullamcorper,dictumst,dui,lectus,fames,etiam,eleifend,,dolor,interdum,vitae,tortor,taciti,vel,tellus,sagittis,quam,iaculis,,fermentum,phasellus,himenaeos,mauris,aliquet,vehicula,ut,fringilla,tempor,habitant,ligula,viverra,fusce,sapien,euismod,rhoncus,orci,ultrices,,enim,etiam,purus,fringilla,nulla,varius,pulvinar,ac,suspendisse,curabitur,,rutrum,habitant,quis,taciti,pulvinar,aenean,duis,augue,per,primis,diam,ultrices.Ac,eleifend,elementum,sollicitudin.Semper,feugiat,quisque,ut,sociosqu,orci,hendrerit,ad,pulvinar,,curae,aliquam,interdum,condimentum,nulla,duis,sapien,metus,,diam,dictum,porttitor,quisque,id,semper,etiam,augue,cursus,ante,faucibus,metus,interdum,pulvinar,,lectus,sem,maecenas,mattis,leo,,urna,potenti,iaculis,arcu,augue,conubia,congue,dolor,hendrerit,tempor,primis,praesent,pretium,molestie,,pharetra,eros,posuere,aliquam,lacus,maecenas,imperdiet,nec,congue,suspendisse,enim,vulputate,turpis,viverra,himenaeos,dapibus,potenti,egestas,augue,mattis,sem";
var words = input.Split(',');
int totalWords = words.Length;
string[] trimmedWords = new string[totalWords];
for (int i = 0; i < totalWords; i++)
trimmedWords[i] = words[i].Trim();
var hs = new HashSet<string>();
var dic = new Dictionary<string, int>();
for (int j = 0; j < totalWords; j++)
{
string word = trimmedWords[j];
int wordLength = word.Length;
for (int i = 0; i <= wordLength - 3; i++)
{
string triplet = word.Substring(i, 3);
if (!hs.Contains(triplet))
{
hs.Add(triplet);
dic[triplet] = 1;
}
else
dic[triplet]++;
}
}
// there might be a faster way to sort by value
var sortedList = dic.OrderByDescending(x => x.Value);
string output = sortedList.First().ToString();
// shows 50 most used triplets, just for checking
//var sortedList = dic.OrderByDescending(x => x.Value).ToList();
//string output = string.Join(Environment.NewLine, sortedList.GetRange(0, sortedList.Count >= 50 ? 50 : sortedList.Count));
Console.WriteLine(output);
Console.ReadKey();
}
}
I'm using HashSet
to lookup and add new triplets, because it's the fastest thing I know in C# that can do this.
I am not entirely sure about using a Dictionary<string, int>
for storing the number of triplet occurrences. A faint voice in my head says something about arrays, but I can't make out the rest :)
Also just sorting the dictionary and getting the first element with Linq doesn't seem like the best approach, but unfortunately I don't know a better way yet.
How could this application be improved in terms of performance and code quality?