For word games, it is often the frequency of letters in English vocabulary, regardless of word frequency, which is of more interest.
1. >E 11.1607% 56.88 M 3.0129% 15.36
2. A 8.4966% 43.31 H 3.0034% 15.31
3. R 7.5809% 38.64 G 2.4705% 12.59
4. I 7.5448% 38.45 B 2.0720% 10.56
5. O 7.1635% 36.51 F 1.8121% 9.24
6. T 6.9509% 35.43 Y 1.7779% 9.06
7. N 6.6544% 33.92 W 1.2899% 6.57
8. S 5.7351% 29.23 K 1.1016% 5.61
9. L 5.4893% 27.98 V 1.0074% 5.13
10. C 4.5388% 23.13 X 0.2902% 1.48
11. U 3.6308% 18.51 Z 0.2722% 1.39
12. D 3.3844% 17.25 J 0.1965% 1.00
13. P 3.1671% 16.14 Q 0.1962% (1) <-
The third column represents proportions, taking the least common letter (q) as equal to 1. The letter E is over 56 times more common than Q in forming individual English words.
How is it possible to build an algorithm is javascript such that if I generate say 100 letters, 11-12% of then i.e. 11-12 letters will be E and so on.
Here's an algorithm:
Split the range [0, 1) in intervals that each matches a letter and has a size proportional to its probability. Eg
0 - 0.116: E
0.116 - 0.201: A
…
Get a random number between 0 and 1
Pick the interval that contains this number
Get the associated letter
Related
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.
I was doing this question in leetcode.
Request:
Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.
I can't understand the solution it gave
Could someone explain how this getSum function works?
Here is the answer in JS:
var getSum=function(a,b) {
const Sum = a^b; //I can't understand how those two line's code can
const carry = (a & b) << 1; //get the sum
if(!carry) {
return Sum
}
return getSum(Sum,carry);
};
console.log(getSum(5,1));
It's basically replicating the half-adder
Adding 2 bits A and B produces 2 outputs: a sum and a carry bit like below
╔═══════╤═════════════╗
║ Input │ Output ║
╠═══╤═══╪═══════╤═════╣
║ A │ B │ carry │ sum ║
╟───┼───┼───────┼─────╢
║ 0 │ 0 │ 0 │ 0 ║
╟───┼───┼───────┼─────╢
║ 1 │ 0 │ 0 │ 1 ║
╟───┼───┼───────┼─────╢
║ 0 │ 1 │ 0 │ 1 ║
╟───┼───┼───────┼─────╢
║ 1 │ 1 │ 1 │ 0 ║
╚═══╧═══╧═══════╧═════╝
From the table we get the logic for the outputs: carry = A and B, sum = A xor B
XOR is also called a carry-less add operator, and represented by ⊕ with the + symbol inside
So the snippet above is working like this
const Sum=a^b; // sum = a xor b = a ⊕ b
const carry=(a&b)<<1; // carry = 2*(a and b), since we carry to the next bit
if(!carry){
return Sum; // no carry, so sum + carry = sum
}
return getSum(Sum,carry); // a + b = sum + carry
So a^b adds each bit in a and b simultaneously, leaving the non-carry sum of a and b in Sum. Then we have to add carry to the carry-less sum to get the final result, since we have only a half-adder instead of a full-adder which does a + b = a ⊕ b + carry
See also
Adding two numbers without + operator (Clarification)
What is the best way to add two numbers without using the + operator?
adds two numbers without using + or any arithmetic operators
Adding two numbers without using the addition operator
Let's learn by example. Imagine that a = 3 and b = 5
In binary notation they are a = 0011 and b = 0101
XOR:
a^b is XOR operator. When compare two bits it returns 0 if they are same and 1 if they are different. 01^10 => 11
So when we're doing a^b result will be 0110.
AND + SHIFT
a&b performs logical AND operation. It returns 1 only when a = b = 1.
In our case the result is 0001
<< shifts it(adds 0 on the right side) and result became 0010 which sets carry variable true. (only 0000 will be false).
Next iterations:
Everything repeats but now a = 0110 and b = 0010 (Sum and carry from last execution)
Now a^b = 0100 and (a&b)<<1 = 0100
Repeating again.
Now a^b = 0000 and (a&b)<<1 = 1000
And again.
Now a^b = 1000 and (a&b)<<1 = 0000. Now carry is finally false. And we're returning 1000 which is decimal 8.
Everything worked fine since 3+5=8
int result = p ^ q; // XOR Operator, + without carry 0+0=0, 0+1=1+0=1, 1+1=0
int carry = (p & q) << 1; // Left Shift, 1+1=2
if (carry != 0) {
return getSum(result, carry);
}
return result;
Start By p=5,q=6. Then the XOR would be,
0101
0110
------
0011
So, XORing results in (0011) which is actually 3 in decimal. Then ANDing p and q we get,
0101
0110
-------
0100
We get 4 (100 in binary) by ANDing 5 & 6, now if we left shift this value by 1, we get
0100<<1=1000
So we get 8 (1000 in binary) after first recursion.As the result (carry variable) isnt zero, lets recursion again by xor value and carry value.
getSum(3, 8);
So, doing the first XORing we get,
0011
1000
-------
1011
The XORing this time yielded in 11 (1011 binary),so we perform the AND now,
0011
1000
-------
0000
We get all ZERO for ANDing 3 and 8, so this time the left shift operator also results in ZERO, as we have no 1 here which may give us a value by left shifing zeroes.
As the carry variable is now Zero, we come to the end of recursion and the XORed value will be the Sum, which is 11 (1011 in Binary).
Hope you get the working of the procedure. You can learn more by learning bitwise operation, as its the way the machine do the arithmatic operations.
^ is XOR, a bitwise operation. On a single bit, the rules are 0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 0, and 1 ^ 1 = 0, and you simply extend perform it on corresponding bits when dealing with multi-bit values. The name is short for "exclusive or", and comes from the fact that A ^ B is 1 if and only if either A or B is 1, not both. But, it's more interesting to talk about its other name, ⊕. ⊕ is + but slightly different. You'll notice that the rules for ⊕ are similar to the rules for addition: 0 + 0 = 0, 0 + 1 = 1, 1 + 0 = 1, and 1 + 1 = 10. ⊕ is +, except 1 ⊕ 1 = 0; that is, ⊕ is +, except without carrying. This holds for multiple bits: 011 + 001 = 100, because you carry a 1 out of the ones place into the twos place, and then carry a 1 again into the fours place. Then, 011 ⊕ 001 = 010, because you just don't carry.
Now, when doing real addition, when do you carry? In binary, the answer is very simple: you carry a 1 into the next place when there are two 1s in a given place. This is easily understood as a bitwise AND, &. 1 & 1 = 1, and 0 otherwise. For 011 + 001, addition without carrying gives 011 ⊕ 001 = 010, and we can tell we need to carry a 1 out of the ones place because 011 & 001 = 001. The shifting in (a & b) << 1 turns a number "where do I need to carry from?" into "where do I need to add carries?": (011 & 001) << 1 = 010; I need to add a carry bit in the twos place.
So, in getSum, we want to know a + b. We compute the addition without carrying with a ^ b, and we find where we need to add carry bits with (a & b) << 1. Now, we just need to add those two together. Well, we already have a function for adding numbers together; it's called getSum. So, we basically just write function getSum(a, b) { return getSum(a ^ b, (a & b) << 1); }, except we make sure to short-circuit if there is nothing to carry, saving us from infinite recursion.
Say you have an alphabet that has these characters in this order:
abcdefghijklmnopABCDEFG123456789
You want to then increment them to an arbitrary length. So it starts off with just 1 character, then 2, then 3, then ... n.
a
b
c
...
A
B
C
...
1
2
3
...
aa
ab
...
aA
aB
...
ba
bb
bc
...
bA
bB
...
za
zb
...
1a
1b
...
aaa
aab
aac
...
aba
abb
abc
...
aAa
aAb
...
So it increments the right-most first, then the next to the left, then left of that, etc.
It is kind of tricky. Wondering how to do this.
Wondering how to do it such that it can take any alphabet, and construct it up to any length, so it's generic.
function getStringAtIndex(index, alphabetArray) {
}
Or perhaps it can be done in a different way, I'm not sure.
#tehhowch is exactly right, instead of doing hex (base 16), you're essentially wanting to do base-n math. With the character set you specified, this would be base-33 math (if you include the 0 character)
Every decimal place represents n^x power. It's easy with decimal. 100 is 10^2, and 1000 is 10^3. And that's what a logarithm is: log(1000) base 10 = 3, because 10^3 = 1000.
Fortunately we can get a log of any base by doing log(n)/log(base). Hence the following function:
function convert(number) {
var chars = '0abcdefghijklmnopABCDEFG123456789',
base = chars.length, i = number, str = '',
exp = Math.floor(Math.log(i)/Math.log(base))+1;
while(exp--) {
var bexp = Math.pow(base, exp);
var j = Math.floor(i/bexp);
i -= j*bexp;
str += chars[j];
}
return str;
}
convert(90014234); // "bi62Gb"
convert(791424) // "F01B"
convert(23423); // "Ep3"
convert(33); // "a0"
You can verify the method by using a more common character set, like hexadecimal (base 16), and making sure the numbers come out right. You'd substitute var chars = '0123456789abcdef' in the function. Then we specify a hex number and make sure our output matches:
convert(0xdd5439af); // "dd5439af"
I am working on a kata that asks for the last digit of a[0] ^ (a[1] ^ (a[2] ^ ... (a[n-1] ^ a[n]))). When computing the answer, eventually Math.pow exceeds Number.MAX_SAFE_INTEGER, causing modexp below to return erroneous results.
#user2357112 says that JS needs a library for arbitrary-precision integers, which is all well and good, but nothing in the kata indicates that such a library is available in the remote environment, or even that I need one.
Since the kata and SO point in different directions on this matter, I want to learn if I can feasibly represent big integers ONLY for the purposes of solving this kata without writing an entire library.
My in-progress code is below, and it passes many tests before printing incorrect results. Some code was omitted to avoid spoilers.
TL;DR: If I cannot use a library, what can I do to feasibly represent large integers for the use case indicated by Math.pow()?
function modexp(b, e) {
let c = 1
while(e) {
if (e & 1)
c = c * b % 10
e >>= 1
b = b * b % 10
}
return c;
}
function lastDigit(as) {
if (!as || !as.length) return 1;
let e = as.slice(1).reverse().reduce((p,c) => Math.pow(c,p));
return modexp(as[0], Number(e));
}
This is obviously an X-Y problem. You don't need large integers.
You need to go back to elementary school math.
What's multiplication? Well let's take one example:
WARNING: SPOILERS! Don't read the following if you want to figure it out yourself!
1 2
x 2 3
------
3 6 last digit 6
2 4
------
2 7 6 notice how last digit is only involved
in ONE multiplication operation?
Hmm.. there seems to be a pattern. Let's see if that pattern holds. Let's multiply 12 x 23 x 23 by only doing the last digit:
1 2
x 2 3
------
6 calculate ONLY last digit
x 2 3
------
8 answer is: last digit is 8
Let's check our answer:
1 2
x 2 3
------
3 6
2 4
------
2 7 6
x 2 3
------
8 2 8
5 5 2
-------
6 3 4 8 last digit is INDEED 8
So it seems that you can find the last digit by only calculating the last digit. Let's try to implement a powLastDigit() function.
WARNING: SPOILERS! DON'T READ THE CODE IF YOU WANT TO WRITE IT YOURSELF!
function powLastDigit (number,power) {
var x = number;
for (var y=1; y<power; y++) {
x = ((x%10)*(number%10))%10; // we only care about last digit!
}
return x;
}
Let's check if we are right:
> powLastDigit(3,7)
7
> Math.pow(3,7)
2187
> powLastDigit(5,8)
5
> Math.pow(5,8)
390625
> powLastDigit(7,12)
1
> Math.pow(7,12)
13841287201
OK. Looks like it's working. Now you can use this function to solve your problem. It has no issues with very large exponents because it doesn't deal with large numbers:
> powLastDigit(2323,123456789)
3
Optimization
The above code is slow because it uses a loop. It's possible to speed it up by using Math.pow() instead. I'll leave that as a homework problem.
I use bit array to represent a positive integer;
[0,0,1,1] // bit array of 12 (MSB=rightmost)
This structure is used to manipulate the overall exponent, E
a[1] ^ (a[2] .. (a[n-1] ^ a[n])) // E
(!)There is a relation between LSD(a[0]) and the overall exponent E as below
//LSD(a[0]) LSD(LSD(a[0]) ^ E) for
// [E/4R0, E/4R1, E/4R2, E/4R3]
//--------- ----------------------------
// 0 [0, 0, 0, 0]
// 1 [1, 1, 1, 1]
// 2 [6, 2, 4, 8]
// 3 [1, 3, 9, 7]
// 4 [6, 4, 6, 4]
// 5 [5, 5, 5, 5]
// 6 [6, 6, 6, 6]
// 7 [1, 7, 9, 3]
// 8 [6, 8, 4, 2]
// 9 [1, 9, 1, 9]
For example, find least significant digit of (2 ^ (2 ^ 3)),
// LSD(a[0]) is 2
// E is 8
// implies E mod 4 is 0
// LSD(LSD(a[0]) ^ E)
// for E/4R0 is 6 (ans)
To determine E mod 4,
E[0] + E[1] * 2 // the two LSBs
To summarize, I create a data structure, bit array, to store large integers,
mainly for the intermediate value of exponent-part. The bit array is dynamic length obtaining max. 9007199254740991 bits, if all bits are set, the value in decimal is 2 ^ (9007199254740991 + 1) - 1. This bit array will never be converted back to decimal(safe). The only interesting information of overall exponent, E, is its two least significant bits, they are the remainder of E/4
which can be applied to the above relation(!).
Obviously, Math.pow will not work for bit array, so I handcraft a simple exp() for it. This is trivial since the fact that
//exponentiation == lots of multiplications == lots of additions
//it is not difficult to implement addition on bit array
This is the fiddle demonstrating above idea ONLY. It is intended to be slow if the E is really large. FYI
LSD.find([3,4,5,6]) // my Nightly hanged ~3s to find lsd
You may optimize the Bits.exp by means of childprocesses, web workers, debounce function, simd etc. Good luck.
You don't really need a bigint library to solve this kata.
You are only interested in the last digit of the result, and fortunately there is a property of powers that helps us with this. We effectively want to compute a power in modulus 10. Yes, modular exponentiation does help us a bit here, but the problem is that the exponent is very large as well - too large to compute, and too large to run a loop with that many iterations. But we don't need to, all we are interested in is the modulus of the result.
And there is a pattern! Let's take 4x as an example:
x 4^x (4^x)%10
--------------------------
0 4^0 = 1 1
1 4^1 = 4 4
2 4^2 = 16 6
3 4^3 = 64 4
4 4^4 = 256 6
5 4^5 = 1024 4
… …
20 4^20 = ??? 6 sic!
21 4^21 = ??? 4
… …
You will be able to find these patterns for all numbers in all modular bases. They all share the same characteristic: there's a threshold below which the remainder is irregular, and then they form a repeating sequence. To get a number in this sequence, we only need to perform a modulo operation on the exponent!
For the example above ((4^x)%10), we use a lookup table 0 → 6, 1 → 4 and compute x % 2; the threshold is 1. In JavaScript code, it might look like this:
x < 1 ? 1 : [6, 4][x % 2];
Of course, x is a very large number formed by the repeated exponentiation of the rest of the input, but we do not need to compute it as whole - we only want to know
whether it is smaller than a relatively small number (trivial)
what the remainder after division by q is - just a recursive call to the function we're implementing!
I'm currently trying to realize a very simple example of genetic algorithms.
At one point, you have to do a "Cross-Over" (biology) with two numbers (parents) to get a "child".
You can find an explanation of Cross-Over here:
How to "crossover" two strings (1234 & abcd -> 12cd & ab34)
(The second illustration, the easier "one-point" Cross-Over is the one I'm trying to do.)
The chromosomes (parents and child) are numbers but the "Cross-Over" will be a bit operation.
I found a solution for one of the "chromosomes", which is the following :
Move the bits X amount to the right (>>> operator )
and then move the bits again X positions but this time to the left (<< operator)
So this would keep the end of one of the chromosomes and fill the beginning with 0s.
But I don't really know how to solve the problem of the other chromosome and then also do the Cross-Over.
(Probably a XOR once I kept the beginning / end of the chromosomes and filled the rest with 0s.)
Or should I even approach this problem from another angle?
If the fraction of the Cross-Over is p (e.g., p = .25), then this should work:
mask1 = ((0xffff >> 16*p) << 16*p)
mask2 = 0xffff ^ mask1
output1 = (input1 & mask1) ^ (input2 & mask2)
output2 = (input1 & mask2) ^ (input2 & mask1)
A couple of notes:
This is just pseudocode. You might want some casts in there.
This treats p differently than you treat it in your comment above. (Just replace p with 1-p to get to your definition of p.)
A naive approach would be to use 4 local variables:
int chromatid1Start;
int chromatid1End;
int chromatid2Start;
int chromatid2End;
Then, assign the incoming chromatid1 to the first two variables and chromatid2 to the last two variables.
chromatid1Start = chromatid1;
chromatid1End = chromatid1;
chromatid2Start = chromatid2;
chromatid2End = chromatid2;
Perform a right-shift on the Start chromatid variables up to the crossover point, then left-shift the exact same amount. On the End chromatid variables, left-shift up to the crossover point, then right-shift the exact same amount.
chromatid1Start = (chromatid1Start >> 16 * crossoverPercent) << 16 * crossoverPercent;
chromatid1End = (chromatid1End << 16 * (1 - crossoverPercent)) >> 16 * (1 - crossoverPercent);
chromatid2Start = (chromatid2Start >> 16 * crossoverPercent) << 16 * crossoverPercent;
chromatid2End = (chromatid2End << 16 * (1 - crossoverPercent)) >> 16 * (1 - crossoverPercent);
With that, you can cross the start of one with the end of the other:
int daughterChromatid1 = chromatid1Start + chromatid2End;
int daughterChromatid2 = chromatid2Start + chromatid1End;