Increasing integers sequence - javascript

In an inteview, i was asked to find the answer to the following algorithm question.
Suppose you get a short input of increasing integers, say, "2 4", can you figure out what integers come after 4? If you assume the second integer is +2 greater than the first, then the next integer should be 6; but if you assume the second integer is double the first integer, then perhaps the next integer is 8. However, if the short input was "2 4 8", then you can almost be sure that the next integer is 16.
In short, the more numbers you get, the more hypotheses you can eliminate. We would like you to write a program, in Javascript. Please clearly indicate which one you would like to use. The program takes in a short list of increasing integers as inputs, hypothesize possible patterns in the integers, and generate the next 10 integers in line.
For instance, if the program receives the following input:
4 14
the program may assume that the next integer is the previous integer plus 10, thus it will generate:
24 34 44 54 64 74 84 94 104 114
but if the program receives the following input instead:
4 14 34
then it may hypothesize that the next integer is the previous multiplied by 2 plus 6.
74 154 3314 634 1274 2554 5114 10234 20474 40954
This is an open-ended problem that we're presenting, in other words, the input list of integers may have very interesting properties (e.g. a fibonacci sequence), there is no particular set of integer sequences that we are testing. So, be creative! try to identify as many sequences as you can think of.
How could you solve this algorithm?

Here is a stab at the madness, because it is Friday and its fun lol.
I wrote 3 tests easy to add more though. Let me know what you think.
function doubleLast(seq) {
this.seq = seq;
this.display = 'Double the last number';
this.match = (seq) => seq.every((v, i) => (i > 0) ? v === seq[i-1]*2 : true);
this.nextValue = (seq) => seq[seq.length-1]*2;
}
function simpleAdd(seq) {
const addNum = (seq) => seq[1] - seq[0];
this.seq = seq;
this.display = 'Add a single number';
this.match = (seq) => {
// subtract initial value from the second
return seq.every((v,i) => (i > 0) ? v === seq[i-1]+addNum(seq) : true);
};
this.nextValue = (seq) => seq[seq.length-1]+addNum(seq);
}
function divideAddMod(seq) {
const modifier = (seq) => seq[1] - (seq[0]*2);
this.seq = seq;
this.display = 'Try to divide by 2, then add Mod';
this.match = (seq) => {
// subtract initial value from the second
return seq.every((v,i) => (i > 0) ? v === (seq[i-1]*2)+modifier(seq) : true);
};
this.nextValue = (seq) => (seq[seq.length-1]*2)+modifier(seq);
}
const algos = [new doubleLast(), new simpleAdd(), new divideAddMod()];
document.addEventListener('click', (e) => {
if(e.target.matches('button')) {
let seq = document.querySelector('input').value.split(' ').map(e => parseInt(e));
algos.forEach(a => {
let possibleMatch = a.match(seq);
if(possibleMatch) {
console.log(`Match found ${a.display} - Next value ${a.nextValue(seq)}`);
} else {
console.log(`${a.display} did not match`);
}
});
}
});
<input type="text"></input>
<button>Work It out</button>
<p>Suppose you get a short input of increasing integers, say, "2 4", can you figure out what integers come after 4? If you assume the second integer is +2 greater than the first, then the next integer should be 6; but if you assume the second integer is double the first integer, then perhaps the next integer is 8. However, if the short input was "2 4 8", then you can almost be sure that the next integer is 16.
In short, the more numbers you get, the more hypotheses you can eliminate. We would like you to write a program, in Javascript. Please clearly indicate which one you would like to use. The program takes in a short list of increasing integers as inputs, hypothesize possible patterns in the integers, and generate the next 10 integers in line.
For instance, if the program receives the following input: 4 14
the program may assume that the next integer is the previous integer plus 10, thus it will generate:
24 34 44 54 64 74 84 94 104 114
but if the program receives the following input instead: 4 14 34
then it may hypothesize that the next integer is the previous multiplied by 2 plus 6.
74 154 3314 634 1274 2554 5114 10234 20474 40954
This is an open-ended problem that we're presenting, in other words, the input list of integers may have very interesting properties (e.g. a fibonacci sequence), there is no particular set of integer sequences that we are testing. So, be creative! try to identify as many sequences as you can think of.</p>

Related

How to find a string with specific letters in gethash javascript function

