Symmetric Difference

Symmetric Difference
0

#1

Hello guys, i’m trying to finish the Symmetric Difference challenge but i can’t seem to go anywhere.

I’ve tried every approach i could think of but i can’t seem to find the solution, and i’m starting to get actually stressed from this.

My approach is the following:

  • Create an array from the arguments, containing every “set”.
  • Reduce the array by comparing the accumulator to the current item, if it matches, remove the element from both arrays.
  • Concatenate the accumulator to the current item.

No matter what i do, i can’t seem to get it right, what should i do?


#2

Try to first state and solve the problem using everyday language avoiding programming terms - use paper and pencil if possible

In everyday terms the problem is there are two lists of numbers - we have to find numbers that are unique to each list

The first test case is:

list 1: 1, 2, 3
list 2: 5, 2, 1, 4

The answer is:

3, 4, 5

How would you do this if you did not know any programming? Come up with one solution no matter how clunky or inefficient just as long as it is deterministic and is always guaranteed to give the right answer.

Once you post your solution in everyday language we can think about how to express it in code


#3

Yeah, i just read the solution out of frustration and… it was basically what i did but i did make the mistake of not creating a new Array.

I feel like i have cheated though.

EDIT:
Also, i had already defined problem and solution with everyday language, but i did not think of using a third array to store the elements.


#4

Even if you do the exercise yourself it is a very good idea to look at the hint. The hint usually shows several different solutions. There is a lot you can learn from figuring out how each one works.


#5

Hi, I’m having a little trouble deleting repeated elements. For example, if I start with this array
[[3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]], I’d like to delete the repeated 3s and 6s and get the following array back
[[3, 2, 5], [2, 1, 5, 7], [3, 4, 6], [1, 2, 3]] but instead I get the following array
[[3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]] which still unfortunately contains a repeated 6. I can’t seem to spot the code responsible for this, or what I should change - here’s my code below:

function sym() {
  var args = Array.from(arguments);
  for (var i = 0; i < args.length; i++) {
    for (var j = 0; j < args[i].length; j++) {
      while (args[i].indexOf(j) !== args[i].lastIndexOf(j)) {
        args[i].splice(args[i].lastIndexOf(j),1);       
      }
    }//now we should have deleted all the repeats from all the sets
  }
  return args;
}

sym([3, 3, 3, 2, 5], [2, 1, 5, 7], [3, 4, 6, 6], [1, 2, 3]);

Thanks in advance for your help.


#6

A few comments

arguments is array-like - there is no need to convert it to another array just for indexing

You probably want indexOf a value in an array not of another index like j

It’s generally not a good idea to modify the array a loop iterates over - the array length is affected - it’s usually wrong and very confusing at a minimum - instead create and modify a different array to store results

this is another problem that benefits from an initial solution in everyday language - write these lists of numbers on paper and ask yourself how repeated values can be identified and removed


#7

Thank you! That is something I hadn’t noticed! I amended it with the following code:

while (args[i].indexOf(args[i][j]) !== args[i].lastIndexOf(args[i][j])) {
        args[i].splice(args[i].lastIndexOf(args[i][j]),1);

And then, since you mentioned that arguments is array-like, I can also try,

for (var i = 0; i < arguments.length; i++) {
    for (var j = 0; j < arguments[i].length; j++) {
      while (arguments[i].indexOf(arguments[i][j]) !== arguments[i].lastIndexOf(arguments[i][j])) {
        arguments[i].splice(arguments[i].lastIndexOf(arguments[i][j]),1);       
      }//delete any repeated elements in a set
    }//now we've deleted all the repeats from all the sets
  }
  
  var myArr = arguments.reduce(function(a, c) {

but that threw an error saying that “arguments.reduce() is not a function”, so I kept the arguments assigned to a new array, like it originally was, and now it works yay!! Thank you very much.

function sym() {
  var args = Array.from(arguments);
  for (var i = 0; i < args.length; i++) {
    for (var j = 0; j < args[i].length; j++) {
      while (args[i].indexOf(args[i][j]) !== args[i].lastIndexOf(args[i][j])) {
        args[i].splice(args[i].lastIndexOf(args[i][j]),1);       
      }//delete any repeated elements in a set
    }//now we've deleted all the repeats from all the sets
  }
  
  var myArr = args.reduce(function(a, c) {
    return a.concat(c);
  });
  
  var symDiffArr = [];
  var parityArr = [];
  var k = 0;
    
  while (myArr.length > 0) {
    var lenAtStart = myArr.length;
    symDiffArr[k] = myArr.shift();
    myArr = myArr.filter(function(v) {
      return v !== symDiffArr[k];
    });
    parityArr[k] = lenAtStart - myArr.length;
    k++;
  }
  
  var resultArr = symDiffArr.filter(function(w, idx) {
    return parityArr[idx] % 2 !== 0; //return true i.e. return odd parities
  });
  return resultArr;
}

sym([3, 3, 3, 2, 5], [2, 1, 1, 5, 7], [3, 4, 6], [1, 2, 3]);

#8

Glad you got it working!

yes - array-like unfortunately means it is not an array - it supports indexing and length but not general array methods - maybe array-unlike is a better term - but the idea is there should be no need to use array functions on arguments