C scanf equivalent in nodejs - javascript

If I want to read from the input stream in C I write scanf., Is there equivalent method in NodeJS to do the same?
For example, here's the code in C
int n,
m,
i;
scanf("%d", &n);
for (i = 0; i < n; i++) {
scanf("%d", &m);
............
}
Here's where I'm starting from in Node... TODO indicates where I'm stuck:
process.stdin.resume();
process.stdin.setEncoding("ascii");
process.stdin.on("data", function (input) {
var n = +input;
for (var i = 0; i < n; i++) {
// TODO
}
});

For starters, calling scanf and the data event for a readable stream in NodeJS are not equivalent. In the NodeJS example, you will need to parse the chunk of the input you've received.
You can examine how these chunks are sent to you by replacing the body of your on method with a simple:
process.stdout.write('onData: ' + input + '\n');
Given how input then contains your data you'll need to use some method to extract the string of interest and then use parseInt. Perhaps a naive approach to your problem, assuming 1 integer per input:
var n = 0;
var m = 0;
var state = 0;
process.stdin.on('data', function (input) {
switch (state)
{
case 0:
// we're reading 'n'
n = parseInt(input.trim(), 10);
state++;
break;
default:
// we're reading 'm'
m = parseInt(input.trim(), 10);
if (state++ == n)
{
// we've read every 'm'
process.exit();
}
break;
}
});
I'm not a terribly large fan of this means of getting data to your NodeJS event loop, you should instead look to command line arguments, configuration/input files, or some other means.

Check sget.
var sget = require('./sget');
var width = sget('Width?'),
height = sget('Height?'),
area = width * height;
console.log('Area is', area);

This function will do what you asked for:
function readNums(s) {
// Split it up into numbers and spaces
var array = s.split(/(\d+)/);
// Keep just the numbers
array = array.filter(function(i) {return "" + +i == i});
// Convert back to a number
array = array.map(function(i) {return +i});
// How many elements should there have been?
var maxLen = array.shift();
if (array.length < maxLen) {
throw "Not enough enough numbers";
} else {
array.length = maxLen;
}
return array;
}
console.log(readNums("4 10 20 30 40 50 60 70"));
Result:
[10, 20, 30, 40]

Related

How can i make a loop that will show '-' mark x time iteration was? [duplicate]