function getHash( string ) {
let h = 7, letters = "acdefhlmnoprstuw";
for( var i = 0; i < string.length; i++ ) {
h = ( h * 37 + letters.indexOf( string[ i ] ) );
}
return h;
}
My task is to write a code which finds the string containing some of following letters: ACDEFHLMNOPRSTUW
Sothat the function getHash(THE SEARCHING STRING) gets the result of 18794359164.
I am not giving you some code, just some hints.
To get an understanding of the code, you have, and the one, you want to get, is to take a string with you gunction and get a hash value from it.
For example take 'wonder' and get
19017519751
as hash value.
This value contains a start value of seven (h = 7) and for each letter it multiplies h with 37 (this value looks like it is made for 37 different characters) and adds the index value of letters.
To get the opposite with a numerical value, you need to separate a rest of a division by 37 to get an index of a letter, exact the opposite of using a letter and add a value to the hash.
For example take the above value 19017519751 and get the rest of the division by 37
19017519751 % 37 -> 11 r
Now with the last letter (remember encoding goes from start to end of the word, decoding starts with the end), you need get a value without the last letter.
By encoding, you multiply each last sum by 37 and this works here as well, but in reversed manner and you need an integer value. Just divide by 37 and take the floored value for the next letter.
The rest looks like this:
513987020 % 37 -> 3 e
13891541 % 37 -> 2 d
375447 % 37 -> 8 n
10147 % 37 -> 9 o
274 % 37 -> 15 w
Finially, you need to have a check to stop the iteration ans this value is 7 the first value of encoding.

Generated hashid size

Today I am generating the hashid as follows:
const Hashids = require('hashids');
const ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
let number = 1419856
let hash = new Hashids('Salto do Pedro', 6, ALPHABET).encode(number)
console.log("Hash:", hash, ". Number:", number, ". Size:", hash.length)
So what is printed on the console is:
[Running] node "c:\Users\pedro\Desktop\teste\testPedro.js"
Hash: YMMMMM . Number: 1419856 . Size: 6
[Done] exited with code=0 in 0.258 seconds
However, if I change the variable 'number' to number 1419857 the result is:
[Running] node "c:\Users\pedro\Desktop\teste\testPedro.js"
Hash: DRVVVVV . Number: 1419857 . Size: 7
[Done] exited with code=0 in 0.245 seconds
My doubt is:
The alphabet I am going through has 26 characters and I defined that the minimum size of the hashid would be 6 characters, the maximum hashid that I would have available with 6 characters would not be 308.915.776 (26 * 26 * 26 * 26 * 26 * 26 )?
Why in the number 1.419.857 he already increased one more character in my hashid?
Good question. This might look intimidating but I would try to make it as simple as possible by understanding the math behind the code.
The Hashids constructor takes parameter - (salt, minLength, alphabet, seps)
Salt - String value which makes your ids unique in your project
MinLength - Number value which is the minimum length of id string you need
alphabet - String value (Input string)
seps - String value to take care of curse words
With this set, it tries to create a buffer array with Salt and random characters(taken based on salt,sep,alphabet passed) and shuffles the positions of each character.
Now, the below is the code which encodes the value based on the above character array
id = []
do {
id.unshift(alphabetChars[input % alphabetChars.length])
input = Math.floor(input / alphabetChars.length)
} while (input > 0)
Let's first take example 1 -
this.salt = 'Salto do Pedro'
this.minLength = 6
input = 1419856
// alphabetChars is the array which generates based on salt,alphabet and seps. (complex operations invol
alphabetChars = ["A","X","R","N","W","G","Q","O","L","D","V","Y","K","J","E","Z","M"]
The final array is then joined by string and a lottery character (another some math operation calc) is appended at the start. This is returned as encoded string.
Let's first take example 2 -
this.salt = 'Salto do Pedro'
this.minLength = 6
input = 1419857
// alphabetChars is the array which generates based on salt,alphabet and seps. (complex operations invol
alphabetChars = ["V","R","Y","W","J","G","M","L","Z","K","O","D","E","A","Q","N","X"]
Now this is the reason why you get +1 character extra if the number changes (because it ran a loop extra). It's the min length of the alphabet array which is monitored rather than max length, so you cannot be sure that you would be getting the same length by +1 characters always.
Hope it helps. If you want to dig in more - Here's the code for the library - https://github.com/niieani/hashids.js/blob/master/dist/hashids.js#L197

Is it possible to pack two integers to a hexadecimal and get them back

