Count the Ones from 1 to 99,999,999 - c#

I am seeking an algorithm that can simply count how many 1's are there from 1 to 99,999,999 as fast as possible
There are many ways but I need the fastest.
Actually the right number is 80000000
My try in c#:
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
int counter = 0;
sw.Start();
for (int i = 1; i <= 99999999; i++)
{
int num = i;
while (num > 0)
{
if (num % 10==1)
{
counter++;
}
num = num / 10;
}
}
sw.Stop();
Console.WriteLine("1 is counted {0} times and prog time is {1}", counter, sw.Elapsed.ToString());
i don't know the math formula to get it without any loop as i think it will be the fastest way !!

actually i managed to do it without any loops so that's considered the fastest way and i am gonna share it for knowlagde
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
int counter = 0;
sw.Reset();
sw.Start();
int n=8;
counter =(int) (n * Math.Pow(10, n - 1));
sw.Stop();
Console.WriteLine("1 is counted {0} times and prog time is {1}", counter, sw.Elapsed.ToString());

Related

How to calculate the average of multiple Stopwatch times?

So basically what i'm trying to do is calculate the average of all the Stop Watch times that my for loop produces and out put it to the Console. i know how to take an average but i dont know how to apply it to Stopwatch times. Please help?
for (int index = 0; index < iterations; index++)
{
// loop to generate an array of random numbers
for (int count = 0; count < arrayOfInts.Length; count++)
{
arrayOfInts[count] = r.Next(numitems);
}
// a random array has been created start the clock and sort it
Stopwatch elpased = new Stopwatch();
elpased.Start();
selectionSort(arrayOfInts);
elpased.Stop();
if (iterations == iterations)
{
var average = elpased.Elapsed;
Console.WriteLine ("Time for ___ sort to complete: " + elpased.Elapsed.ToString ());
}
}
Console.ReadLine();
}
This is what i have so far.
I'd suggest to use ElapsedTicks instead. And you need to store the ticks for each iteration and calculate the average afterwards:
List<long> ticks = new List<long>();
for (int index = 0; index < iterations; index++)
{
// loop to generate an array of random numbers
for (int count = 0; count < arrayOfInts.Length; count++)
{
arrayOfInts[count] = r.Next(numitems);
}
// a random array has been created start the clock and sort it
Stopwatch elapsed = new Stopwatch();
elapsed.Start();
selectionSort(arrayOfInts);
elpased.Stop();
ticks.Add(elapsed.Elapsed.Ticks);
}
double avg = ticks.Average(); // create average of ticks
TimeSpan averageTimeSpan = new TimeSpan((long)avg); // cast needed from double to long
There is a little more elegant way to produce your random number array:
arrayOfInts = Enumerable.Range(0, count).Select(i => r.Next(numitems)).ToArray();
And because LINQ uses deferred execution you could even pre-declare this "query" and call ToArray() in the iteration:
List<long> ticks = new List<long>();
IEnumerable<int> randomQuery = Enumerable.Range(0, count).Select(i => r.Next(numitems));
for (int index = 0; index < iterations; index++)
{
//creates NEW random numbers each time, because of deferred execution
arrayOfInts = randomQuery.ToArray();
...
Another suggestion is to let the Stopwatch measure the whole time and divide the result by iterations. Stopwatches can be resumed:
IEnumerable<int> randomQuery = Enumerable.Range(0, count).Select(i => r.Next(numitems));
Stopwatch elapsed = new Stopwatch(); // only ONE instance needed
for (int index = 0; index < iterations; index++)
{
arrayOfInts = randomQuery.ToArray();
elapsed.Start(); // resumes without a reset
selectionSort(arrayOfInts);
elpased.Stop();
}
TimeSpan averageTimeSpan = new TimeSpan(elapsed.ElapsedTicks/iterations);

StopWatch gives random results

That is my first attempt to use StopWatch to meassure code performance and I don't know what is wrong. I want to check if there is difference when casting to double to calculate average with integers.
public static double Avarage(int a, int b)
{
return (a + b + 0.0) / 2;
}
public static double AvarageDouble(int s, int d)
{
return (double)(s + d) / 2;
}
public static double AvarageDouble2(int x, int v)
{
return ((double)x + v) / 2;
}
Code to test these 3 methods, using StopWatch:
Stopwatch sw = new Stopwatch();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
var ret = Avarage(2, 3);
}
sw.Stop();
Console.Write("Using 0.0: " + sw.ElapsedTicks + "\n");
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
var ret2 = AvarageDouble(2, 3);
}
sw.Stop();
Console.Write("Using Double(s+d): " + sw.ElapsedTicks + "\n");
sw.Reset();
sw.Start();
for (int i = 0; i < 1000000; i++)
{
var ret3 = AvarageDouble2(2, 3);
}
sw.Stop();
Console.Write("Using double (x): " + sw.ElapsedTicks + "\n");
It shows random result, once Average is the fastets, other time AverageDouble or AverageDouble2. I use diff variable names, but looks like it does not matter.
What am I missing?
PS. What is the best method to calculate average with two ints as inputs?
Tested your code, yes the results was very random at times. Remember Stopwatch is only the time elapsed from sw.start() to sw.stop(). It does not take into consideration .Net's Just In Time compilation, operating system process scheduling, cpu load etc.
This will be more noteworthy in methods with such small runtimes. Where these noises, can more then double the runtime.
An elaborate and better explanation is written in the following SO question.