In Perl I can repeat a character multiple times using the syntax:
$a = "a" x 10; // results in "aaaaaaaaaa"
Is there a simple way to accomplish this in Javascript? I can obviously use a function, but I was wondering if there was any built in approach, or some other clever technique.
These days, the repeat string method is implemented almost everywhere. (It is not in Internet Explorer.) So unless you need to support older browsers, you can simply write:
"a".repeat(10)
Before repeat, we used this hack:
Array(11).join("a") // create string with 10 a's: "aaaaaaaaaa"
(Note that an array of length 11 gets you only 10 "a"s, since Array.join puts the argument between the array elements.)
Simon also points out that according to this benchmark, it appears that it's faster in Safari and Chrome (but not Firefox) to repeat a character multiple times by simply appending using a for loop (although a bit less concise).
In a new ES6 harmony, you will have native way for doing this with repeat. Also ES6 right now only experimental, this feature is already available in Edge, FF, Chrome and Safari
"abc".repeat(3) // "abcabcabc"
And surely if repeat function is not available you can use old-good Array(n + 1).join("abc")
Convenient if you repeat yourself a lot:
String.prototype.repeat = String.prototype.repeat || function(n){
n= n || 1;
return Array(n+1).join(this);
}
alert( 'Are we there yet?\nNo.\n'.repeat(10) )
Array(10).fill('a').join('')
Although the most voted answer is a bit more compact, with this approach you don't have to add an extra array item.
An alternative is:
for(var word = ''; word.length < 10; word += 'a'){}
If you need to repeat multiple chars, multiply your conditional:
for(var word = ''; word.length < 10 * 3; word += 'foo'){}
NOTE: You do not have to overshoot by 1 as with word = Array(11).join('a')
The most performance-wice way is https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat
Short version is below.
String.prototype.repeat = function(count) {
if (count < 1) return '';
var result = '', pattern = this.valueOf();
while (count > 1) {
if (count & 1) result += pattern;
count >>>= 1, pattern += pattern;
}
return result + pattern;
};
var a = "a";
console.debug(a.repeat(10));
Polyfill from Mozilla:
if (!String.prototype.repeat) {
String.prototype.repeat = function(count) {
'use strict';
if (this == null) {
throw new TypeError('can\'t convert ' + this + ' to object');
}
var str = '' + this;
count = +count;
if (count != count) {
count = 0;
}
if (count < 0) {
throw new RangeError('repeat count must be non-negative');
}
if (count == Infinity) {
throw new RangeError('repeat count must be less than infinity');
}
count = Math.floor(count);
if (str.length == 0 || count == 0) {
return '';
}
// Ensuring count is a 31-bit integer allows us to heavily optimize the
// main part. But anyway, most current (August 2014) browsers can't handle
// strings 1 << 28 chars or longer, so:
if (str.length * count >= 1 << 28) {
throw new RangeError('repeat count must not overflow maximum string size');
}
var rpt = '';
for (;;) {
if ((count & 1) == 1) {
rpt += str;
}
count >>>= 1;
if (count == 0) {
break;
}
str += str;
}
// Could we try:
// return Array(count + 1).join(this);
return rpt;
}
}
If you're not opposed to including a library in your project, lodash has a repeat function.
_.repeat('*', 3);
// → '***
https://lodash.com/docs#repeat
For all browsers
The following function will perform a lot faster than the option suggested in the accepted answer:
var repeat = function(str, count) {
var array = [];
for(var i = 0; i < count;)
array[i++] = str;
return array.join('');
}
You'd use it like this :
var repeatedString = repeat("a", 10);
To compare the performance of this function with that of the option proposed in the accepted answer, see this Fiddle and this Fiddle for benchmarks.
For moderns browsers only
In modern browsers, you can now do this using String.prototype.repeat method:
var repeatedString = "a".repeat(10);
Read more about this method on MDN.
This option is even faster. Unfortunately, it doesn't work in any version of Internet explorer. The numbers in the table specify the first browser version that fully supports the method:
In ES2015/ES6 you can use "*".repeat(n)
So just add this to your projects, and your are good to go.
String.prototype.repeat = String.prototype.repeat ||
function(n) {
if (n < 0) throw new RangeError("invalid count value");
if (n == 0) return "";
return new Array(n + 1).join(this.toString())
};
String.repeat() is supported by 96.39% of browsers as of now.
function pad(text, maxLength){
return text + "0".repeat(maxLength - text.length);
}
console.log(pad('text', 7)); //text000
/**
* Repeat a string `n`-times (recursive)
* #param {String} s - The string you want to repeat.
* #param {Number} n - The times to repeat the string.
* #param {String} d - A delimiter between each string.
*/
var repeat = function (s, n, d) {
return --n ? s + (d || "") + repeat(s, n, d) : "" + s;
};
var foo = "foo";
console.log(
"%s\n%s\n%s\n%s",
repeat(foo), // "foo"
repeat(foo, 2), // "foofoo"
repeat(foo, "2"), // "foofoo"
repeat(foo, 2, "-") // "foo-foo"
);
Just for the fun of it, here is another way by using the toFixed(), used to format floating point numbers.
By doing
(0).toFixed(2)
(0).toFixed(3)
(0).toFixed(4)
we get
0.00
0.000
0.0000
If the first two characters 0. are deleted, we can use this repeating pattern to generate any repetition.
function repeat(str, nTimes) {
return (0).toFixed(nTimes).substr(2).replaceAll('0', str);
}
console.info(repeat('3', 5));
console.info(repeat('hello ', 4));
Another interesting way to quickly repeat n character is to use idea from quick exponentiation algorithm:
var repeatString = function(string, n) {
var result = '', i;
for (i = 1; i <= n; i *= 2) {
if ((n & i) === i) {
result += string;
}
string = string + string;
}
return result;
};
For repeat a value in my projects i use repeat
For example:
var n = 6;
for (i = 0; i < n; i++) {
console.log("#".repeat(i+1))
}
but be careful because this method has been added to the ECMAScript 6 specification.
function repeatString(n, string) {
var repeat = [];
repeat.length = n + 1;
return repeat.join(string);
}
repeatString(3,'x'); // => xxx
repeatString(10,'🌹'); // => "🌹🌹🌹🌹🌹🌹🌹🌹🌹🌹"
This is how you can call a function and get the result by the helps of Array() and join()
using Typescript and arrow fun
const repeatString = (str: string, num: number) => num > 0 ?
Array(num+1).join(str) : "";
console.log(repeatString("🌷",10))
//outputs: 🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷
function repeatString(str, num) {
// Array(num+1) is the string you want to repeat and the times to repeat the string
return num > 0 ? Array(num+1).join(str) : "";
}
console.log(repeatString("a",10))
// outputs: aaaaaaaaaa
console.log(repeatString("🌷",10))
//outputs: 🌷🌷🌷🌷🌷🌷🌷🌷🌷🌷
Here is what I use:
function repeat(str, num) {
var holder = [];
for(var i=0; i<num; i++) {
holder.push(str);
}
return holder.join('');
}
I realize that it's not a popular task, what if you need to repeat your string not an integer number of times?
It's possible with repeat() and slice(), here's how:
String.prototype.fracRepeat = function(n){
if(n < 0) n = 0;
var n_int = ~~n; // amount of whole times to repeat
var n_frac = n - n_int; // amount of fraction times (e.g., 0.5)
var frac_length = ~~(n_frac * this.length); // length in characters of fraction part, floored
return this.repeat(n) + this.slice(0, frac_length);
}
And below a shortened version:
String.prototype.fracRepeat = function(n){
if(n < 0) n = 0;
return this.repeat(n) + this.slice(0, ~~((n - ~~n) * this.length));
}
var s = "abcd";
console.log(s.fracRepeat(2.5))
I'm going to expand on #bonbon's answer. His method is an easy way to "append N chars to an existing string", just in case anyone needs to do that. For example since "a google" is a 1 followed by 100 zeros.
for(var google = '1'; google.length < 1 + 100; google += '0'){}
document.getElementById('el').innerText = google;
<div>This is "a google":</div>
<div id="el"></div>
NOTE: You do have to add the length of the original string to the conditional.
Lodash offers a similar functionality as the Javascript repeat() function which is not available in all browers. It is called _.repeat and available since version 3.0.0:
_.repeat('a', 10);
var stringRepeat = function(string, val) {
var newString = [];
for(var i = 0; i < val; i++) {
newString.push(string);
}
return newString.join('');
}
var repeatedString = stringRepeat("a", 1);
Can be used as a one-liner too:
function repeat(str, len) {
while (str.length < len) str += str.substr(0, len-str.length);
return str;
}
In CoffeeScript:
( 'a' for dot in [0..10]).join('')
String.prototype.repeat = function (n) { n = Math.abs(n) || 1; return Array(n + 1).join(this || ''); };
// console.log("0".repeat(3) , "0".repeat(-3))
// return: "000" "000"

