Code for Variations with repetition (combinatorics) using javascript? - javascript

Does anyone have Javascript code for generating all variations with repetition?
Example of variations with repetition:
(size=3, input=A,B)
AAA, AAB, ABA, BAA, ABB, BAB, BBA, BBB
What I need is to do something similar for numbers from 0-9 as the input and 6 digits length as size (according to my example).
Just to know, I got this working with a code in Java and also in .NET based on this project (check the link). All variations with repetition for what I need generates 1000000 values.
http://www.codeproject.com/KB/recipes/Combinatorics.aspx
Is it possible to do it in Javascript?

you have chosen the simplest case from combinatorics...
var i, n = 1000000;
for (i = 0; i < n; i++)
console.log(('' + (i + n)).substring(1));
will give you all the combinations of 0-9 in 6 spots (1000000 === Math.pow(10, 6)).

I've just wrote it right now, it needs more tests and optimizations but this should get you started:
​var input = "ABCD";
var size = 3;
var results = [];
function solve(i, elt) {
if(elt.length == size) {
results.push(elt);
return;
}
for(var j = 0; j < input.length; j++) {
solve(j, elt+input[j]);
}
}​​​​​​
solve(0, "");
​console​.log(results);​

Related

How to get numbers of variants numerical combinations in javascript?

I need to implement a function that accepts two parameters - the number of 0 and the number of 1 and determine how many ways to place these 0 and 1 so that there are no two zeros in a row.
For example, I need to find all methods of placing two 0 and two 1.
There are six possible ways to place them: 0011, 0101, 0110, 1001, 1010, 1100.
In three cases there are two zeros in a row: 0011, 1001 and 1100.
I subtract them from the total number and get three possible ways: 0101, 0110 and 1010. So the answer is 3.
First, I'm trying to write script to recognize which cases I need
let arr = ["1100","1010","1001","0011","0101","0110"]
let result = [];
for (let i = 0; i < arr.length; i++){
let expVal = arr[i];
for (let p = 0; p < expVal.length; p++){
if (expVal[p] === expVal[p++] || expVal[p] === "0"){
result.push(expVal)
}
}
}
console.log(result);
It's does not work. I don't know how to fix it.
And I don't understand what I need to do later
The problem you are solving is equivalent to the Fibonacci sequence.
filter for includes '00'
recursive function x generates binary number strings using n0 zeroes, n1 ones. Works by branching to (add a zero, find combos for one less zero)'0'+x(n0-1,n1) and (add a one, find combos for one less 1)'1'+x(n0,n1-1).
let arr = ["1100","1010","1001","0011","0101","0110"]
const x = (n0,n1) =>
!(n0 === 0 || n1 === 0) ?
x(n0-1,n1).map(x=>'0'+x).concat(
x(n0,n1-1).map(x=>'1'+x))
: ['0'.repeat(n0)||'1'.repeat(n1)]
arr = x(2,2)
console.log(
x(2,2)
)
console.log(arr.filter(x=>x.includes('00')))
There are 2 issues with the code, as far as I can see:
You're incrementing p two times: once in the for definition, and once in the execution itself (p++). The second one should be replaced by p+1
Also, you're checking if the next character is equal to the current, OR the current character is 0. This should be AND.
let arr = ["1100","1010","1001","0011","0101","0110"]
let result = [];
for (let i = 0; i < arr.length; i++){
let expVal = arr[i];
for (let p = 0; p < expVal.length; p++){
if (expVal[p] === expVal[p+1] && expVal[p] === "0"){
result.push(expVal)
}
}
}
console.log(result);
Changing those two things fixes it.

The answer should be valid for any given input