I have a weird requirement,
My destination only supports one integer, But I want to send two integers to it and later I want to get them back from a response.
for example,
allowed input:
{
'task': 2
}
I have subtask kind of a logic in my side, But my target is not aware of this. So, without letting know the target, can I somehow pack two integers and get decode them back in future?
Can this be achieved with hexadecimal?
You can combine any two numbers and get both numbers back using their product (a * b) as long as a * (a * b) + b < Number.MAX_SAFE_INTEGER
Here's a demo snippet:
(() => {
document.addEventListener("click", handleStuff);
// formula: c = (a * (a * b)) + b
// as long as c < 9007199254740991
const combine = (a, b) => ({
a: a,
b: b,
get c() { return this.a * this.b; },
get combined() { return this.a * this.c + this.b; },
get unraveled() { return [
Math.floor(this.combined / this.c),
this.combined % this.c ]; }
});
const log = txt => document.querySelector("pre").textContent = txt;
let numbers = combine(
+document.querySelector("#num1").value,
+document.querySelector("#num2").value );
function handleStuff(evt) {
if (evt.target.nodeName.toLowerCase() === "button") {
if (evt.target.id === "combine") {
numbers = combine(
+document.querySelector("#num1").value,
+document.querySelector("#num2").value );
if (numbers.combined > Number.MAX_SAFE_INTEGER) {
log (`${numbers.combined} too large, unraveled will be unreliable`);
} else {
log (`Combined ${numbers.a} and ${numbers.b} to ${numbers.combined}`);
}
} else {
log(`${numbers.combined} unraveled to ${numbers.unraveled}`);
}
}
}
})();
input[type=number] {width: 100px;}
<p>
<input type="number" id="num1"
value="12315" min="1"> first number
</p>
<p>
<input type="number" id="num2"
value="231091" min="1"> second number
</p>
<p>
<button id="combine">combine</button>
<button id="unravel">unravel</button>
</p>
<pre id="result"></pre>
Note: #RallFriedl inspired this answer
JSFiddle
Yes, you can, assuming your two integers don't contain more information than the one integer can handle.
Let's assume your tasks and sub tasks are in the range 1..255. Then you can encode
combined = (task * 256) + subtask
And decode
task = combined / 256
subtask = combined % 256
At first, you don't have to convert an integer to hexadecimal to do this. An integer is a value and decimal, hexadecimal or binary is a representation to visualize that value. So all you need is integer arithmetics to achieve your goal.
According to this answer the maximum allowed integer number in javascript would be 9007199254740991. If you write this down in binary you'll get 53 ones, which means there are 53 bits available to store within an integer. Now you can split up this into two or more smaller ranges as you need.
For example let's say you need to save three numbers, the first is always lower 4.294.967.296 (32-bit), the second always lower 65.536 (16-bit) and the third always lower 32 (5-bit). If you sum up all the bits of these three values, you'll get 53 bits which means it would perfectly match.
To pack all these values into one, all you need is to move them at the right bit position within the integer. In my example I'd like to let the 32 bit number on the lowest position, then the 16 bit number and at the highest position the 5 bit number:
var max32bitValue = 3832905829; // binary: 1110 0100 0111 0101 1000 0000 0110 0101
var max16bitValue = 47313; // binary: 1011 1000 1101 0001
var max5bitValue = 17; // binary: 1000 1
var packedValue = max32bitValue // Position is at bit 0, so no movement needed.
+ max16bitValue << 32 // Move it up next to the first number.
+ max5bitValue << 48; // Move it up next to the second number (32 + 16)
This single integer value can now be stored, cause is a perfectly valid javascript integer value, but for us it holds three values.
To get all three values out of the packed value, we have to pick the correct bits out of it. This involves two steps, first remove all unneeded bits on the lower side (by using shift right), then remove all unneeded bits on the higher side (by masking out):
var max32bitValueRead = packedValue & Math.pow(2, 32); // No bits on the lower side, just mask the higher ones;
var max16bitValueRead = (packedValue >> 32) & Math.pow(2, 16); // Remove first 32 bits and set all bits higher then 16 bits to zero;
var max5bitValueRead = (packedValue >> 48); // Remove first 48 bits (32 + 16). No higher bits there, so no mask needed.
So hope this helps to understand, how to put multiple integer values into one, if the ranges of these values don't exceed the maximum bit range. Depending on your needs you could put two values with 26 bits each into this or move the range like one 32 bit value and one 21 bit value or a 48 bit value and a 5 bit value. Just be sure what your maximum value for each one could be and set the width accordingly (maybe add one to three bits, just to be sure).
I wouldn't suggest using hexadecimal if you can not have 2 sequential numbers. Try converting to an ASCII character and then back. So if you wanted to send:
{ 'task': 21 }
You could set the 21 to a character like:
var a = 55; var b = String.fromCharCode(a); var send2 = { 'task': b };
And to convert it back it would be: var res = { 'task': b }; var original = res.task.charCodeAt();

