I am learning javascript, I have been able to create a function that has a parameter, the function has the task of forming an array containing a 2 character (0/1) random string of 1 parameter and the return value must be an array.
example:
console.log (generateString(2));
sample results:
['01', '11']
The problem I face is even though it's a random string, but it still has the possibility to have the same value. Suppose I run the program code
console.log (generateString(4));
and one of the results is like this:
['00', '00', '01', '10']
my question is how can I ensure that the return value of the array has no duplicate value? This is my code so far..
function generateString(num){
let newArray = [];
for(let i = 0; i < num; i++){
let randomChar = generateCharacters();
if(i >= 1 && (newArray[i - 1] === randomChar)){
randomChar = generateCharacters();
newArray.push(randomChar);
} else {
newArray.push(randomChar);
}
}
return newArray;
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
Just check for the duplicate before adding the new string.
function generateString(num){
let newArray = [];
let i =0;
while(i<num){
console.log(newArray)
let randomChar = generateCharacters();
if(newArray.indexOf(randomChar)<=-1){
newArray.push(randomChar);
i+=1;
}
}
return newArray;
}
You can use a do-while inside the for-loop and keep making new random strings until the new strings generated is not included in the previous array.
function generateString(num){
let newArray = [];
let randomChar;
for(let i = 0; i < num; i++){
do{
randomChar = generateCharacters();
}
while(newArray.includes(randomChar));
newArray.push(randomChar)
}
return newArray;
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
You can shuffle the array of all 4 possible pairs of digits:
function shuffle(a) {
for (let i = a.length - 1; i > 0; i--) {
let j = Math.floor(Math.random() * (i + 1));
let temp = a[i];
a[i] = a[j];
a[j] = temp;
}
return a;
}
function generateString(num){
let all = ["00", "01", "10", "11"];
shuffle(all);
return all.slice(0, num); // Only take the number of elements requested
}
console.log(generateString(4));
Made changes in your generateString function. You can use set for not updating duplicates in the result. I think you need to update generateCharacters function to generate all possible strings properly.
function generateString(num){
let newArraySet = new Set();
for(let i = 0; i < num; i++){
let randomChar = generateCharacters();
while(newArraySet.has(randomChar)) {
randomChar = generateCharacters();
}
newArraySet.add(randomChar);
}
return Array.from(newArraySet);
}
function generateCharacters(){
const chars = '01';
let result = '';
for (let j = 2; j > 0; --j){
result += chars[Math.floor(Math.random() * chars.length)];
}
return result;
}
console.log(generateString(4));
When building the array you need to check to see if the random number is not already in the array before adding it to the array. This function will return true if you feed it the array in question and your "random" item you need to check.
function isInArray(myArray, arrayItemToCheck)
{
var found = myArray.find(function(arrayItem) {
return arrayItem == arrayItemToCheck;
});
return !!found
}
in your function, you change the line let randomChar = generateCharacters(); to:
let randomChar;
// loops forever until condition is met
while (true) {
randomChar = generateCharacters();
if (!isInArray(newArray, randomChar)) {
break;
}
}
Related
I need to test Combinational Sum I algorithm using JavaScript. I have done all things in html, but I don't know how to call function (in script.js), which contain Combinational Sum I algorithm, correctly. Does anybody know how to call it? how to calculate? how to write test?
let botun=document.getElementById('botun');
//including variables
botun.onclick=function(){
let niz=document.getElementById('input').value;
let target=document.getElementById('target').value;
//convert string in array
let nizInt=niz.split(' ').map(Number);
//convert element of array in Int
let nizIntNovi=[];
for(var i=0; i<nizInt.length; i++) {
nizInt[i] = parseInt(nizInt[i], 10);
nizIntNovi[i]=nizInt[i];
}
console.log(nizIntNovi);
//calling function
let meduRez=combinationalSum(nizIntNovi,target);
console.log(meduRez);
}
// Javascript program to find all combinations that
// sum to a given value
var combinationalSum=function(candidates,target){
//global result
const result=[];
candidates.sort((a,b)=>a-b);
//dfs recursive helper
const dfs=(i,candidates,target,slate)=>{
//backtracking case
if(target<0) return;
//base case
if(target===0){
result.push(slate.slice());
return;
}
//dfs recursive case
for(let j=i;j<candidates.lenght;j++){
slate.push(candidates[j]);
dfs(j,candidates,target-candidates[j],slate);
slate.pop();
}
}
dfs(0,candidates,target,[]);
return result;
};
You call it like in the snippet below, with some basic HTML.
Or using the console of the browser.
The function is not working right.
You can read about implementation here https://www.geeksforgeeks.org/combinational-sum/
let botun = document.getElementById('botun');
//including variables
botun.onclick = function() {
let niz = document.getElementById('input').value;
let target = document.getElementById('target').value;
//convert string in array
let nizInt = niz.split(' ').map(Number);
//convert element of array in Int
let nizIntNovi = [];
for (var i = 0; i < nizInt.length; i++) {
nizInt[i] = parseInt(nizInt[i], 10);
nizIntNovi[i] = nizInt[i];
}
console.log(nizIntNovi);
//calling function
let meduRez = combinationalSum(nizIntNovi, target);
console.log(meduRez);
}
// Javascript program to find all combinations that
// sum to a given value
var combinationalSum = function(candidates, target) {
//global result
const result = [];
candidates.sort((a, b) => a - b);
//dfs recursive helper
const dfs = (i, candidates, target, slate) => {
//backtracking case
if (target < 0) return;
//base case
if (target === 0) {
result.push(slate.slice());
return;
}
//dfs recursive case
for (let j = i; j < candidates.lenght; j++) {
slate.push(candidates[j]);
dfs(j, candidates, target - candidates[j], slate);
slate.pop();
}
}
dfs(0, candidates, target, []);
return result;
};
input {
height: 30px;
width: 100px;
line-height: 1;
}
.as-console-wrapper {
max-height: 100% !important;
}
Input: <input id="input" value="1 2 3 4"> Target: <input id="target" value="6">
<input type="button" id="botun" value="click">
There is solved problem. Task: input array of integer, input target then calculate Combinational Sum and print the smallest array of Combinational Sum.
For example: Input: [2,4,6] Target:4. Output will be 1, because Combinational Sum prints (2+2),(4). Smaller array is 4 and it contains one element so 1 will be output!
Code:
let botun=document.getElementById('botun');
let nizSplitNew=[];
let targetNew;
let brojac;
let array=[];
let min;
var rezultat=document.getElementById("rezl");
//including variables
botun.onclick=function(){
let niz=document.getElementById('input').value;
let target=document.getElementById('target').value;
//convert string in array
let nizSplit=niz.split(',').map(Number);
//convert element of array in Int
for(var i=0; i<nizSplit.length; i++) {
nizSplitNew[i] = parseInt(nizSplit[i], 10);
}
console.log(nizSplitNew);
targetNew = parseInt(target, 10);
//calling function
let meduRez=combinationSum(nizSplitNew,targetNew);
// Javascript program to find all combinations that
// sum to a given value
function combinationSum(arr, sum) {
let ans = new Array();
let temp = new Array();
// first do hashing since hashset does not always
// sort
// removing the duplicates using HashSet and
// Sorting the arrayList
let set = new Set([...arr]);
arr = [...set];
arr.sort()
findNumbers(ans, arr, sum, 0, temp);
return ans;
}
function findNumbers(ans, arr, sum, index, temp) {
if (sum == 0) {
// pushing deep copy of list to ans
ans.push([...temp]);
return;
}
for (let i = index; i < arr.length; i++) {
// checking that sum does not become negative
if ((sum - arr[i]) >= 0) {
// pushing element which can contribute to
// sum
temp.push(arr[i]);
findNumbers(ans, arr, sum - arr[i], i, temp);
// removing element from list (backtracking)
temp.splice(temp.indexOf(arr[i]), 1);
}
}
}
// Driver Code
// arr.push(5);
// arr.push(4);
// arr.push(8);
//let arr = []
for(let i=0;i<nizSplitNew;i++){
nizSplitNew.push(nizSplitNew[i]);
}
let sum = targetNew;
let ans = combinationSum(nizSplitNew, sum);
// If result is empty, then
// print all combinations stored in ans
for (let i = 0; i < ans.length; i++) {
brojac=0;
for (let j = 0; j < ans[i].length; j++) {
brojac=brojac+1;
}
array.push(brojac);
}
console.log(array);
min = Math.min(...array);
if (array.length == 0) {
rezultat.innerHTML=`<p>-1</p>`
}
else{
rezultat.innerHTML=`<p>${min}</p>`
}
}
I need to write a function strLetterCount(word) that takes the string input, and returns a string followed by the count of occurrences.
Ex:
strLetterCount("coconut"); // "c2o2n1u1t1"
Here is what I have so far:
function strLetterCount (word){
let results = ""
for(let i = 0; i < word.length; i++) {
let charAt = word.charAt(i)
let count = 0
results += charAt
for (let j = 0; j < word.length ; j++)
{
if(word.charAt(j) === charAt)
{
count++
}
}
results += count
}
return results;
}
But the issue is that it returns c2o2c2o2n1u1t1 instead of c2o2n1u1t1. I'm not sure how to get rid of the duplicates
function strLetterCount (word){
let results = ""
for(let i = 0; i < word.length; i++) {
let charAt = word.charAt(i)
if (!results.includes(charAt)) // <----------------------
{
let count = 0
results += charAt
for (let j = 0; j < word.length ; j++)
{
if(word.charAt(j) === charAt)
{
count++
}
}
results += count
}
}
return results;
}
console.log(strLetterCount("coconut"));
Using String.prototype.split function, you can convert string into char array.
Based on that char array, using Array.prototype.reduce, you can get the duplicated char info.
With that duplicated info, can get the string linked using Array.prototype.map.
console.log(strLetterCount("coconut")); // "c2o2n1u1t1"
function strLetterCount(word) {
const wordArr = word.split('');
const duplicates = wordArr.reduce((acc, cur) => {
acc[cur] ? acc[cur] ++ : acc[cur] = 1;
return acc;
}, {});
return Object.entries(duplicates).map(([key, value]) => key + value).join('');
}
function strLetterCount(word) {
let results = {};
for (let i = 0; i < word.length; i++) {
let c = word.charAt(i)
results[c] = (results[c] || 0) + 1;
}
let r = '';
for (let c in results)
r += c + results[c];
return r;
}
console.log(strLetterCount("coconut")); // "c2o2n1u1t1"
Using the String split method, a Set, the Array map method and the Array join method you can do it in a single line of code
const strLetterCount = word => [...new Set(word.split(''))].map(l => `${l}${word.split(l).length - 1}`).join('');
console.log(strLetterCount('coconut'));
how can i get elements uniquely from an array if aa is twice time it should not count in a result if it is if a is three times it should count 1
var string = "aaabbccddde" // Expected result ade
var toArray = string.split("")
console.log(toArray)
var newArr = []
for(let i =0; i<toArray.length; i++) {
if(newArr.indexOf(toArray[i]) === -1) {
newArr.push(toArray[i])
}
}
console.log(newArr)
can't find the solution yet please guide thank
Maybe this function can help you:
function getUniques(str) {
const uniques = [];
const strs = str.split("");
for (let i = 0; i < strs.length; i++) {
const elm = strs[i];
for (let j = i; j < strs.length; j++) {
if(elm === uniques[uniques.length - 1]) break;
if (elm !== strs[j + 1]) {
uniques.push(elm);
break;
}
}
}
return uniques.join("");
}
Sample:
getUniques("aaaadaaabbbcccdeeeee22222222222232") // adabcde232
Here is the problem:
Given two strings, find the number of common characters between them.
For s1 = "aabcc" and s2 = "adcaa", the output should be 3.
I have written this code :
function commonCharacterCount(s1, s2) {
var count = 0;
var str = "";
for (var i = 0; i < s1.length; i++) {
if (s2.indexOf(s1[i]) > -1 && str.indexOf(s1[i]) == -1) {
count++;
str.concat(s1[i])
}
}
return count;
}
console.log(commonCharacterCount("aabcc", "adcaa"));
It doesn't give the right answer, I wanna know where I am wrong?
There are other more efficient answers, but this answer is easier to understand. This loops through the first string, and checks if the second string contains that value. If it does, count increases and that element from s2 is removed to prevent duplicates.
function commonCharacterCount(s1, s2) {
var count = 0;
s1 = Array.from(s1);
s2 = Array.from(s2);
s1.forEach(e => {
if (s2.includes(e)) {
count++;
s2.splice(s2.indexOf(e), 1);
}
});
return count;
}
console.log(commonCharacterCount("aabcc", "adcaa"));
You can do that in following steps:
Create a function that return an object. With keys as letters and count as values
Get that count object of your both strings in the main function
Iterate through any of the object using for..in
Check other object have the key of first object.
If it have add the least one to count using Math.min()
let s1 = "aabcc"
let s2 = "adcaa"
function countChars(arr){
let obj = {};
arr.forEach(i => obj[i] ? obj[i]++ : obj[i] = 1);
return obj;
}
function common([...s1],[...s2]){
s1 = countChars(s1);
s2 = countChars(s2);
let count = 0;
for(let key in s1){
if(s2[key]) count += Math.min(s1[key],s2[key]);
}
return count
}
console.log(common(s1,s2))
After posting the question, i found that i havent looked the example well. i thought it wants unique common characters ..
and i changed it and now its right
function commonCharacterCount(s1, s2) {
var count = 0;
var str="";
for(var i=0; i<s1.length ; i++){
if(s2.indexOf(s1[i])>-1){
count++;
s2=s2.replace(s1[i],'');
}
}
return count;
}
Create 2 objects containing characters and their count for strings s1
and s2
Count the common keys in 2 objects and return count - Sum the common keys with minimum count in two strings
O(n) - time and O(n) - space complexities
function commonCharacterCount(s1, s2) {
let obj1 = {}
let obj2 = {}
for(let char of s1){
if(!obj1[char]) {
obj1[char] = 1
} else
obj1[char]++
}
for(let char of s2){
if(!obj2[char]) {
obj2[char] = 1
} else
obj2[char]++
}
console.log(obj1,obj2)
let count = 0
for(let key in obj1 ){
if(obj2[key])
count += Math.min(obj1[key],obj2[key])
}
return count
}
I think it would be a easier way to understand. :)
function commonCharacterCount(s1: string, s2: string): number {
let vs1 = [];
let vs2 = [];
let counter = 0;
vs1 = Array.from(s1);
vs2 = Array.from(s2);
vs1.sort();
vs2.sort();
let match_char = [];
for(let i = 0; i < vs1.length; i++){
for(let j = 0; j < vs2.length; j++){
if(vs1[i] == vs2[j]){
match_char.push(vs1[i]);
vs2.splice(j, 1);
break;
}
}
}
return match_char.length;
}
JavaScript ES6 clean solution. Use for...of loop and includes method.
var commonCharacterCount = (s1, s2) => {
const result = [];
const reference = [...s1];
let str = s2;
for (const letter of reference) {
if (str.includes(letter)) {
result.push(letter);
str = str.replace(letter, '');
}
}
// ['a', 'a', 'c'];
return result.length;
};
// Test:
console.log(commonCharacterCount('aabcc', 'adcaa'));
console.log(commonCharacterCount('abcd', 'aad'));
console.log(commonCharacterCount('geeksforgeeks', 'platformforgeeks'));
Cause .concat does not mutate the string called on, but it returns a new one, do:
str = str.concat(s1[i]);
or just
str += s1[i];
You can store the frequencies of each of the characters and go over this map (char->frequency) and find the common ones.
function common(a, b) {
const m1 = {};
const m2 = {};
let count = 0;
for (const c of a) m1[c] = m1[c] ? m1[c]+1 : 1;
for (const c of b) m2[c] = m2[c] ? m2[c]+1 : 1;
for (const c of Object.keys(m1)) if (m2[c]) count += Math.min(m1[c], m2[c]);
return count;
}
I have a combinatoric script that's working fine, actually got most of it from the IBM dev website. But I want to be able to not just show the possible combinations, but also extract the numbers on each combination and get the product of the entire numbers. The project am working on mixes numbers (quantity) with strings (codename). So after combining them, i extract the number from each string and get the product of all the numbers in each combination. As shown;
[A2,B4,C5] = 2*4*5 = 40
Here is my javascript code that gets the combination, not to worry, I ran it with a test array of numbers 1-6, without the characters as shown above.
var Util = function() {
};
Util.getCombinations = function(array, size, start, initialStuff, output) {
if (initialStuff.length >= size) {
output.push(initialStuff);
} else {
var i;
for (i = start; i < array.length; ++i) {
Util.getCombinations(array, size, i + 1, initialStuff.concat(array[i]), output);
}
}
}
Util.getAllPossibleCombinations = function(array, size, output) {
Util.getCombinations(array, size, 0, [], output);
}
// Create an array that holds numbers from 1 ... 6.
var array = [];
for (var i = 1; i <= 6; ++i) {
array[i - 1] = i;
}
var output = [];
var resultArray = [];
Util.getAllPossibleCombinations(array, 4, output);
for(var j=0; j<output.length; j++) {
resultArray += output[j] + "=" + "<br />";
}
document.getElementById("test").innerHTML = resultArray;
});
I tried running this code inside the last for loop to get my multiplication, but it's just not executing, i must be doing something wrong. Here is the code;
var inputval = output[j].replace(/[^,.0-9]/g, '');
inputval = inputval.slice(0, -1);
var hoArray = inputval.split(',');
var cunt= hoArray.length;
var ans=1;
for(var m=0; m<cunt; m++)
{
ans *= hoArray[m];
}
Thanks for your assistance in advance.
walk the array then walk the string, then cast and see if it is an integer then tally and sum the product.
let array = ['A20', 'B11', 'C5'];
function getProduct(ar) {
let product = 1;
for (let x of ar) {
let semiProduct = [];
for (let i of x) {
if (Number.isInteger(+i)) {
semiProduct.push(i);
}
}
product *= semiProduct.join('');
}
return product;
}
console.log(getProduct(array))
You could also use a regular expression.
let array = ['A20', 'B11', 'C5'];
function getProduct(ar) {
let product = 1;
for (let x of ar) {
product *= x.match(/\d+/)[0];
}
return product;
}
console.log(getProduct(array))
If you want a way to generate permutations, you can utilize a generator to make things more concise.
let array = ['A20', 'B11', 'C5'];
function* permu(arr, l = arr.length) {
if (l <= 0) yield arr.slice();
else
for (var i = 0; i < l; i++) {
yield* permu(arr, l - 1);
const j = l % 2 ? 0 : i;
[arr[l - 1], arr[j]] = [arr[j], arr[l - 1]];
}
}
console.log(
Array.from(permu(array))
);
When I run that code in the console it throws an error because output[j] is an array [1,2,3,4] and it looks like you're expecting it to be a string. Arrays do not have a replace method in JS.
You should run this:
var count= hoArray.length;
var ans=1;
for(var m=0; m<count; m++)
{
ans *= hoArray[m];
}
And put output[j] instead of hoArray. And don't do any of this:
var inputval = output[j].replace(/[^,.0-9]/g, '');
inputval = inputval.slice(0, -1);
var hoArray = inputval.split(',');