Write a function which takes a sentence as an input and output a sorted sentence.
1.Each character of the word should be arranged in alphabetical order
Words should be arranged in ascending order depending on its character count
Note: - Word only can have lowercase letters
Example :
Inputs str = "she lives with him in a small apartment"
Output = "a in ehs him hitw eilsv allms aaemnprtt"
function makeAlphabetSentenceSort(str) {
var word = str.split(' ');
for (var j = 0; j < word.length; j++) {
word[j] = word[j].split('').sort().join('');
}
for (var h = 0; h < word.length - 1; h++) {
for (var i = 0; i < word.length - h - 1; i++) {
if (String(word[i]).length > String(word[i + 1]).length) {
var temp = word[i];
word[i] = word[i + 1];
word[i + 1] = temp;
}
}
}
return word.join(' ');
}
console.log(makeAlphabetSentenceSort("she lives with him in a small apartment"));
ERROR message is "The answer should be valid for any given input."
Upon further reflection, it's clear that their challenge isn't following their own rules. It clearly states:
Word only can have lowercase letters
Yet, it runs this through the code (with punctuation):
he was curious about how it would taste, so he took a small bite.
To make matters worse, it expects the following output, which places how before saw, even though how appears after saw:
a eh it os eh how asw koot .beit allms dlouw abotu ,aestt ciorsuu
So, to be able to pass this challenge, you're also going to need to swap words of the same length with each other.
NodeJS Solution
The following produces the correct results in NodeJS, but not in the browser, in fact, sort() gave me different results in different browsers!
function makeAlphabetSentenceSort(str) {
var word = str.split(' ');
for (var j = 0; j < word.length; j++) {
word[j] = word[j].split('').sort().join('');
}
return word.sort((a, b) => a.length - b.length).join(' ');
}
console.log(makeAlphabetSentenceSort('he was curious about how it would taste, so he took a small bite.'));
I then read about why sort is so unreliable, and this article is a great resource, unfortunately, the solution in it provides reliable results, but not in the way this challenge expects it.
https://medium.com/#fsufitch/is-javascript-array-sort-stable-46b90822543f
Challenge
http://ccc.fidenz.com/en/challenges/challenges/challenge--86
Takeaway
This is a horribly designed challenge, you really should focus your efforts on a better website to practice programming, such as HackerRank, instead of this hodgepodge mess.

Using only one loop to generate nested arrays

I am trying to come up with an algorithm to generate a nested array of consecutive numbers using only one loop. I feel it should be solved somehow using remainder operator but can't quite come up with a general solution. Anyone has any suggestion or hints?
input: 4
output: 1,2,3,4,1,2,3,4,1,2,3,4,1,2,3,4
You would use the modulo operator (%), but note that you should loop from zero and up, and the result from modulo is also from zero and up, so you have to add one to it.
var input = 4;
for (var i = 0; i < input * input; i++) {
var n = (i % input) + 1;
document.write(n + '<br>');
}
Something like that should do the trick:
int input = ...
int i = 0;
while(i<=(input*input)){
int output = (i % input) + 1;
i++;
}

Intense loop freezing browser; how to make server do it?