Logging the time it takes to fill a LinkedList and Array

This Console-application is a bit strange but kinda funny, if it works. First, I'm clocking the time it takes to fill a LinkedList with 4.000.000 elements, with random numbers. Then I'm searching for 100 random elements in that LinkedList. And between this I'm writing out the time it took to fill and find the elements.
After that I'm trying to do the same thing again, but with an Array. First filling it, then looking for 100 random elements. And then I'm sorting the array, to see the difference between looking for 100 random elements in a unsorted vs sorted array. And then typing the time again.
The problem is, after I've filled the LinkedList, and found the elements in the LinkedList, I'm starting to fill the Array with a loop. And I get a infinite loop. I really don't know what's wrong ATM.
I suggest, if you want to help, that you copy the code I'm pasting into this question, so you understand how it should look for all the parts of the program.
Code:
public static bool sokning(int[] a, int b)
{
bool sant = false;
Random rand = new Random();
Stopwatch watchFindArray = new Stopwatch();
Console.Write("Letar efter tal: ");
watchFindArray.Start();
int myint = 0;
for (int iii = 0; iii < a.Length; iii++)
{
b = rand.Next();
Console.Write("#");
myint = Array.BinarySearch(a, b);
if (myint < 0)
{
sant = false;
}
else
{
sant = true;
}
}
watchFindArray.Stop();
if (sant == true)
{
Console.WriteLine("\nFann alla element efter " + watchFindArray.Elapsed.TotalSeconds + " sekunder.");
return true;
}
else
{
return false;
}
}
public static void körMetod()
{
const int MAX = 40000000;
int[] array = new int[MAX];
int hittamig2 = 0;
Random rand2 = new Random();
Stopwatch watchArray = new Stopwatch();
Console.WriteLine("\nStartar Array...");
watchArray.Start();
Console.Write("Position: ");
for (int ii = 0; ii < MAX; ii++)
{
array[ii] = rand2.Next();
if (array.Length % 1000000 == 0)
{
Console.Write("#");
}
}
watchArray.Stop();
Console.WriteLine("\nTid: " + watchArray.Elapsed.TotalSeconds + " sekunder att fylla en array.");
Console.WriteLine("Letar efter tal: ");
bool sant = sokning(array, hittamig2);
Console.WriteLine("Sorterar arrayen.");
Array.Sort(array);
sant = sokning(array, hittamig2);
if (sant == false)
{
Console.WriteLine("\nHittade inte alla element i arrayen.");
Console.ReadLine();
}
else
{
Console.WriteLine("Klar!");
Console.ReadLine();
}
}
static void Main(string[] args)
{
Random rnd = new Random();
const int MAX = 40000000;
LinkedList<int> lankadLista = new LinkedList<int>();
Stopwatch watchLinkedList = new Stopwatch();
Console.WriteLine("Startar LinkedList...");
watchLinkedList.Start();
Console.Write("Position: ");
for (int i = 0; i < MAX; i++)
{
lankadLista.AddLast(rnd.Next());
if (lankadLista.Count() % 1000000 == 0)
{
Console.Write("#");
}
}
watchLinkedList.Stop();
Console.WriteLine("\nTid: " + watchLinkedList.Elapsed.TotalSeconds + " sekunder att fylla en LinkedList.");
Stopwatch watchFindLinkedList = new Stopwatch();
int hittaMig;
Console.Write("Letar efter tal: ");
watchFindLinkedList.Start();
for (int j = 0; j < 100; j++)
{
hittaMig = rnd.Next();
Console.Write("#");
lankadLista.Find(hittaMig);
}
watchFindLinkedList.Stop();
Console.WriteLine("\nFann alla element efter " +
watchFindLinkedList.Elapsed.TotalSeconds + " sekunder.");
Console.ReadLine();
körMetod();
}
Best Regards.
You are not in an infinite loop, the problem is that it the following code:
for (int ii = 0; ii < MAX; ii++)
{
array[ii] = rand2.Next();
if (array.Length % 1000000 == 0)
{
Console.Write("#");
}
}
The inner condition is array.Length % 1000000 == 0 which is always true because the size of array is always 40000000 as you initialized it:
const int MAX = 40000000;
int[] array = new int[MAX];
When you are doing array[ii] = rand2.Next(); you are not changing the length of the array you are just setting one of its cells with a value equals to rand2.Next();.
This causes the Console.Write("#"); to work in every iteration and also slowing your loop dramatically.
To fix this, just change:
if (array.Length % 1000000 == 0)
to:
if (ii % 1000000 == 0)
You don't want to add new item at the end of the array every time because, resizing the array reallocates the array every time which is super slow but you can do it using the Array.Resize method (no reason for you to do it)
I think you have a big problem in the routine that searches the Array. (sokning)
Where is the code that searches for only 100 elements?
It seems that your are searching a random generated number for 40 millions times. Just fixing the Console.Write("#") to write correctly at every million point is not enough. I think that the big delay that let you think to have an infinite loop is in your code that search 40 millions of random generated numbers in an array of 40 millions of numbers
Of course this is not very "responsive" (considering also that you call this method two times)
public static bool sokning(int[] a, int b)
{
bool sant = false;
Random rand = new Random();
Stopwatch watchFindArray = new Stopwatch();
Console.Write("Letar efter tal: ");
watchFindArray.Start();
int myint = 0;
// Search only 100 numbers like you do in the linked list
for (int iii = 0; iii < 100; iii++)
{
b = rand.Next();
Console.Write("#");
myint = Array.BinarySearch(a, b);
if (myint < 0)
{
sant = false;
}
else
{
sant = true;
}
}
watchFindArray.Stop();
if (sant == true)
{
Console.WriteLine("\nFann alla element efter " + watchFindArray.Elapsed.TotalSeconds + " sekunder.");
return true;
}
else
{
return false;
}
}
There are also two minor problems.
Why passing the variable b inside the sokning method? The original value is never used and when you start the loop to search a random generated number the b variable os overwritten. So I think you could remove it
The second problem is the result of this sokning method. You set the sant variable to true or false at every loop. So the latest loop wins. In other words, if the latest loop finds a match you return true or false if not. If some previous loop has a different result, it is totally lost for the callers of sokning.

