Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Minimum number of digit changes to get two arrays to have the same value

I am pretty new to coding and I'm trying my best, but after hours and hours of research i still cant figure this out. I'm trying to make these two separate arrays the same with the minimum number of moves. I can only ++ or -- one number at a time.

This is the challenge:

No reordering of the digits is allowed For example, consider two arrays: Andrea's [123, 543] and Maria's [321, 279]. For the first digit, Andrea can increment the 1 twice to achieve 3. The 2's are equal already. Finally, she decrements her 3 twice to equal 1. It took 4 moves to reach her goal. For the second integer, she decrements 5 three times, increments 4 three times and 3 six times. It took 12 moves to convert the second array element. In total, it took 16 moves to convert both values comprising the complete array.

let a = [1234, 4321]
let m = [2345, 3214]

function minimumMoves(a, m) {
    // Write your code here
    let numMoves = 0;
    let num1 = '' ;
    let num2 = '' ;
    let digit1 = '';
    let digit2= '';
    for (let i = 0; i < a.length; i++)
    {
        num1 = a[i]; 
        while (num1 != 0) {
            digit1 = num1 % 10; 
            digit2 = num2 % 10; 
            num1 = Math.trunc(num1 / 10); 
            num2 = Math.trunc(num2 / 10);
            numMoves = numMoves + Math.abs(digit1 - digit2);

        }
    }
    return numMoves
}
like image 771
zrwhite151 Avatar asked Oct 18 '25 01:10

zrwhite151


2 Answers

For getting only the count for changina a string of digits to another, you could add the absolute delta of the digits at a place.

function count(a, b) {
    return Array.from(a).reduce((s, v, i) => s + Math.abs(v - b[i]), 0);
}

console.log(count('123', '321'));
like image 86
Nina Scholz Avatar answered Oct 19 '25 15:10

Nina Scholz


In my opinion you should make a function that effectively takes a single digit and while it is greater than the other number aka needs to be decremented it does that:

const incrementWhileNeeded = (target, currentValue) =>
  Math.abs(target - currentValue)

Then, you need split the numbers into their digits (you can do this the mathematical way using % like it looks like you've done, but just for simplicity something like: String(num1).split('').map(Number) will take 451 and change it to [4, 5, 1].

Then, your next step is to map that function (incrementWhileNeeded) to each individual digit: just focus on the first number (and then apply forEach or .map to apply that function to all of them.

So that will look something like: firstNumberArray.map(incrementWhileNeeded)

Which will respond with as you explained [1, 0, 2].

Then .reduce() this so that you can get the sum of the counts. So this will reduce using [1,0,2].reduce((accumulator, current) => accumulator + current) to 3.

So for the full functionality:

const incrementWhileNeeded = (target, currentValue) =>
      Math.abs(target - currentValue)

const calculateMinimumMoves = (fullNumber, targetNumber) => {
      const numArray = String(fullNumber).split('').map(Number)
      const targetArray = String(targetNumber).split('').map(Number)
      const diffArray = numArray.map((currentElement, targetArray[index]) => incrementWhileNeeded(currentElement, targetArray[index])
      return diffArray.reduce((accumulator, current) => accumulator + current, 0)
}

const minimumMoves = (array1, array2) =>
      array1.reduce((accumulator, current, index) =>
            accumulator + calculateMinimumMoves(current, array2[index]),
            0)
like image 40
Zargold Avatar answered Oct 19 '25 14:10

Zargold