Find the longest occurrence of the "aeiou" in a string

I was recently doing an interview and was asked multiple questions, one of the questions was this and I had a bit of trouble trying to answer it.
Given a string, find the longest occurrence of vowels "aeiou" that appear.
The substring of vowels do not have to be consecutive, and there can be repeats.
The goal is the find the max occurrence of each vowel and join them, but it must be in the order of "a","e","i","o","u".
Edit: In addition, each individual vowel character must be chained as well. In the example below, there is "aaa" and "aa" , since 3 is longer, our result must contain the longer chain.
For example:
Input: "aaagtaayuhiejjhgiiiouaae"
Result: aaaeiiiou
The code that I have tried is below:
EDIT: Following the solution, I have written this below but I am still running into issues with strings such as "aeiouaaaeeeiiiooouuu". The correct result for that would be 15 but I am getting 5.
var findLongestVowels = function(s){
var count = 1;
var i = 0;
var j = 0;
var vowels = ['a','e','i','o','u'];
var total = 0;
var array = [];
while (i < s.length){
if (s.charAt(i) == vowels[j] && s.charAt(i) == s.charAt(i+1) ){
count++;
}
else if (s.charAt(i) == vowels[j] && s.charAt(i) != s.charAt(i+1)){
if (j === 0 && !array[vowels[j]]){
array[vowels[j]] = count;
}
else if (j === 0 && array[vowels[j]]){
array[vowels[j]] = Math.max(array[vowels[j]],count);
}
else if (j !== 0 && !array[vowels[j]] && array[vowels[j-1]]){
array[vowels[j]] = array[vowels[j-1]] + count;
}
else if (j !== 0 && array[vowels[j]] && array[vowels[j-1]]){
array[vowels[j]] = Math.max(array[vowels[j]],array[vowels[j-1]] + count);
}
count = 1;
}
else if (s.charAt(i) == vowels[j+1] && array[vowels[j]]){
j++;
i--;
}
i++;
}
console.log(array);
console.log('Answer: ' + array[vowels[j]]);
}
findLongestVowels("eeeeebbbagtaagaaajaaaaattyuhiejjhgiiiouaae");
Am I at least going in the right direction?
Thanks in advance.
We can solve this in O(n) time. Consider that for each block, if its vowel is at index v in the list of vowels, we are only interested in the best solution for the block with a vowel at index v-1 in the order of vowels. We save the last best solution for each block type (each vowel) as we go along:
|aaa|g|t|aa|y|u|h|i|e|jj|h|g|iii|o|u|aa|e
b: 1 2 3 4 5 6 7 8 9 10
b 1: v[a] = 3
b 2: v[a] = max(2,3)
b 3: v[u] = None recorded for v-1
b 4: v[i] = None recorded for v-1
b 5: v[e] = 1 + 3
b 6: v[i] = 3 + 4
b 7: v[o] = 1 + 7
b 8: v[u] = 1 + 8 // answer
b 9: v[a] = max(2,3)
b 10: v[e] = 1 + 3
JavaScript code:
function f(str){
console.log(`String: ${ str }\n`);
var vowels = {
a: {best: 0, prev: null},
e: {best: 0, prev: 'a'},
i: {best: 0, prev: 'e'},
o: {best: 0, prev: 'i'},
u: {best: 0, prev: 'o'}
};
function getBlock(i){
let length = 1;
while (str[i+1] && str[i] == str[i+1]){
length++;
i++;
}
return length;
}
for (let i=0; i<str.length;){
let length = getBlock(i);
console.log(`i: ${ i }; length: ${ length }`)
if (!vowels[str[i]]){
i = i + length;
continue;
}
if (!vowels[str[i]].prev){
vowels[str[i]].best = Math.max(
vowels[str[i]].best,
length
);
// make sure the previous vowel
// exists in the string before
// this vowel
} else if (vowels[ vowels[str[i]].prev ].best){
vowels[str[i]].best = Math.max(
vowels[str[i]].best,
length + vowels[ vowels[str[i]].prev ].best
);
}
i = i + length;
}
console.log(`\n${ JSON.stringify(vowels) }\n\n`);
return vowels['u'].best;
}
var s = 'eeeeebbbagtaagaaajaaaaattyuhiejjhgiiiouaae';
console.log(f(s) + '\n\n');
s = 'aaagtaayuhiejjhgiiiouaae';
console.log(f(s) + '\n\n');
s = 'aeiouaaaeeeiiiooouuu';
console.log(f(s));
This problem can be solved by using dynamic programming technique.
First, we have string x and we want to find the longest string for this string.
Traversing the string x from start to end, assuming at index i, we are trying to find vowel e, there are two possibilities:
Current character is e, so we take the whole block and move to next character
Or, we can try with the next character
So, we have our pseudocode:
int[][]dp;
int largestBlock (int index, int currentVowel, String x, String vowels){
if (currentVowel == 5) {
// We found all 5 vowel
return 0;
}
if visited this state (index, currentVowel) before {
return dp[index][currentVowel];
}
int result = largestBlock(index + 1, currentVowel, x, vowels) ;
if (x[index] == vowels[currentVowel]){
int nxt = nextIndexThatIsNotVowel(index, currentVowel, x, vowels);
result = max(result, nxt - index + largestBlock(nxt, currentVowel + 1, x , vowels));
}
return dp[index][currentVowel] = result;
}
Time complexity is O(n * m) with m is number of vowels which is 5 in this case.
You need to remember biggest combination of individual vowels.
Use reduce, map and Object.values
var vowels = "aeiou";
var input = "aaagtaayuhiejjhgiiiouaae";
var output = Object.values(
input.split( "" ).reduce( ( a, c, i, arr ) => {
var lastChar = arr[ i - 1 ];
if ( !vowels.includes( c ) ) return a; //if not vowel, return accumulator
if ( c != lastChar ) //if not same as last character then create a new array
{
a[ c ] = a[ c ] || [];
a[ c ].push( [ c ] );
}
else //else push to the last array;
{
var lastCombo = a[ c ].slice( -1 )[ 0 ];
lastCombo.push(c)
}
return a; //return accumulator
} , {}) ).map( s => {
var char = s[0][0]; //find the character to repeat
var maxLength = Math.max.apply( null, s.map( s => s.length ) ); //find how many times to repeat
return Array( maxLength + 1 ).join( char );
}).join( "" ); //join all the vowels
console.log( output );
It's just one of many possible solutions - feel free to try it out.
Store every vowel you're interested in, in vowels array.
Use map to loop over every vowel in array, create regex from vowel to split string into array of vowels. For example "aaabdmedaskaa" would be split into ["aaa", "a", "aa"].
Filter this array so it doesn't include empty strings.
Sort it by length, so accesing 0 element would give you longest occurance
After mapping over every vowel, return the result - filter out "undefined" in case some of your vowels don't occur at all and regex results in empty array (accesing empty array's 0th element would result in undefined), join array of occurances into a result string.
The regex created from "a" will be [^a]+ which means any character sequence that does not include "a".
function findLongestOccurance(str) {
const vowels = ["a", "e", "i", "o", "u"];
const result = vowels.map(vowel => {
const regex = new RegExp(`[^${vowel}]+`);
return str.split(regex)
.filter(r => r !== "")
.sort((a, b) => b.length - a.length)[0];
});
return result.filter(occ => typeof(occ) !== "undefined").join("");
}
console.log(findLongestOccurance("aaagtaayuhiejjhgiiiouaae"));
Why not regex?
var result = /(a+).*(e+).*(i+).*(o+).*(u+)/.exec("aaagtaayuhiejjhgiiiouaae");
console.log(result[1]+result[2]+result[3]+result[4]+result[5]);
First of all, from what I understand from the question the result for Input: "aaagtaayuhiejjhgiiiouaae" should be aaaaaeiiiou, like #PhamTrung asked in the comments but didn't get answered.
Because it a job interview I would start with the first thing that comes to mind, namely brute force the solution out of this
function a(string, prefix='') {
if(!string.length){
return prefix
}
if(!/[aeiou]/.test(string[0])){
return a(string.substr(1), prefix)
}
const option1 = a(string.substr(1), prefix)
const option2 = a(string.substr(1), prefix+string[0])
const validateRegex = /^a+e+i+o+u+$/
const isValidOption1 = validateRegex.test(option1)
const isValidOption2 = validateRegex.test(option2)
if(isValidOption1 && isValidOption2){
if(option1.length > option2.length) {
return option1
}
return option2
}
if(isValidOption1) {
return option1
}
if(isValidOption2) {
return option2
}
return null
}
const input = 'aaagtaayuhiejjhgiiiouaae'
console.log(a(input))
This has a terrible run time though, we are trying all possible substring that contains only vowels, than we are discarding those that aren't of the form required (a+e+i+o+u+) and than choosing only the biggest of them all. If I'm not mistake this has a worst case of ∑(n choose i) which is O(n^n) - well, the actual worst case here would be a stackOverflow exception for sufficiently large n in which case we'd have to reimplement this with a loop instead of recursing. In this case we could still get an out of memory exception in which case we'd be out of options but to improve our algorithm. It's fair to imagine that if the input were large enough that we got an out of memory exception than our code would also be slow enough to not be a reasonable solution to the problem. I'm just arguing all this because these are things that an interviewer would possibly like to see that you are aware of, meaning you know enough of CS 101.
Following that the interviewer would ask if I can improve the performance. This is a solution with running time of O(n).
const input = 'aeiouaaaeeeiiiooouuu'
let curr = { "1": {price: -1} }
const nodes = []
const voewels = '1aeiou'
const getPrevLetter = (node) => voewels[voewels.indexOf(node.letter) -1]
let resultNode
function setUpNodeByCurrent(node, letter){
node.price = curr[letter].price + 1
node.previous = curr[letter]
}
function setBestResultIfNeeded(node){
if(node.letter !== 'u') {
return
}
if(!resultNode || resultNode.price < node.price) {
resultNode = node
return
}
}
function setCurrent(letter){
const node = {
letter,
price: 0
}
const prevLetter = getPrevLetter(node)
if(!prevLetter || !curr[prevLetter]){
// either letter isn't on of aeiou or
// we got to an i without ever seeing an e, an o without ever seeing an i, ... this letter is irrelevant
return
}
if(curr[node.letter]) {
setUpNodeByCurrent(node, node.letter)
}
if(node.price < curr[prevLetter].price + 1) {
setUpNodeByCurrent(node, prevLetter)
}
curr[node.letter] = node
setBestResultIfNeeded(node)
}
function getStringResult(node){
let result = ''
while(node) {
result = node.letter + result
node = node.previous
}
return result
}
function getResult(){
const node = resultNode //getBestResultNode()
const result = getStringResult(node)
console.log(result)
console.log(result.length)
}
for(let l of input){
setCurrent(l)
}
getResult()
This can be seen as a simplification of the longest path problem over a DAG basically you'd run through the string and every a points to the next occurance of a and the next occurance of e. e points to the next e and to the next i and so on. You'd than have a start node pointing to every occurance of a and an end node pointed to by every occurance of u. Now what you want is the longest path from the start node to the end node which is an O(|V|+|E|), now |V|<=n and |E|<=2n since every node in your graph has at most 2 vertices going out of it so the total running time is O(n). I have simplified the code to build the result as it goes on building the graph, basically I already calculate the cost on the go so when I finished building a graph similar to what I described I already know what the result is.
Note that this solution is based on the assumption that the input string is one that necessarily has a solution embedded in it. If the input string is unsolvable (there isn't and aeiou sequence in it) than this case would need to be properly handled, it is actually trivial to add the code that handles that. The first solution will return null in such a case(if I'm not mistaken)
Hope this helps.
If you want to find a substring which contains the maximum number of vowels and you also want to give {specify} the length of the substring then you should use this program:
let newk = s;
const elementsArray = [];
const tempoArray = [];
const counting = [];
const maxPoint = [];
let count
for (var i = 0; i < newk.length; i++) {
while (tempoArray.length > 0) {
tempoArray.pop();
}
let fk = i + k;
if (fk <= newk.length) {
for (let j = i; j < fk; j++) {
tempoArray.push(newk[j]);
}
let makingArray = tempoArray.toString();
elementsArray.push(makingArray);
} else {
// console.log(" ");
}
}
for (let q = 0; q < elementsArray.length; q++) {
count = 0
let tempString = new String(elementsArray[q]).split(",")
for (let l = 0; l < tempString.length; l++) {
if (tempString[l] == "a" || tempString[l] == "e" || tempString[l] == "i" || tempString[l] == "o" || tempString[l] == "u") {
count ++;
}else{
}
}
// console.log(count);
counting.push(count)
}
let max = 0,Maximist
// for (let d = 0; d < counting.length; d++) {
// console.log(counting[d] , " this is the value of the counting array");
// }
for (let t = 0; t <= counting.length; t++) {
if (counting[t] != 0) {
if (max < counting[t]) {
max = counting[t]
Maximist = t
}
else if (max == counting[t]){
max = counting[t]
Maximist = t
}
else{
console.log("");
}
}
}
// console.log(Maximist);
// console.log(max);
// maxPoint.push(Maximist)
for (let t = 0; t <= counting.length; t++) {
if (counting[0] != 0) {
if (max == counting[t]) {
maxPoint.push(t)
}
}
}
for (let e = 0; e < maxPoint.length; e++) {
console.log("{", elementsArray[maxPoint[e]] ,"}")
}
}
findSubstring("captainamerica", 3);
The bigger your size of the substring will be the less chances that there will be less substring with same number of vowels in it

