Build string by generating random characters step by step
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
3
down vote
favorite
I'm trying to create a program that will try to build a target string character by character by generating random characters. I have come up with the following Nodejs program with a little bit of Google help:
const args = process.argv.slice(2)
const targetWord = args[0]
let builtWord = ''
function getRandomChar()
return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
function updateWord()
const length = builtWord
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(builtWord)
process.stdout.write(nextChar)
if (targetWord[length] === nextChar)
builtWord += nextChar
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
async function main()
while (true)
updateWord()
if (builtWord === targetWord)
break
await sleep(1000 / 16)
main()
What are your thoughts on it, anything I can improve or do differently? Thanks ðÂÂÂ!
javascript strings node.js
add a comment |Â
up vote
3
down vote
favorite
I'm trying to create a program that will try to build a target string character by character by generating random characters. I have come up with the following Nodejs program with a little bit of Google help:
const args = process.argv.slice(2)
const targetWord = args[0]
let builtWord = ''
function getRandomChar()
return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
function updateWord()
const length = builtWord
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(builtWord)
process.stdout.write(nextChar)
if (targetWord[length] === nextChar)
builtWord += nextChar
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
async function main()
while (true)
updateWord()
if (builtWord === targetWord)
break
await sleep(1000 / 16)
main()
What are your thoughts on it, anything I can improve or do differently? Thanks ðÂÂÂ!
javascript strings node.js
add a comment |Â
up vote
3
down vote
favorite
up vote
3
down vote
favorite
I'm trying to create a program that will try to build a target string character by character by generating random characters. I have come up with the following Nodejs program with a little bit of Google help:
const args = process.argv.slice(2)
const targetWord = args[0]
let builtWord = ''
function getRandomChar()
return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
function updateWord()
const length = builtWord
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(builtWord)
process.stdout.write(nextChar)
if (targetWord[length] === nextChar)
builtWord += nextChar
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
async function main()
while (true)
updateWord()
if (builtWord === targetWord)
break
await sleep(1000 / 16)
main()
What are your thoughts on it, anything I can improve or do differently? Thanks ðÂÂÂ!
javascript strings node.js
I'm trying to create a program that will try to build a target string character by character by generating random characters. I have come up with the following Nodejs program with a little bit of Google help:
const args = process.argv.slice(2)
const targetWord = args[0]
let builtWord = ''
function getRandomChar()
return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
function updateWord()
const length = builtWord
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(builtWord)
process.stdout.write(nextChar)
if (targetWord[length] === nextChar)
builtWord += nextChar
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms))
async function main()
while (true)
updateWord()
if (builtWord === targetWord)
break
await sleep(1000 / 16)
main()
What are your thoughts on it, anything I can improve or do differently? Thanks ðÂÂÂ!
javascript strings node.js
edited May 1 at 9:41
Vogel612â¦
20.9k345124
20.9k345124
asked May 1 at 9:19
Jennifer Zhou
183
183
add a comment |Â
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
Extract magic numbers into constants
For instance, what do
126
and32
represent in the following line?return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:
const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with
-32
,+32
,Math.random()
andMath.floor()
there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));
Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to
getRandomInt
indicating that property.await sleep(1000 / 16)
also features magic numbers.
Miscellaneous remarks
Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!
Extracting only a single property with the object destructuring syntax (
const length = builtWord
) seems a bit unidiomatic to me as opposed toconst length = builtWord.length
.
Apart from that, you are usinglength
only once anyway, so I would drop that variable all together.Try to avoid global variables and interdependencies.
For example,
builtWord
as well astargetWord
are shared (and the former even modified!) bymain
andupdateWord
. I would suggest makingupdateWord
accepting both as arguments and returning the possibly newly built word:function tryUpdateWord(currentBuiltWord, targetWord)
// This is a good moment to introduce a sanity check as well
if (currentBuildWord.length >= targetWord.length)
throw new Error('<todo>');
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(currentBuiltWord)
process.stdout.write(nextChar)
if (targetWord[currentBuildWord.length] === nextChar)
return currentBuiltWord + nextChar
else
return currentBuiltWord;
Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into
main()
:async function main()
const targetWord = process.args[2]
let builtWord = ''
const SLEEP_PER_ITERATION = 1000 / 16;
while (true)
builtWord = tryUpdateWord(builtWord, targetWord)
if (builtWord === targetWord)
break
await sleep(SLEEP_PER_ITERATION)
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Extract magic numbers into constants
For instance, what do
126
and32
represent in the following line?return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:
const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with
-32
,+32
,Math.random()
andMath.floor()
there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));
Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to
getRandomInt
indicating that property.await sleep(1000 / 16)
also features magic numbers.
Miscellaneous remarks
Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!
Extracting only a single property with the object destructuring syntax (
const length = builtWord
) seems a bit unidiomatic to me as opposed toconst length = builtWord.length
.
Apart from that, you are usinglength
only once anyway, so I would drop that variable all together.Try to avoid global variables and interdependencies.
For example,
builtWord
as well astargetWord
are shared (and the former even modified!) bymain
andupdateWord
. I would suggest makingupdateWord
accepting both as arguments and returning the possibly newly built word:function tryUpdateWord(currentBuiltWord, targetWord)
// This is a good moment to introduce a sanity check as well
if (currentBuildWord.length >= targetWord.length)
throw new Error('<todo>');
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(currentBuiltWord)
process.stdout.write(nextChar)
if (targetWord[currentBuildWord.length] === nextChar)
return currentBuiltWord + nextChar
else
return currentBuiltWord;
Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into
main()
:async function main()
const targetWord = process.args[2]
let builtWord = ''
const SLEEP_PER_ITERATION = 1000 / 16;
while (true)
builtWord = tryUpdateWord(builtWord, targetWord)
if (builtWord === targetWord)
break
await sleep(SLEEP_PER_ITERATION)
add a comment |Â
up vote
2
down vote
accepted
Extract magic numbers into constants
For instance, what do
126
and32
represent in the following line?return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:
const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with
-32
,+32
,Math.random()
andMath.floor()
there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));
Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to
getRandomInt
indicating that property.await sleep(1000 / 16)
also features magic numbers.
Miscellaneous remarks
Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!
Extracting only a single property with the object destructuring syntax (
const length = builtWord
) seems a bit unidiomatic to me as opposed toconst length = builtWord.length
.
Apart from that, you are usinglength
only once anyway, so I would drop that variable all together.Try to avoid global variables and interdependencies.
For example,
builtWord
as well astargetWord
are shared (and the former even modified!) bymain
andupdateWord
. I would suggest makingupdateWord
accepting both as arguments and returning the possibly newly built word:function tryUpdateWord(currentBuiltWord, targetWord)
// This is a good moment to introduce a sanity check as well
if (currentBuildWord.length >= targetWord.length)
throw new Error('<todo>');
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(currentBuiltWord)
process.stdout.write(nextChar)
if (targetWord[currentBuildWord.length] === nextChar)
return currentBuiltWord + nextChar
else
return currentBuiltWord;
Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into
main()
:async function main()
const targetWord = process.args[2]
let builtWord = ''
const SLEEP_PER_ITERATION = 1000 / 16;
while (true)
builtWord = tryUpdateWord(builtWord, targetWord)
if (builtWord === targetWord)
break
await sleep(SLEEP_PER_ITERATION)
add a comment |Â
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Extract magic numbers into constants
For instance, what do
126
and32
represent in the following line?return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:
const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with
-32
,+32
,Math.random()
andMath.floor()
there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));
Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to
getRandomInt
indicating that property.await sleep(1000 / 16)
also features magic numbers.
Miscellaneous remarks
Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!
Extracting only a single property with the object destructuring syntax (
const length = builtWord
) seems a bit unidiomatic to me as opposed toconst length = builtWord.length
.
Apart from that, you are usinglength
only once anyway, so I would drop that variable all together.Try to avoid global variables and interdependencies.
For example,
builtWord
as well astargetWord
are shared (and the former even modified!) bymain
andupdateWord
. I would suggest makingupdateWord
accepting both as arguments and returning the possibly newly built word:function tryUpdateWord(currentBuiltWord, targetWord)
// This is a good moment to introduce a sanity check as well
if (currentBuildWord.length >= targetWord.length)
throw new Error('<todo>');
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(currentBuiltWord)
process.stdout.write(nextChar)
if (targetWord[currentBuildWord.length] === nextChar)
return currentBuiltWord + nextChar
else
return currentBuiltWord;
Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into
main()
:async function main()
const targetWord = process.args[2]
let builtWord = ''
const SLEEP_PER_ITERATION = 1000 / 16;
while (true)
builtWord = tryUpdateWord(builtWord, targetWord)
if (builtWord === targetWord)
break
await sleep(SLEEP_PER_ITERATION)
Extract magic numbers into constants
For instance, what do
126
and32
represent in the following line?return String.fromCharCode(Math.floor(Math.random() * (126 - 32 + 1)) + 32)
It is much better to extract magic numbers into constants, i.e. to annotate them with a semantically meaningful name:
const HIGHEST_ASCII_PRINTABLE_CHARACTER = 126;
const LOWEST_ASCII_PRINTABLE_CHARACTER = 32;But even when you replace the numbers by their constant's name, it isn't immediately clear what you're doing with
-32
,+32
,Math.random()
andMath.floor()
there. Even if you are accustomed to random number generation, a dedicated function call is more readable with less redundancy and in fact is easier to reason about:return String.fromCharCode(getRandomInt(LOWEST_ASCII_PRINTABLE_CHARACTER, HIGHEST_ASCII_PRINTABLE_CHARACTER));
Especially, with your old code, I had to look up Math.random() on MDN to make really sure that is produces a uniform distribution. Now you can just add a docblock comment to
getRandomInt
indicating that property.await sleep(1000 / 16)
also features magic numbers.
Miscellaneous remarks
Using async-await for waiting after each loop iteration is a good use case and really makes the code cleaner!
Extracting only a single property with the object destructuring syntax (
const length = builtWord
) seems a bit unidiomatic to me as opposed toconst length = builtWord.length
.
Apart from that, you are usinglength
only once anyway, so I would drop that variable all together.Try to avoid global variables and interdependencies.
For example,
builtWord
as well astargetWord
are shared (and the former even modified!) bymain
andupdateWord
. I would suggest makingupdateWord
accepting both as arguments and returning the possibly newly built word:function tryUpdateWord(currentBuiltWord, targetWord)
// This is a good moment to introduce a sanity check as well
if (currentBuildWord.length >= targetWord.length)
throw new Error('<todo>');
const nextChar = getRandomChar()
process.stdout.write('r')
process.stdout.write(currentBuiltWord)
process.stdout.write(nextChar)
if (targetWord[currentBuildWord.length] === nextChar)
return currentBuiltWord + nextChar
else
return currentBuiltWord;
Since the interdependencies have now been eliminiated, I would also move the part reading the process arguments into
main()
:async function main()
const targetWord = process.args[2]
let builtWord = ''
const SLEEP_PER_ITERATION = 1000 / 16;
while (true)
builtWord = tryUpdateWord(builtWord, targetWord)
if (builtWord === targetWord)
break
await sleep(SLEEP_PER_ITERATION)
edited May 1 at 16:06
answered May 1 at 16:01
ComFreek
608617
608617
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193339%2fbuild-string-by-generating-random-characters-step-by-step%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password