0

First of all, any of built-in methods cannot be used. ex. pop(), shift(). What I can use is merely loops, array and so on.

I would like to make a function which takes an array as an argument and generate random strings of numbers, which does not contain these numbers given in the array.

For instance, func([6, 2]) //=> "20353" (2 and 6 would not be there). The array length could change ([6, 2, 9], [7, 2, 1, 9]). So the function has to have an ability to accommodate any length of an array.

In order to tackle this practice question, I have used for and while loops. However, I ran into a problem that, when the second index is checked (whether numbers randomly generated contain 2 or not, in the example), if it contains, I regenerate the random number and it could produce the first index number (in this case, 6) which I do not want.

Please see the code I posted below and help me solve this. On top of that, if there is another way to get the same result which is a better way, please let me know too.

let str = "";
let arr = [];
let tem

const func = arg2 => {
  for (let i = 0; i < 5; i++) {
    arr[i] = Math.floor(Math.random() * 10);
  }

  for (let i = 0; i < arr.length; i++) {
    for (let v = 0; v < arg2.length; v++) {
      if (arg2[v] == arr[i]) {
        do {
          tem = Math.floor(Math.random() * 10);
        } while (tem == arr[i])
        arr[i] = tem;
      }
    }
  }

  for (let i = 0; i < arr.length; i++) str += arr[i]
  return str
}

console.log(func([6, 2]))

// the output will not contain 2, which is the last index element
// however, when the second index number is removed, the output might replace it with 6, which is the first index element

Expected output:

func([6, 3, 8]) //=> "45102"
func([4, 9]) //=> "55108"
2
  • The length of the string result should always be 5? Commented Jul 9, 2019 at 21:28
  • 4
    "any of built-in methods cannot be used.": you are already using two native methods... Commented Jul 9, 2019 at 21:33

4 Answers 4

2

First, you already use two native methods (floor and random), but I'll assume you're OK with that.

Secondly, in your question the term digit would have been more appropriate in some instances than number. There is a difference...

To avoid that you still select a digit that is not allowed, you could first build an array with digits that are still allowed, and then randomly pick values from that array. That way you will not ever pick a wrong one.

Here is how that would look:

const func = arg2 => {
    const digits = [0,1,2,3,4,5,6,7,8,9];
    // Mark digits that are not allowed with -1
    for (let i=0; i<arg2.length; i++) {
        digits[arg2[i]] = -1;
    }
    // Collect digits that are still allowed
    const allowed = [];
    for (let i=0; i<digits.length; i++) {
        if (digits[i] > -1) allowed[allowed.length] = digits[i];
    }
    // Pick random digits from the allowed digits
    let str = "";
    for(let i=0; i<5; i++) {
        str += allowed[Math.floor(Math.random() * allowed.length)];
    }
    return str;
}

console.log(func([6, 2]));

Just for fun, if you lift the restrictions on what language aspects cannot be used, you can do this as follows:

const func = arg2 => {
    const digits = new Set(Array(10).keys());
    for (let digit of arg2) digits.delete(digit);
    const allowed = [...digits];
    return Array.from({length:5}, () => 
        allowed[Math.floor(Math.random() * allowed.length)]
    ).join``;
}

console.log(func([6, 2]));

Sign up to request clarification or add additional context in comments.

Comments

0

I suspect you're overthinking this. The basic algorithm is:

  • In a loop:
    • If output has 5 digits, return it.
    • Otherwise
      • Pick a random digit n from 0 to 9.
      • If n is not in the list of excluded numbers, it to output.

This maps pretty directly to the following function:

function fn(exclude, length = 5) {
  let output = '';
  while (output.length < length) {
    const n = Math.floor(Math.random() * 10)
    if (!exclude.includes(n)) {
      output += n;
    }
  }
  return output;
}

console.log(fn([6,3,8]));

There are, of course, other ways to achieve this, such as initializing an array with five elements and then joining the elements:

function fn(exclude, length = 5) {
  return Array.from({ length }, () => {
    let n;
    while (n = Math.floor(Math.random() * 10), exclude.includes(n)) {}
    return n;
  }).join('');
}

console.log(fn([6,3,8]));

Comments

0

You need to loop through the entire arg2 array each time you pick a random digit. You can't replace the value in the arg2 loop, because then you won't check against earlier elements.

You don't need the arr array, you can append to str in the loop.

const func = arg2 => {
  let str = "";
  let arr = [];
  for (let i = 0; i < 5; i++) {
    let random;
    while (true) {
      let ok = true;
      random = Math.floor(Math.random() * 10);
      for (let j = 0; j < arg2.length; j++) {
        if (random == arg2[j]) {
          ok = false;
          break;
        }
      }
      if (ok) {
        break;
      }
    }
    str += random
  }

  return str
}

console.log(func([6, 2]))

Comments

0

Besides the fact (what others stated as well) that you use native array-methods yourself, I would probably go for it with something like this (using only what you used so far):

const func = without => {
    let result = '';

    while (result.length < 5) {
        let rand = Math.floor(Math.random() * 10);
        let add = true;

        for (i=0; i<without.length; i++) {
            if (rand === without[i]) {
                add = false;
            }
        }

        if (add) {
            result += rand;
        }
    }

    return result;
}

console.log(func([6, 2]))

a more concise version using native array methods could look like this:

const func = without => {
    let result = '';

    while (result.length < 5) {
        let rand = Math.floor(Math.random() * 10);

        if (!without.includes(rand)) {
            result += rand;
        }
    }

    return result;
}

console.log(func([6, 2]))

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.