JavaScript Dynamically created object undefined

I am doing the freecodecamp algorithmic challenge "Caesars Cipher". I have a problem with my code. I try to generate a lookup table as a dynamic object and for some reason it doesn't register. When doing console.log it is says "lookup table is undefined". It is the same with the Acode variable. If I comment out the console.logs then it will work but it will not encrypt anything because of the below part which checks if the char from strArr exists in the lookupTable, if not, it should assign the same value to the encryptedArr (this was done to not encrypt commas, spaces etc):
strArr.forEach(function(thisArg) {
var newValue;
if(lookupTable[thisArg] !== undefined ) {
newValue = lookupTable[thisArg];
} else {
newValue = thisArg;
}
encryptedArr.push(newValue);
});
Ofcourse lookupTable[thisArg] is always undefined.
Here is the whole function with the above part as well:
function rot13(str) { // LBH QVQ VG!
var strArr;
var encryptedArr = [];
var Acode;
var lookupTable = {}; //this object will contain the mapping of letters
var encryptedString;
//check the code of A , this will be a reference for the first letter as the algorith will use Modular Arithmetic
Acode = 'A'.charCodeAt(0);
console.log(Acode);
//generate an object containing mappings (I din't want to do it initially but theoreticaly just making lookups in a table would be more efficiant for huge workloads than calculating it every time)
//this algorithm is a little bit complecated but i don't know how to do modular arithmetic in code properly so I use workarrounds. If a = 101 then I do 101 + the remainder from current letter((Acode + 1) - 13) divided by 26 which works
for (i = 0; i < 26; i++) {
lookupTable[String.fromCharCode(Acode + i)] = String.fromCharCode(Acode + ((Acode + i) - 13) % 26);
console.log(lookupTable[String.fromCharCode(Acode + i)]);
}
//save the string into the array
strArr = str.split("");
//change letters into numbers and save into the code array
strArr.forEach(function(thisArg) {
var newValue;
if (lookupTable[thisArg] !== undefined) {
newValue = lookupTable[thisArg];
} else {
newValue = thisArg;
}
encryptedArr.push(newValue);
});
encryptedString = encryptedArr.join("");
return encryptedString;
}
// Change the inputs below to test
rot13("SERR PBQR PNZC");
console.log(Acode);
What am I doing wrong with the lookupTable object creation AND with the below?
Acode = 'A'.charCodeAt(0);
There's no undefined variable. The problem with your code is in how you calculate the lookup table entries. Your code is mapping every character to itself, not shifting by 13. The correct formula is
Acode + ((i + 13) % 26)
Acode is the ASCII code for the letter, and you shouldn't be including that when performing the modular shift. You just want to apply the modulus to the offset from the beginning of the alphabet after shifting it by 13.
function rot13(str) { // LBH QVQ VG!
var strArr;
var encryptedArr = [];
var Acode;
var lookupTable = {}; //this object will contain the mapping of letters
var encryptedString;
//check the code of A , this will be a reference for the first letter as the algorith will use Modular Arithmetic
Acode = 'A'.charCodeAt(0);
// console.log(Acode);
//generate an object containing mappings (I din't want to do it initially but theoreticaly just making lookups in a table would be more efficiant for huge workloads than calculating it every time)
//this algorithm is a little bit complecated but i don't know how to do modular arithmetic in code properly so I use workarrounds. If a = 101 then I do 101 + the remainder from current letter((Acode + 1) - 13) divided by 26 which works
for (i = 0; i < 26; i++) {
lookupTable[String.fromCharCode(Acode + i)] = String.fromCharCode(Acode + ((i + 13) % 26));
// console.log(lookupTable[String.fromCharCode(Acode + i)]);
}
//save the string into the array
strArr = str.split("");
//change letters into numbers and save into the code array
strArr.forEach(function(thisArg) {
var newValue;
if (lookupTable[thisArg] !== undefined) {
newValue = lookupTable[thisArg];
} else {
newValue = thisArg;
}
encryptedArr.push(newValue);
});
encryptedString = encryptedArr.join("");
return encryptedString;
}
// Change the inputs below to test
var result = rot13("SERR PBQR PNZC");
console.log(result);

