0

I have 3 inputs which take 3 digits each. My code then combines all of the numbers into 1 array. [1,2,3,4,5,6,7,8,9] in this case. I just want to output every pair starting with the first digit excluding double digits, repeated pairs, or reversed pairs. So I would want it to look something like:

12

13

14 etc.

but if 12 is already a pair inside the array then 21 would not be added. ( reversed pairs ). Double digits like 55 would not be added as well as repeat pairs ( any pair would not be entered twice ).

Any ideas on the direction I should take?

var button = document.querySelector( 'button' );
button.addEventListener( 'click', clicked );

function clicked() {
 var output = document.getElementById( 'output' );
  
  var first = document.getElementById( 'first' );
  var second = document.getElementById( 'second' );
  var third = document.getElementById( 'third' );
  
  var first = first.value.split( '' );
  var second = second.value.split( '' );
  var third = third.value.split( '' );
  
  var numGroup = first.concat( second );
  numGroup = numGroup.concat( third );
  
  //alert( numGroup );
  
  output.innerHTML = '';
  
  var i = 0;
  var j = 0;
  
  for( i; i < numGroup.length; i++ ){
   for( j; j < numGroup.length; j++ ){
    output.innerHTML += numGroup[ i ] + numGroup[ j ] + '<br>';
   }
  }
}
* {
  box-sizing: border-box;
}
html {
  font-family: Arial;
  letter-spacing: 0.1rem;
}
.controls {
  display: flex;
}
input {
  font-size: 2rem;
  letter-spacing: 0.125rem;
  padding: 0.5rem;
  width: 4.75rem;
  margin-right: 1rem;
}
button {
  height: 4.5rem;
  width: 4.75rem;
  text-transform: uppercase;
  padding: 8px;
  background: black;
  border: none;
  color: white;
  cursor: pointer;
}
button:hover {
  outline-color: aqua;
  outline-width: 2px;
  outline-style: solid;
  outline-offset: 1px;
}
.output {
  background-color: #eee;
  padding: 1rem;
  margin-top: 1rem;
  width: 22rem;
}
<div class="controls">
  <input type="text" maxlength="3" id="first" value="123">
  <input type="text" maxlength="3" id="second" value="456">
  <input type="text" maxlength="3" id="third" value="789">
  <button>submit</button>
</div>

<div class="output" id="output">
  output
</div>

EDIT: As far as I'm aware this is a question about the possible combinations and not permutations.

Lynel Hudson
  • 2,335
  • 1
  • 18
  • 34

1 Answers1

0

If I understood the problem, it seems like for each item in the array, you want to pair it with all the items following it. This avoids repeating pairs (including reversed ones) as well as doubles.

To do this, you can use .reduce() to put together the resulting array. On each iteration, you'll have the current number, and then you just need to slice the original array from one after the current index forward to get all the ones that should be paired with it.

So you take the sub-slice after the current index, you .map() it, returning the pairing of the outer number with the current one from the .map() callback, and concat the mapped array to the .reduce result.

All this takes only a few lines of code.

const arr = [1,2,3,4,5,6,7,8,9];

const res = arr.reduce((res, n, i, arr) =>
  res.concat(arr.slice(i+1).map(nn => "" + n + nn))
, [])

console.log(res);

For the clarified requirements, eliminate any duplicates in the original data set early. You can use the example provided by trincot in the comments.

const arr = [...new Set([1,2,3,4,5,5,6,3,7,8,9])];

const res = arr.reduce((res, n, i, arr) =>
  res.concat(arr.slice(i+1).map(nn => "" + n + nn))
, []);

String.prototype.reverse = function() {   this.split("").reverse().join("")
}

console.log("No doubles, dupes or reverse dupes?", 
  res.every(s =>
    res.indexOf(s) === res.lastIndexOf(s) &&
    res.indexOf(s.reverse()) === -1 &&
    s !== s.reverse()
  )
);

