0

I was attempting the hallenge/problem as below in HackerRank. (You don't have to sign in to view the problem, for those who don't wish to view it via the link I'll write a briefly about the problem statement).

https://www.hackerrank.com/challenges/time-conversion

Given a specified input (string) of date (02:34:50PM) in AM/PM format, I had to convert it into military time (14:34:50). Midnight in Military is 00:00:00 and in AM/PM format is 12:00:00AM as for Afternoon in Milatary is 12:00:00 and in AM/PM format is 12:00:00PM.

Now the approach I used was checking the 2nd last value of the string since the input format was specified. B/c I only need to change the hours I only take the 0th and 1st index of string convert it into double using "GetNumericValue".

Now when I use the values of these doubles in my IF statement (in the PM if block) they fail if I check for "!=". I've given the code below. After using the debugger and seeing what happens it completely forgoes the IF statement containing the "!=". This happens if my input has "1" in its first index or has "2" in its 2nd index.

At first I was thinking that it might be an issue with the precision of double with such a small number, however, my code gives the right answer if the input "01:xx:xxPM". So I'm inclined to think its the logic of my IF statement, though I've stared at it for so long and I have no idea why it won't work. I gave the alternate piece of code I wrote that worked. I essentially did the same thing except I used "==" and an else statement (before I was using "!=" and an else statement)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace HackerRank_Algorithms
{
    class Time_Conversion
    {
        static void Main(string[] args)
        {

            //Reading input Date in the format "02:34:50PM"
            string time = Console.ReadLine();
            //Creating a double array for storing the first digits that is the hours
            //used double since 'GetNumericValue' returns type double
            double[] timeIn24 = new double[2];
            //loop to convert the first two digits from string into double 
            for (int x = 0; x < 2; x++)
            {
                timeIn24[x] = char.GetNumericValue(time, x);
            }

            //Because I know the date will always be in a specified format I check at the place for
            //'P' or 'A' for AM or PM 
            //If PM then do this
            if (time[time.Length-2] == 'P')
            {
                //Console.WriteLine("Time is PM");

                /********************************************
                //I tried doing this since but didn't work
                //timeIn24[1] = Convert.ToInt32(timeIn24[1]);
                //timeIn24[0] = Convert.ToInt32(timeIn24[0]);
                *********************************************/

                //Console.WriteLine("Before {0} timeIn24[0]", timeIn24[0]);
                //Console.WriteLine("Before {0} timeIn24[1]", timeIn24[1]);


                //PROBLEM OCCURRING HERE I check if its 12PM or not if it isn't then I do the follwoing
                if (timeIn24[1] != 2 && timeIn24[0] != 1)
                {
                    //add 2 to the unit of hours
                    timeIn24[1] = timeIn24[1] + 2;

                    //Console.WriteLine("After addition {0} timeIn24[0]", timeIn24[0]);

                    //if the sum i get is greater than 10 that is I'm getting a carry
                    if (timeIn24[1] > 9)
                    {
                        //I add one to the tenth of hours
                        timeIn24[0] = timeIn24[0] + 1;
                        //Modulus to get the last digit of unith hour
                        timeIn24[1] = timeIn24[1] % 10;
                    }
                    timeIn24[0] = timeIn24[0] + 1;
                    Console.Write("{0}{1}", timeIn24[0], timeIn24[1]);


                    //Console.WriteLine(timeIn24[0]);
                    //Console.WriteLine(timeIn24[1]);
                }
                else //if its 12PM then I do not do anything and I print it as is
                {
                    Console.Write("{0}{1}", timeIn24[0], timeIn24[1]);
                }

                /***********CODE THAT GAVE THE CORRECT SOLUTION******************/
                //if (timeIn24[1] == 2 && timeIn24[0] == 1)
                //{
                //    Console.Write("{0}{1}", timeIn24[0], timeIn24[1]);


                //    //timeIn24[0] = timeIn24[0] / 10; 
                //    //Console.WriteLine(timeIn24[0]);
                //    //Console.WriteLine(timeIn24[1]);
                //}
                //else
                //{
                //    timeIn24[1] = timeIn24[1] + 2;
                //    //Console.WriteLine("After addition {0} timeIn24[0]", timeIn24[0]);
                //    if (timeIn24[1] > 9)
                //    {
                //        timeIn24[0] = timeIn24[0] + 1;
                //        timeIn24[1] = timeIn24[1] % 10;
                //    }
                //    timeIn24[0] = timeIn24[0] + 1;
                //    Console.Write("{0}{1}", timeIn24[0], timeIn24[1]);
                //}
                /******************************************************************/

                //Here I simply start from the first colon and print the date as string till end
                int y = 2;
                while( y < time.Length-2)
                {
                    Console.Write("{0}", time[y]);
                    y++;
                }
            }
            else //if its AM
            {
                //if its 12AM that is Midnight
                if (timeIn24[0] == 1 && timeIn24[1] == 2)
                { //set both tenth and unit of hour to 0
                    timeIn24[0] = 0;
                    timeIn24[1] = 0;
                }
                //print the hours
                Console.Write("{0}{1}", timeIn24[0], timeIn24[1]);

                //again print from first colon + the remaining of string
                int x = 2;
                while ( x < time.Length-2)
                {
                    Console.Write("{0}", time[x]);
                    x++;
                }
            }

            Console.ReadLine();
        }
    }
}
  • 1
    You need to compare double values using epsilon and not just == or != or >= or <=, etc.. See: Comparing Floats and Doubles with Epsilon. http://stackoverflow.com/questions/2411392/double-epsilon-for-equality-greater-than-less-than-less-than-or-equal-to-gre and http://floating-point-gui.de/errors/comparison/ – Brandon Feb 21 '17 at 18:07
  • 1
    I think you'll have more success working with .NET's build in `DateTime` type. https://msdn.microsoft.com/en-us/library/system.datetime(v=vs.110).aspx – maniak1982 Feb 21 '17 at 18:07
  • 2
    There is a lot of long winded academic stuff going on. Does the hacker program disallow built in functions? There should be user validation like `TryParse`. And you already have 24 hr format `date.ToString("HH:mm:ss")`. – P.Brian.Mackey Feb 21 '17 at 18:13
  • No the hacker program doesn't disallow inbuilt functions. I wanted to try building my own logic because usually in my school setting they disallow the usage of inbuilt functions. So for purposes of learning I implemented my logic instead of using the inbuilt functionality. But yes agreed I'll definitely would have more success with the inbuilt functionality. – Haroon Ramay Feb 21 '17 at 18:30

1 Answers1

0

The issue is indeed with the if statement. Think about using 10:00:00AM as your input. In this case, timeIn24[1] != 2 will evaluate to true (since the second digit is 0, not 2), but the second part, timeIn24[0] != 1, will evaluate to false because the first digit is indeed 1. Since you're using &&, both sides need to evaluate to true in order to enter the if statement.

If you use || (or) instead of && (and), the if statement should work correctly, because if either digit isn't equal to the right value, the code will enter the if block.

Of course, like others have noted, unless it's specifically prohibited by the challenge, it'd be much simpler to just use the built-in DateTime type.

A. Damond
  • 152
  • 1
  • 8