Javascript repeatable random number based on multiple inputs

I am trying to create a function that takes 4 parameters and spits out a random number. But I want it so if the same 4 parameters are input, you will always get the same answer. The number should be between 0 and the max argument.
function random (x,y,z,max) {
output = ;
return Math.floor(output * max);
}
Is there any simple forumala I can use to get this? I tried to create one but it didn't look random at all, and would look very similar if you changed one parameter very slightly. I want it to be completely different, but repeatable.
hash function:
function hash (input){
input = 'random'+input;
var hash = 0;
if (input.length == 0) return hash;
for (i = 0; i < input.length; i++) {
char = input.charCodeAt(i);
hash = ((hash<<5)-hash)+char;
hash = hash & hash; // Convert to 32bit integer
}
return Math.abs(hash);
}
Generating an apparently unpredictable data from another is called "hashing"; restricting it to a range is called "modulo". Here is an easy way to do hashing using exponentiation:
const hashLim = () => {
const args = Array.prototype.slice.call(arguments);
const limit = args.shift();
var seed = limit - 1;
for (a in args) {
seed = Math.pow(args[a] + limit, seed) % limit
}
return seed;
}
document.write(hashLim(100, 4, 16, 64) + '<br/>')
document.write(hashLim(100, 5, 16, 64))
You can use some self made calculation for pseudo random values, like this example with pi and the taking of only the fractal part.
function Random(seed) {
var r = seed;
this.random = function () {
var v = r * Math.PI;
r = v - (v | 0);
return r;
}
this.random();
}
var i,
q = new Random(42),
r = new Random(42);
for (i = 0; i < 10; i++) {
document.write(q.random() +'<br>'+ r.random() + '<hr>');
}