Basic outline; I am retrieving ~100 Facebook statuses, and running a search of these posts to check if it contains one of ~20 search terms. When I try to run it in the browser it locks up, which makes me apprehensive to try and run this on the client side.
What would be the easiest way to have the server run this operation and return the results? Can I do it in Python? Here is the loop, for reference.
function Filter() {
console.log("running Filter")
//loop through fbObj.posts
for (i = 0, l = fbObj.length; i < l; i++){
var post = fbObj[i].post
console.log("Checking " + post + " for search terms")
//loop through searchTerms
for (j = 0; j<searchTermObj.length; j= j++) {
searchTerm_variants = searchTermObj[j].words
for (x = 0; x < searchTerm_variants.length; x++){
if (post.indexOf(searchTerm_variants[x]) !== 0){
foundPosts[i] = {}
foundPosts[i] = fbObj[i]
}
}
}
console.log(foundPosts)
}
}
You have an error in your code that might explain the lockup :
//loop through searchTerms
for (j = 0; j<searchTermObj.length; j= j++) {
j is never incremented (so it is always 0) :
j++ increments j, but evaluates to j which is assigned to j. So it's a null operation.
Therefore your code gets stuck in the loop.
Have you thought of using worker threads to do this on the client? However this might be available only in the latest builds of various browsers?
https://developer.mozilla.org/en-US/docs/DOM/Worker
You could build an all-encompassing regex like this, I think:
var regexWords = [], variants;
for (var i = 0; i < searchTermObj.length; ++i) {
variants = searchTermObj[i].words;
for (var j = 0; j < variants.length; ++j)
regexWords.push(variants[j]);
}
var regex = new RegExp(regexWords.join("|"));
Then you can test each post like this:
for (i = 0, l = fbObj.length; i < l; i++){
var post = fbObj[i].post
if (regex.test(post)) {
// found a naughty word in the post
}
}
Now this works so long as your word lists are just alphabetic words, with no funny characters like "*" or "." in them. You could still make this work if they did contain special characters, but it'd be a little more complex.
Doing it with a big regex like that allows the regex engine to employ smart sub-linear searching techniques, so that each post only needs to be searched once. It still may not be extremely fast.

Javascript: matching a dynamic string against an array

I'm attempting to teach myself javascript. I chose something I assumed was simple, but ran into problems relatively quickly.
I'm attempting to search a string for another string given by the user.
My code so far is:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = [];
var one = 0;
var two = 0;
var k = 0;
var sourceSearch = function(text) {
for(i = 0; i < source.length; i++) { //for each character in the source
if(source[i] === searchString[0]) { //if a character in source matches the first element in the users input
one = source.indexOf(i); //confused from here on
for(p = searchString.length; p > 0; p--) {
}
}
}
};
sourceSearch(searchString);
My idea was:
check to see if the first loop finds a character that matches the first character in the user input
if it matches, check to see if the next X characters after the first match the next X characters in the source string
if they all match, push them to the hits array
My problem: I have no idea how to iterate along the arrays without nesting quite a few if statements, and even then, that wouldn't be sufficient, considering I want the program to work with any input.
Any ideas would be helpful. Thanks very much in advance.
Note: There are a few un-used variables from ideas I was testing, but I couldn't make them work.
You can try:
if (source.indexOf(searchString) !== -1) {
// Match!
}
else
{
//No Match!
}
As the other answers so far point out, JavaScript strings have an indexOf function that does what you want. If you want to see how it's done "by hand", you can modify your function like this:
var sourceSearch = function(text) {
var i, j, ok; // always declare your local variables. globals are evil!
// for each start position
for(i = 0; i < source.length; i++) {
ok = true;
// check for a match
for (j = searchString.length - 1; ok && j >= 0; --j) {
ok = source[i + j] === searchString[j];
}
if (ok) {
// searchString found starting at index i in source
}
}
};
This function will find all positions in source at which searchString was found. (Of course, you could break out of the loop on the first success.) The logic is to use the outer loop to advance to each candidate start position in source and use the inner loop to test whether that position actually is the position of a match to searchString.
This is not the best algorithm for searching strings. The built-in algorithm is much faster (both because it is a better algorithm and because it is native code).
to follow your approach, you can just play with 2 indexes:
var sourceSearch = function(text) {
j = 0;
for(i = 0; i < source.length; i++) {
if(source[i] === text[j]) {
j++;
} else {
j = 0;
}
if (j == text.length) {
console.log(i - j); //this prints the starting index of the matching substring
}
}
};
These answers are all pretty good, but I'd probably opt for something like this:
var source = "XREs2qqAQfjr6NZs6H5wkZdOES5mikexRkOPsj6grQiYNZfFoqXI4Nnc1iONKVrA";
var searchString = []; //the users input
searchString = prompt("Enter search string");
var hits = source.split(searchString);
var hitsCount = hits.length - 1;
This way you have all of the data you need to figure out where each hit occurred in he source, if that's important to you.

Categories