Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Stopwatch in C#

Tags:

c#

stopwatch

Does anyone know how I can add a timer function to this code that solves sudoku puzzles? I've tried the Stopwatch class but I can't get it to work because I don't know exactly where to put it. I've tried several places but always get errors. The main purpose of the code works but I'd like to add a timer function to see how long the code ran for.

using System;

namespace SuDoKu
{
  public class SuDoKu
  {
    private int[,] grid;

    public SuDoKu()
    { 
        grid = new int[9, 9];
    } 
     static void Main(string[] args)
     {
        SuDoKu sdk = new SuDoKu();

        int[,] grd = {
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
                     { 0, 0, 0, 0, 0, 0, 0, 0, 0 } };

        for(int i = 0; i < 9; i++)
            for(int j = 0; j < 9; j++)
                sdk.EnterToGrid(grd[i, j], new Point(i, j));

        Console.WriteLine("Original Grid"); 

        sdk.Display(); 

        sdk.Solve(sdk.NextAvailableCell(), new Point()); 

        Console.WriteLine("\n\n\nSolved Grid"); 

        sdk.Display(); 

        Console.WriteLine();
    }

    public void Display()
    {
        for(int i = 0; i < 9; i++)
        {
            Console.WriteLine();

            for(int j = 0; j < 9; j++)
            {
                if(ShowFromGrid(new Point(i, j)) == 0) {
                    Console.Write("0 ");
                }
                else
                {
                    Console.Write(ShowFromGrid(new Point(i, j)) + " ");
                }

                if(j == 2 || j == 5)
                {
                    Console.Write("| ");
                }
            }
            if(i == 2 || i == 5) {

                Console.Write("\n------|-------|------ ");
            }
        }
    }
    public void EnterToGrid(int num, Point pos) {
        grid[pos.X, pos.Y] = num;
    }

    public int ShowFromGrid(Point pos) {
        return grid[pos.X, pos.Y];
    }

    public void Solve(Point pos, Point prevPos) {

        if(pos.X < 9 && pos.Y < 9)
        {
            Point posPrev = new Point();

            if(grid[pos.X, pos.Y] == 0)
            {
                for(int i = 1; i <= 9; i++)
                {
                    if(IsThisNumberPossibleInTheGrid(i, pos))
                    {
                        grid[pos.X, pos.Y] = i;

                        posPrev.X = pos.X;

                        posPrev.Y = pos.Y;

                        Point posNext = NextAvailableCell();

                        if(!posNext.Equals(new Point()))

                            Solve(posNext, posPrev);
                    }
                }
                if(grid[pos.X, pos.Y] == 0)
                {
                    if(!prevPos.Equals(new Point()))

                        grid[prevPos.X, prevPos.Y] = 0; 

                    return;
                }
            }
        }
        else
        {
            Point posNext = NextAvailableCell();

            if(!posNext.Equals(new Point()))
                Solve(posNext, pos);
        }
    }

    public Point NextAvailableCell()
    {
        for(int i = 0; i < 9; i++)
            for(int j = 0; j < 9; j++)
                if(grid[i, j] == 0)
                    return new Point(i, j);

        return new Point();
    }

    public bool IsThisNumberPossibleInTheGrid(int num, Point pos) {

        if(IsThisNumberPossibleInTheBlock(num, pos))
        {
            for(int i = 0; i < 9; i++)
            {
                if(grid[i, pos.Y] == num && pos.X != i)
                {
                    return false;
                }

                if(grid[pos.X, i] == num && pos.Y != i)
                {
                    return false;
                }
            }
            return true;
        }
        return false;
    }

    public bool IsThisNumberPossibleInTheBlock(int num, Point pos)
    {
        Point Grid = new Point();

        Grid.X = (pos.X >= 0 && pos.X <= 2) ? 0 : ((pos.X >= 3 && pos.X <= 5) ? 3 : ((pos.X >= 6 && pos.X <= 8) ? 6 : -1));
        Grid.Y = (pos.Y >= 0 && pos.Y <= 2) ? 0 : ((pos.Y >= 3 && pos.Y <= 5) ? 3 : ((pos.Y >= 6 && pos.Y <= 8) ? 6 : -1));

        if(!Grid.Equals(new Point()))
        {
            for(int i = Grid.X; i < Grid.X + 3; i++)
            {
                for(int j = Grid.Y; j < Grid.Y + 3; j++)
                {
                    if(grid[i, j] == num && !pos.Equals(new Point(i, j)))
                        return false;
                }
            }
            return true;
        }
        return false;
    }
}

  public class Point
  {
    public int X;

    public int Y;

    public Point()
    {
        this.X = -1;
        this.Y = -1;
    }

    public Point(int x, int y)
    {
        this.X = x;
        this.Y = y;
    }

    public bool Equals(Point p)
    {
        return (this.X == p.X && this.Y == p.Y) ? true : false;
    }
  }
}
like image 385
PRO_grammer Avatar asked Apr 15 '19 10:04

PRO_grammer


2 Answers

The Stopwatch object is often used to (as you do here), measure how long things take. One quick thing to remember here is that it will take the time for everything you do between starting and stopping it, so make sure you only put the actual code you want to time between those.

using System.Diagnostics;  //... void StopwatchUsingMethod() {   //A: Setup and stuff you don't want timed   var timer = new Stopwatch();   timer.Start();    //B: Run stuff you want timed   timer.Stop();    TimeSpan timeTaken = timer.Elapsed;   string foo = "Time taken: " + timeTaken.ToString(@"m\:ss\.fff");  } 

Foo will here show the minutes, seconds, and milliseconds it took to complete, though will show as wrong if it takes more than 59 minutes. Further information about TimeSpan can be found here: https://docs.microsoft.com/en-us/dotnet/standard/base-types/custom-timespan-format-strings

If I understand your code correctly, you want to put everything up to and including the first sdk.Display(); line in the A section and only put the call to Solve in the B section, so something like

static void Main(string[] args) {   //...   sdk.Display();   var timer = new Stopwatch();    timer.Start();   sdk.Solve(sdk.NextAvailableCell(), new Point());   timer.Stop();    Console.WriteLine("\n\n\nSolved Grid");    //...you can use the time taken here } 
like image 59
Stian A. Sætrang Avatar answered Sep 18 '22 22:09

Stian A. Sætrang


"The main purpose of the code works but I'd like to add a timer function to see how long the code ran for"

For this you can use System.Diagnostics.Stopwatch(https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.stopwatch?view=netframework-4.7.2). If you want to see how long a function takes to execute, add stopWatch.Start() before and stopWatch.Stop() after the function calls. You can now see total time it took(in seconds/milliseconds etc) using stopWatch.Elapsed, according to your convenience.

like image 36
afrose Avatar answered Sep 20 '22 22:09

afrose