Равновеликие массивы

Назавём две массивы равновеликими , если только один раз в одном из массивов, сменив места одной пары из элементов , мы получим другой массив. Например A = [1,2,3], B = [1,2,3] равновеликие, потому что они одинаковы и нет нужды эелементы поменят местами. И например массивы A = [2, 1, 3], B = [1, 2, 3] снова равномерны, паскольку в массиве A если поменять местами элементы A[0] и A[1] мы получим массив B. Или A = [1, 2, 2], B = [2, 1, 1] тем же принципом не равновеликие. Надо написать функцию, который получает матрицу [A, B] и проверяет массивы A и B раномерные или нет? (true/ false).

function solution(x) {
    let a = []
    let b = []
    x = [a,b]
    let flag = a.some((value, index) => {
        let checkIndex = b.indexOf(value);
        if (checkIndex === -1) return true;
        if (a[checkIndex] !== b[index]) return true;
        let temp = b[index];
        b[index] = a[index];
        b[checkIndex] = temp;
    })
    return !flag
};


console.log(solution([1, 2, 3], [1, 2, 3]));   // Должен вернуть true
console.log(solution([1, 2, 3], [2, 1, 3]));   // Должен вернуть true
console.log(solution([1, 2, 2], [2, 1, 1]));   // Должен вернуть false
console.log(solution([1, 1, 4], [1, 2, 3]));   // Должен вернуть false
console.log(solution([1, 2, 3], [1, 10, 2]));  // Должен вернуть false
console.log(solution([3, 3, 3], [3, 3, 3]));   // Должен вернуть true
console.log(solution([832, 998, 148, 570, 533, 561, 894, 147, 455, 279],
                     [832, 998, 148, 570, 533, 561, 455, 147, 894, 279]));  // Должен вернуть true
console.log(solution([832, 998, 148, 570, 533, 561, 894, 147, 455, 279],
                     [832, 998, 148, 570, 894, 461, 455, 147, 533, 179]));  // Должен вернуть false
console.log(solution([4, 5, 6], [9, 8, 7])); // Должен вернуть false
console.log(solution([0], [0]));  // Должен вернуть true
console.log(solution([832, 998, 148, 570, 533, 561, 894, 147, 455, 279],
                     [832, 570, 148, 998, 533, 561, 455, 147, 894, 279]));  //Должен вернуть false

Пожалуйста, помогите решить задачу верно


Ответы (2 шт):

Автор решения: Yaant

Подозреваю, что можно и попроще, но думать дальше уже лень: :)

function solution(x) {
  let [a, b] = x;
  if (a.length !== b.length) return false;
  let count = 0;
  let index;
  for (let i = 0; i < a.length; i++) {
    if (a[i] != b[i]) {
      if (++count > 2) return false;
      if (index === undefined) {
        index = i
      } else {
        if (a[i] !== b[index] || a[index] !== b[i]) 
          return false;
      }
    }
  }
  return true;
};


console.log(solution([[1, 2, 3], [1, 2, 3]]));   // Должен вернуть true
console.log(solution([[1, 2, 3], [2, 1, 3]]));   // Должен вернуть true
console.log(solution([[1, 2, 2], [2, 1, 1]]));   // Должен вернуть false
console.log(solution([[1, 1, 4], [1, 2, 3]]));   // Должен вернуть false
console.log(solution([[1, 2, 3], [1, 10, 2]]));  // Должен вернуть false
console.log(solution([[3, 3, 3], [3, 3, 3]]));   // Должен вернуть true
console.log(solution([[832, 998, 148, 570, 533, 561, 894, 147, 455, 279],
                     [832, 998, 148, 570, 533, 561, 455, 147, 894, 279]]));  // Должен вернуть true
console.log(solution([[832, 998, 148, 570, 533, 561, 894, 147, 455, 279],
                     [832, 998, 148, 570, 894, 461, 455, 147, 533, 179]]));  // Должен вернуть false
console.log(solution([[4, 5, 6], [9, 8, 7]])); // Должен вернуть false
console.log(solution([[0], [0]]));  // Должен вернуть true
console.log(solution([[832, 998, 148, 570, 533, 561, 894, 147, 455, 279],
                     [832, 570, 148, 998, 533, 561, 455, 147, 894, 279]]));  //Должен вернуть false

→ Ссылка
Автор решения: teran

проходите по первому массиву, считайте количество каждых значений. Проходите по второму массиву, вычитайте найденные элементы. Если в конце останутся не нули, то массивы различны.

function check(m){
   const [a, b] = m;
   if(a.length != b.length) return false;
   
   var r   = a.reduce((acc, v) => (acc[v] = (acc[v] || 0)+1, acc), {});
   var res = b.reduce((acc, v) => (acc[v] = (acc[v] || 0)-1, acc), r);
   return !Object.values(res).some(v => v);   
}


console.log(check([[1,2,3], [1,2,3]]));    //true
console.log(check([[1,2,3], [1,2,4]]));    //false
console.log(check([[1,1,2], [1,2,1]]));    //true 
console.log(check([[1], []]));             //false
console.log(check([[1,2,3,4],[2,1,4,3]])); //false 

приведенный выше код не учитывает то, что перестановка элементов может быть только одна.

вариант ниже: проходим по массивам, сравниваем элементы. если различаются, заносим их в массив расхождений. По итогу, если расхождений нет, то массивы одинаковы. Для одной перестановки нам нужно 2 различия, так что если длина не равно двум, то false. И если длина получалась два, то сравниваем соответствуют ли перемещаемые элементы.

function check(m){
  const [a,b] = m;
  if(a.length != b.length)  return false;
  
  let d = [];
  a.forEach(function(v,idx){
                if(v != b[idx]) d.push({a: v, b: b[idx]});
             }, {});
  
  if(d.length == 0) return true;
  if(d.length != 2) return false;        
    
  return d[0].a == d[1].b && d[0].b == d[1].a;
  
}


console.log(check([[1,2,3], [1,2,3]]));    //true
console.log(check([[1,2,3], [1,2,4]]));    //false
console.log(check([[1,1,2], [1,2,1]]));    //true 
console.log(check([[1], []]));             //false
console.log(check([[1,2,3,4],[2,1,4,3]])); //false 

→ Ссылка