Javascript check if character is 32bit

Using javascript, i want to check if a certain character is 32 bit or not ? How can i do it ? I have tried with charCodeAt() but it didn't work out for 32bit characters.
Any suggestions/help will be much appreciated.
The charCodeAt() docs returns integer between 0 to 65535 (FFFF) representing UTF-16 code unit.
If you want the entire code point value, use codePointAt(). You can use the string.codePointAt(pos) to easily check if a character is represented by 1 or 2 code point value .
Values greater than FFFF means they take 2 code units for a total of 32 bits.
function is32Bit(c) {
return c.codePointAt(0) > 0xFFFF;
}
console.log(is32Bit("𠮷")); // true
console.log(is32Bit("a")); // false
console.log(is32Bit("₩")); // false
Note: codePointAt() is provided in ECMAScript 6 so this might not work in every browser. For ECMAScript 6 support, check firefox and chrome.
function characterInfo(ch) {
function is32Bit(ch) {
return ch.codePointAt(0) > 0xFFFF;
}
let result = `character: ${ch}\n` +
`CPx0: ${ch.codePointAt(0)}\n`;
if(ch.codePointAt(1)) {
result += `CPx1: ${ch.codePointAt(1)}\n`;
}
console.log( result += is32Bit(ch) ?
'Is 32 bit character.' :
'Is 16 bit character.');
}
//For testing
let ch16 = String.fromCodePoint(10020);
let ch32 = String.fromCodePoint(134071);
characterInfo(ch16);
characterInfo(ch32);

Decomposing a value into results of powers of two

Is it possible to get the integers that, being results of powers of two, forms a value?
Example:
129 resolves [1, 128]
77 resolves [1, 4, 8, 64]
I already thought about using Math.log and doing also a foreach with a bitwise comparator. Is any other more beautiful solution?
The easiest way is to use a single bit value, starting with 1 and shift that bit 'left' until its value is greater than the value to check, comparing each bit step bitwise with the value. The bits that are set can be stored in an array.
function GetBits(value) {
var b = 1;
var res = [];
while (b <= value) {
if (b & value) res.push(b);
b <<= 1;
}
return res;
}
console.log(GetBits(129));
console.log(GetBits(77));
console.log(GetBits(255));
Since shifting the bit can be seen as a power of 2, you can push the current bit value directly into the result array.
Example
You can adapt solutions from other languages to javascript. In this SO question you'll find some ways of solving the problem using Java (you can choose the one you find more elegant).
decomposing a value into powers of two
I adapted one of those answers to javascript and come up with this code:
var powers = [], power = 0, n = 129;// Gives [1,128] as output.
while (n != 0) {
if ((n & 1) != 0) {
powers.push(1 << power);
}
++power;
n >>>= 1;
}
console.log(powers);
Fiddle
Find the largest power of two contained in the number.
Subtract from the original number and Add it to list.
Decrement the exponent and check if new 2's power is less than the number.
If less then subtract it from the original number and add it to list.
Otherwise go to step 3.
Exit when your number comes to 0.
I am thinking of creating a list of all power of 2 numbers <= your number, then use an addition- subtraction algorithm to find out the group of correct numbers.
For example number 77:
the group of factors is { 1,2,4,8,16,32,64} [ 64 is the greatest power of 2 less than or equal 77]
An algorithm that continuously subtract the greatest number less than or equal to your number from the group you just created, until you get zero.
77-64 = 13 ==> [64]
13-8 = 7 ==> [8]
7-4 = 3 ==> [4]
3-2 = 1 ==> [2]
1-1 = 0 ==> [1]
Hope you understand my algorithm, pardo my bad english.
function getBits(val, factor) {
factor = factor || 1;
if(val) {
return (val % 2 ? [factor] : []).concat(getBits(val>>1, factor*2))
}
return [];
}
alert(getBits(77));

Categories