Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Find Minimum Possible difference between numbers with unknown digits

I have some cases as follows.

  • 1? 2?
  • ?2? ??3
  • ? ?
  • ?5 ?0

Now what I am supposed to do is to find some values in place of question marks, that would give produce the minimum possible difference between the 2 numbers.

Answers Should be like

  • 19 20

  • 023 023

  • 0 0

  • 05 00

Note : the number which will be produced after the minimum absolute difference between the 2 values must be smallest. As in, the last case could be 15 and 10 with the absolute difference to be 5 but it is invalid.

I tried some permutation combination ideas for replacing the question marks for both numbers individually and then find out the number but the length of the number could go up to 18 digits per number. Hence I believe it wouldn't be a good idea.

Then I tried to search for similar questions but that didn't help. I still think that regex could be helpful to solve this question but am stuck with how to do it.

Any help is welcome!! Thanx!

The language shall be Php.. I am working with Php.

like image 872
Tirthraj Rao Avatar asked Nov 03 '16 07:11

Tirthraj Rao


1 Answers

Okay, I got a solution.

Explanation:

Uses regex to grab the two numbers, then compares them in pairs from left to right, starting with the assumption they're equal. Meaning they both resolve to the same number wherever possible, or 0 if they are both ?.

After there is a pair of numbers that aren't equal, it starts setting the lower ones ?'s to 9, and the higher ones ?'s to 0, to make them as close as possible.

Here is an example of it in action.

function minDiff($str) {
    preg_match("/([\d\?]+) ([\d\?]+)/", $str, $matches);
    
    $first = $matches[1];
    $second = $matches[2];
    
    $biggest = 0; // -1 = first, 0 = none, 1 = second
    
    $firstResult = 0;
    $secondResult = 0;
    
    for ($i = 0; $i < strlen($first); $i++) {
        $powerValue = strlen($first) - $i - 1;
        if ($biggest != 0) { // not equal
            if (!strcmp($first[$i], '?') && !strcmp($second[$i], '?')) {
                if ($biggest > 0) { // second is biggest
                    $firstResult += 9 * pow(10, $powerValue);
                } else { // first is biggest
                    $secondResult += 9 * pow(10, $powerValue);
                }
            } elseif (!strcmp($first[$i], '?')) {
                if ($biggest > 0) { // second is biggest
                    $firstResult += 9 * pow(10, $powerValue);
                }
                $secondResult += $second[$i] * pow(10, $powerValue);
            } elseif (!strcmp($second[$i], '?')) {
                if ($biggest < 0) { // first is biggest
                    $secondResult += 9 * pow(10, $powerValue);
                }
                $firstResult += $first[$i] * pow(10, $powerValue);
            } else {
                $firstResult += $first[$i] * pow(10, $powerValue);
                $secondResult += $second[$i] * pow(10, $powerValue);
            }
        } else { // both equal (so far)
            if (!strcmp($first[$i], '?')) {
                $firstResult += $second[$i] * pow(10, $powerValue);
                $secondResult += $second[$i] * pow(10, $powerValue);
            } elseif (!strcmp($second[$i], '?')) {
                $firstResult += $first[$i] * pow(10, $powerValue);
                $secondResult += $first[$i] * pow(10, $powerValue);
            } else {
                if (intval($first[$i]) > intval($second[$i])) {
                    $biggest = -1;
                } elseif (intval($first[$i]) < intval($second[$i])) {
                    $biggest = 1;
                }
                $firstResult += $first[$i] * pow(10, $powerValue);
                $secondResult += $second[$i] * pow(10, $powerValue);
            }
            
            // Find if next number will change
            if (($i + 1) < strlen($first) && strcmp($first[$i + 1], '?') && strcmp($second[$i + 1], '?')) {
                $diff = preg_replace('/\?/', '0', substr($first, $i + 1)) - preg_replace('/\?/', '0', substr($second, $i + 1));
                echo "$diff\n";
                // Check to see if you need to add 1 to the value for this loop
                if ($diff > pow(10, $powerValue) / 2) {
                    $secondResult += pow(10, $powerValue);
                    $biggest = 1;
                } elseif ($diff < pow(10, $powerValue) / -2) {
                    $firstResult += pow(10, $powerValue);
                    $biggest = -1;
                }
            }
        }
    }
    
    echo "first: ".str_pad($firstResult, strlen($first), "0", STR_PAD_LEFT)."\n";
    echo "second: ".str_pad($secondResult, strlen($second), "0", STR_PAD_LEFT)."\n\n";
}
like image 83
Addison Avatar answered Oct 29 '22 13:10

Addison