Trying to find the average amount of attempt it takes for Tom to roll a six on: 10 repetitions

It takes the total number of rolls and divides them by 10. For example, if it took 56 rolls so my average is 5.6.
Random numGen = new Random ();
int numOfAttempt = 0;
int Attempt = 0;
int avrBefore = 0;
int avrAfter = 0;
for (int i = 1; i <= 10; i++)
do {
Attempt = numGen.Next (1, 7);
Console.WriteLine (Attempt);
numOfAttempt++;
avrBefore = numOfAttempt;
avrAfter = avrBefore / 10;
} while (Attempt != 6);
Console.WriteLine ("He tried " + numOfAttempt + " times to roll a six.");
Console.WriteLine ("The average number of times it took to get a six was " + avrAfter);
Console.ReadKey ();
maybe you need to reset the vars inside the for loop, before the while:
for (int i = 1; i <= 10; i++){
int numOfAttempt = 0;
int Attempt = 0;
int avrBefore = 0;
int avrAfter = 0;
do {//your code
You are diving by ten at the wrong time.
You are dividing by ten even when you haven't done ten iterations.
This code below instead shows the correct average at each iteration.
void Main()
{
Random numGen = new Random ();
int totalAttempts = 0;
for (int i = 1; i <= 10; i++)
{
int attempts = 0;
int attempt = 0;
do {
attempt = numGen.Next (1, 7);
attempts++;
} while (attempt != 6);
totalAttempts+=attempts;
Console.WriteLine ("He tried " + attempts + " times to roll a six.");
Console.WriteLine ("The average number of times it took to get a six was " + (double)totalAttempts / i);
}
}
So you want to know how many times it took to get a six. This is quite simple. You just have to save how many times you rolled the dices and how many times you got a six.
Random numGen = new Random ();
int attempt = 0;
int numOfAttempt = 0;
int numberOfSixes = 0;
int i;
for (i = 0; i < 10; i++) {
do {
attempt = numGen.Next (1, 7);
Console.WriteLine (Attempt);
numOfAttempt++;
} while (Attempt != 6);
numberOfSixes++;
}
Console.WriteLine ("He tried " + numOfAttempt + " times to roll a six.");
Console.WriteLine ("The average number of times it took to get a six was " + (numberOfAttempt/numberOfSixes));
Console.ReadKey ();
I hope you understand my approach.
I would appreciate it if you could elaborate your thought process behind avrBefore,avrAfter and divide by 10. I didn't get that.
You can shorten down the code a lot and get it correct:
Random numGen = new Random();
int numOfAttempt = 0;
for (int i = 0; i < 10; i++)
{
int attempt = 0;
while (attempt != 6)
{
attempt = numGen.Next(1, 7);
Console.WriteLine (attempt );
numOfAttempt++;
}
}
Console.WriteLine("He tried " + numOfAttempt + " times to roll a six.");
Console.WriteLine("The average number of times it took to get a six was " + numOfAttempt / 10.0);
Console.ReadKey();

Which one is faster List<T> or ArrayList<T>? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
.NET: ArrayList vs List
Hello,
I searched around the web and find my conflicting answers and so far unclear as to,
Which one is faster List<T> or ArrayList<T> and what is the reason?
I am guessing List<T> should be faster but not sure as in this specific case even ArrayList<T> also is marked as a generic type.
Much Thanks,
Mani
I suppose you meant List<T> and ArrayList.
you should be using List<T> and not ArrayList because it doesn't have all the boxing\un-boxing.
I made this for you.
static void Main(string[] args)
{
Stopwatch sw = new Stopwatch();
Console.WriteLine("Adding a million 32bit integers");
sw.Start();
List<int> listA = new List<int>();
for(int i = 0; i < 1000000; i++)
{
listA.Add(i);
}
sw.Stop();
Console.WriteLine("List<int> took {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
List<object> listB = new List<object>();
for (int i = 0; i < 1000000; i++)
{
listB.Add(i);
}
sw.Stop();
Console.WriteLine("List<object> took {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
ArrayList listC = new ArrayList();
for(int i = 0; i < 1000000; i++)
{
listC.Add(i);
}
sw.Stop();
Console.WriteLine("ArrayList took {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
Console.WriteLine("\n Inserting 1000 values");
//Gen list of random numbers
Random rand = new Random(12345);
int[] insertlocs = new int[1000];
for (int i = 0; i < insertlocs.Length; i++)
insertlocs[i] = rand.Next(1, 999999);
sw.Start();
for (int i = 0; i < insertlocs.Length; i++)
{
listA.Insert(insertlocs[i], i);
}
sw.Stop();
Console.WriteLine("List<int> took {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < insertlocs.Length; i++)
{
listB.Insert(insertlocs[i], i);
}
sw.Stop();
Console.WriteLine("List<object> took {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
sw.Start();
for (int i = 0; i < insertlocs.Length; i++)
{
listC.Insert(insertlocs[i], i);
}
sw.Stop();
Console.WriteLine("ArrayList took {0} ms", sw.ElapsedMilliseconds);
sw.Reset();
Console.ReadKey();
}
On my comp, List<int> took 13ms, List<object> took 69ms, ArrayList took 40ms.
So there you have it, for reference types ArrayList is faster. But for value types you should obviously use List
EDIT: Testing insert performance too, List<int> took 255ms, List<object> took 723ms, ArrayList took 397ms. ArrayList with boxing is almost on par with List without boxing!
I'm guessing it depends, are you talking about lookups, inserts, etc?

Categories