for loop not executing properly Javascript

i m trying to calculate weight of a string using the following function
function weight(w)
{
Cap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
small = 'abcdefghijklmnopqrstuvwxyz'
spcl = "~!##$%^&*()_+[]\{}|;':,./<>?"
num = '0123456789'
var p = []
for(i=0;i<w.length;i++)
{
if(Cap.contains(w[i])==true)
p[i] = Cap.indexOf(w[i]) + 2
else if(small.contains(w[i])==true)
p[i] = small.indexOf(w[i]) + 1
else if(num.contains(w[i]))
p[i] = num.indexOf(w[i])
else if(spcl.contains(w[i]))
p[i] = 1
}
return _.reduce(p,function(memo, num){ return memo + num; }, 0);
}
where w is a string. this properly calculates weight of the string.
But whn i try to to calculate weight of strings given in a an array, it jst calculates the weight of the first element, ie. it does not run the full for loop. can anyone explain to me why is that so??
the for loop is as given below
function weightList(l)
{
weigh = []
for(i=0;i<l.length;i++)
weigh.push(weight(l[i]));
return weigh;
}
input and output:
>>> q = ['abad','rewfd']
["abad", "rewfd"]
>>> weightList(q)
[8]
whereas the output array should have had 2 entries.
[8,56]
i do not want to use Jquery. i want to use Vanilla only.
Because i is a global variable. So when it goes into the function weight it sets the value of i greater than the lenght of l. Use var, it is not optional.
for(var i=0;i<l.length;i++)
and
for(var i=0;i<w.length;i++)
You should be using var with the other variables in the function and you should be using semicolons.
I think your issue is just malformed JavaScript. Keep in mind that JavaScript sucks, and is not as forgiving as some other languages are.
Just by adding a few "var" and semicolons, I was able to get it to work with what you had.
http://jsfiddle.net/3D5Br/
function weight(w) {
var Cap = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
small = 'abcdefghijklmnopqrstuvwxyz',
spcl = "~!##$%^&*()_+[]\{}|;':,./<>?",
num = '0123456789',
p = [];
for(var i=0;i<w.length;i++){
if(Cap.contains(w[i])==true)
p[i] = Cap.indexOf(w[i]) + 2
else if(small.contains(w[i])==true)
p[i] = small.indexOf(w[i]) + 1
else if(num.contains(w[i]))
p[i] = num.indexOf(w[i])
else if(spcl.contains(w[i]))
p[i] = 1
}
return _.reduce(p,function(memo, num){ return memo + num; }, 0);
}
function weightList(l) {
var weigh = [];
for(var i=0;i<l.length;i++)
weigh.push(weight(l[i]));
return weigh;
}
q = ['abad','rewfd'];
results = weightList(q);
Hope that helps

Categories

Resources