console.log(res);
  • Awesome answer. It would be helpful in understanding how this works, if the variable names were a bit more verbose though. – ryanpcmcquen Jan 22 '18 at 21:02
  • 2
    Add `arr = [...new Set(arr)];` to ensure there are no duplicates. – trincot Jan 22 '18 at 21:02
  • Am still getting some duplicates under modified base array https://jsfiddle.net/5gbfvpLf/ – Lynel Hudson Jan 22 '18 at 21:07
  • @trincot: True, that would be needed if the original set contains duplicates. –  Jan 22 '18 at 21:07
  • @rockstar Conditions in OP are to avoid duplicates as these are inputs any user can enter. Although removing duplicates is a simple matter and this has helped me greatly. – Lynel Hudson Jan 22 '18 at 21:08
  • @solacyon: Yes, if there are duplicates in the original set, there'll be so in the result. See trincot's suggestion for eliminating them. –  Jan 22 '18 at 21:08
  • The `arr` parameter in `.reduce()` is unnecessary, you already have access to `arr` there. – ryanpcmcquen Jan 22 '18 at 21:09
  • 1
    Rewrite for readability: https://repl.it/@ryanpcmcquen/FatMadAngwantibo – ryanpcmcquen Jan 22 '18 at 21:10
  • @solacyon: The OP wasn't clear if there would be duplicates in the original set. It looks to me like you're saying that the algorithm itself shouldn't produce duplicates. If there may be duplicates in the data, you should provide various representative data sets. –  Jan 22 '18 at 21:11
  • @ryanpcmcquen: I prefer to avoid closing over variables unnecessarily when possible. –  Jan 22 '18 at 21:11
  • @ryanpcmcquen: "readability" is subjective. Verbosity doesn't always beget readability. –  Jan 22 '18 at 21:12
  • @solacyon: It doesn't produce any given the sample data provided. I'll update, but I hate to guess at what the data may look like. –  Jan 22 '18 at 21:22
  • @rock-star, explicit is better than implicit. – ryanpcmcquen Jan 22 '18 at 21:26
  • @ryanpcmcquen: Do you mean the names? `res`, `i`, `n` and `arr` are very common indicators in programming, and are used in accordance to their common meaning. Anything more just seems like verbosity for the sake of verbosity. I did agree though about my original `a` variable, so I changed it, though I do usually prefer to avoid shadowing too. Ultimately, being familiar with the API is what gives the greatest clarity to the callback parameters. –  Jan 22 '18 at 21:36
  • @solacyon: I updated, though I didn't actually have to change anything beyond adding trincot's recommendation. Maybe you were applying it to the result instead? –  Jan 22 '18 at 21:39
  • @rockstar, 'very common', and 'very readable' are _very_ different things. – ryanpcmcquen Jan 22 '18 at 21:45
  • @ryanpcmcquen: I disagree. If a single letter variable is used in accordance with its common application, it enhances readability. They become confusing when used outside of those norms. I always hate it when I see `for (var i in someObject) {...}` because `i` isn't an index, assuming `someObject` isn't an array. Whereas `subsequentValue` is more to consume, and requires on-the-fly interpretation. I'd rather have 50 people agree on a convention than have them all give longer, more descriptive, but non-uniform names. –  Jan 22 '18 at 21:49
  • @rockstar, 'consistency' and 'readability' are both important, but they are not synonyms. – ryanpcmcquen Jan 22 '18 at 21:52
  • @ryanpcmcquen: I didn't say they were. I said it enhances readability. If a person consistently uses an index name that is 100 characters long, it clearly doesn't translate to readability (for me at least). In the real world, there's a reason that developers adopt these common, short names, and it isn't because it makes things *more* difficult –  Jan 22 '18 at 21:57
  • This isn't working with my regular array. Going to try converting my array to whatever a "Set" is like you have here. – Lynel Hudson Jan 23 '18 at 01:48
  • It works by modifying it to `const arr = [...new Set(myActualArray)];` – Lynel Hudson Jan 23 '18 at 01:58
  • @rockstar, and there is a reason the bandwagon is a logical fallacy. – ryanpcmcquen Jan 23 '18 at 02:45
  • @solacyon: Yes, I didn't name the collection. That would be correct. –  Jan 23 '18 at 14:52
  • @ryanpcmcquen: Now you're misunderstanding either the bandwagon fallacy or my statement. I'm not saying it's right and should be done because many do it. I'm just saying the fact that they do it is evidence that it's helpful. Do you really think a developer uses `i` for an index because they have no idea what `i` will mean in that context? Anyway, my point all along is that *"readability is subjective"*, and I'd say that this conversation demonstrates that assertion. –  Jan 23 '18 at 15:01
  • @rockstar, I disagree. Just because some or many developers do something is not evidence that it is helpful or enhancing readability. – ryanpcmcquen Jan 23 '18 at 15:21
  • @ryanpcmcquen: Fair enough, but don't confuse "proof" and "evidence" –  Jan 23 '18 at 15:30
  • ...and the inherent subjectivity of readability means that it requires neither proof nor evidence anyway; it requires only perception. –  Jan 23 '18 at 15:32