I need help because if I try to write a number that has a whole bunch of zeroes, it will come out as num1Enum2.
ie: for a googol it would write "1E100".
I want it to actually write the number, rather than the shortened form. How would I do this?
Note: I want it to still be an integer rather than a string.
If you "write out" a number, you get a string. Period. "Writing out" means outputting a sequence of characters that represent the number. But that's what a string is: a sequence of characters.
A number like 1E100 is too big to represent as a normal-sized integer, even internally. To get a value that big as an integer, you'll have to use some sort of library to represent big integers. Search around for one. There are several, with names like "BigInt", "BigInteger", "BigNumber", "LongDecimal" and so on. They should all be able to store internally arbitrarily large integer values, and should all provide a way to turn that value into a string, which you can then write out. Pick one you like.
You could try a big number handling library, like big.js. Otherwise, your only solution will be to split your big numbers into arrays and write your own math functions to manipulate them -- something like this function to treat an array as an integer and increment it:
var longVal=[0];
// inherits global array longVal[]
// increments each element from right to left
function inc() {
for (var i=longVal.length - 1; i>=0; i--) {
if (++longVal[i] == 10) {
longVal[i] = 0;
if (!i) {
longVal.splice(0, 0, 0);
i++;
}
continue;
}
else break;
}
}
I think if you exceed the length limit of your array, you could probably change the if (++longVal[i] == 10) line to something like if (++longval[i] == 1000000000) for great justice, but you'd have to left pad each array element except the first with zeros to make it ten digits. I haven't tested that though. My answer is the concept, rather than the implementation.
Related
I'm making a bot for a gaming chatroom with some friends, but I've hit an impasse. Is there a reliable way to get numbers from inside a string of text that won't completely break an inexperienced script kiddy's brain? Here's the best I've been able to come up with so far, variables simplified slightly for illustration's sake:
var k = [0];
function dieRoll(m,n) {
for(i = 0; i < m; i++) {
k[i] = Math.floor(Math.random()*n)+1;
}
}
var m = text[5];
var n = text[7];
if (text === 'roll '+m+'d'+n) {
dieRoll(m,n)
console.log(k);
}
The biggest problem as-is is that it's limited to single-digit input.
EDIT: Looping through the text looking for integers is exactly the kind of thing I'm looking for. I don't have much experience with programming, so I probably tend to end up with overly complicated and confusing messes of spaghetti code that would embarrass anyone remotely professional. As for the format of the input I'm looking for, "roll [number of dice]d[highest number on the dice]". For anyone who doesn't know, it's the notation most tabletop rpgs use. For example, "roll 2d6" for two normal six-sided dice.
EDIT: It's not that I'm necessarily against regex, I just want to be able to understand what's going on, so that if and when I need to edit or reuse the code it I can do so without going completely insane.
EDIT: Thank you all very much! split() seems to be exactly what I was looking for! It'll probably take some trial and error, but I think I'll be able to get her working how she's supposed to this weekend (Yes I call my bots 'she').
Basically, you need to look at the format of the input you're using, and identify certain facts about it. Here are the assumptions I've taken based on your question.
1) The "roll" command comes first followed by a space, and
2) After the command, you are provided with dice information in the form xdy.
Here's something that should work given those constraints:
function getRollParameters(inputCommand) {
var inputWords = inputCommand.split(' '); //Split our input around the space, into an array containing the text before and after the space as two separate elements.
var diceInfo = inputWords[1]; //Store the second element as "diceInfo"
var diceDetails = diceInfo.split('d'); //Split this diceInfo into two sections, that before and after the "d" - ie, the number of dice, and the sides.
//assign each part of the dicedetails to an appropriate variable
var dice = diceDetails[0];
var sides = diceDetails[1];
//return our two pieces of information as a convenient object.
return {
"dice": dice,
"sides": sides
};
}
//a couple of demonstrations
console.log(getRollParameters("roll 5d8"));
console.log(getRollParameters("roll 126d2"));
Effectively, we're first splitting the string into the "command", and the "arguments" - the information we want. Then, we split our arguments up using the "d" as a midpoint. That gives us two numbers - the one before and the one after the d. Then we assign those values to variables, and can use them however we like.
This obviously won't deal with more creative or flexible inputs, and isn't tested beyond the examples shown but it should be a decent starting point.
I'm implementing a purpose-built regular expression engine using finite automata. I will have to store thousands of states, each state with its own transition table from unicode code points (or UTF-16 code units; I haven't decided) to state IDs.
In many cases, the table will be extremely sparse, but in other cases it will be nearly full. In most cases, most of the entries will fall into several contiguous ranges with the same value.
The simplest implementation would be a lookup table, but each such table would take up a great deal of space. A list of (range, value) pairs would be much smaller, but slower. A binary search tree would be faster than a list.
Is there a better approach, perhaps leveraging built-in functionality?
Unfortunately, JavaScript's built-in data-types - especially Map - are not of great help in accomplishing this task, as they lack the relevant methods.
In most cases, most of the entries will fall into several contiguous
ranges with the same value.
We can however exploit this and use a binary search strategy on sorted arrays, assuming the transition tables won't be modified often.
Encode contiguous input ranges leading to the same state by storing each input range's lowest value in a sorted array. Keep the states at corresponding indices in a separate array:
let inputs = [0, 5, 10]; // Input ranges [0,4], [5,9], [10,∞)
let states = [0, 1, 0 ]; // Inputs [0,4] lead to state 0, [5,9] to 1, [10,∞) to 0
Now, given an input, you need to perform a binary search on the inputs array similar to Java's floorEntry(k):
// Returns the index of the greatest element less than or equal to
// the given element, or undefined if there is no such element:
function floorIndex(sorted, element) {
let low = 0;
let high = sorted.length - 1;
while (low <= high) {
let mid = low + high >> 1;
if (sorted[mid] > element) {
high = mid - 1;
} else if (sorted[mid] < element) {
low = mid + 1;
} else {
return mid
}
}
return low - 1;
}
// Example: Transition to 1 for emoticons in range 1F600 - 1F64F:
let transitions = {
inputs: [0x00000, 0x1F600, 0x1F650],
states: [0, 1, 0 ]
};
let input = 0x1F60B; // 😋
let next = transitions.states[floorIndex(transitions.inputs, input)];
console.log(`transition to ${next}`);
This search completes in O(log n) steps where n is the number of contiguous input ranges. The transition table for a single state then has a space requirement of O(n). This approach works equally well for sparse and dense transition tables as long as our initial assumption - the number of contiguous input ranges leading to the same state is small - holds.
Sounds like you have two very different cases ("in many cases, the table will be extremely sparse, but in other cases it will be nearly full").
For the sparse case, you could possibly have a separate sparse index (or several layers of indexes), then your actual data could be stored in a typed array. Because the index(es) would be mapping from integers to integers, they could be represented as typed arrays as well.
Looking up a value would look like this:
Binary search the index. The index stores pairs as consecutive entries in the typed array – the first element is the search value, the second is the position in the data set (or the next index).
If you have multiple indexes, repeat 1 as necessary.
Start iterating your dataset at the position given by the last index. Because the index is sparse, this position might not be the one where the value is stored, but it is a good starting point as the correct value is guaranteed to be nearby.
The dataset itself is represented as a typed array where consecutive pairs hold the key and the value.
I cannot think of anything better to use in JavaScript. Typed arrays are pretty fast and having indexes should increase the speed drastically. That being said, if you only have a couple thousand entries, don't bother with indexes, do a binary search directly on the typed array (described in 4. above).
For the dense case, I am not sure. If the dense case happens to be a case where repeated values across ranges of keys are likely, consider using something like run-length encoding – identical consecutive values are represented simply as their number of occurrences and then the actual value. Once again, use typed arrays and binary search, possibly even indexes to make this faster.
firstly the language Im writing in is node (javascript) but really Im looking for the computer science behind it, and how to actually do it, not just the code.
Basically what I have is a 2,000 x 2,000 two dimensional array (what I mean by that is that every entry in the 2,000 entry long array has its own 2,000 entries). Inside this array I have values 0, 1, 2 3, etc. They are spaced out different, with different rarities as to how common each appears. What I want to do is generate this array based on a key, idc how long the key/seed is, just a reasonable length that can get the job done. I want the same key to generate the same array if its the same key and a different one if its a different key. Basically take a key and generate longer data from it but for no recognizable patterns to appear in this data.
My thoughts on this is to have a key that is a decimal of some sort I multiply against a bunch of constants to get a location in the array, but tbh I really have no Idea where to start. Essentially its like how minecraft takes a seed and turns it into map and the same seed will again generate an identical map.
Any random number generator (RNG) that can be seeded will give the same series of random values for a given seed & should have no determinable pattern. Unfortunately, the default RND for javascript is not seedable; as per this SE post, you will need to write your own or use a someone else's.
Once you have a seedable RNG, for each entry, first get a random value & then convert the random value into the desired output value. There's a number of different ways to do the conversion; if you only have a few, I would do something like this (assumes random_value is between 0 & 1):
if(rand_value <= 70){
output_value = 1;
}
else if(rand_value <= 90){
output_value = 2;
}
else if(rand_value <= 97){
output_value = 3;
}
else {
output_value = 4
}
This gives a 70%, 20%, 7% & 3% to get a 1,2,3 or 4 respectively; adjust the values as needed. Note: if you have many output values you should edit your question to reflect this, as there are cleaner ways to solve this than a giant if else block.
Here is a typical example of what I need to do
$testArr = array(2.05080E6,29400,420);
$stockArrays = array(
array(2.05080E6,29400,0),
array(2.05080E6,9800,420),
array(1.715E6,24500,280),
array(2.05080E6,29400,140),
array(2.05080E6,4900,7));
I need to identify the stockArray that is the least different. A few clarifications
The numeric values of array elements at each position are guaranteed not to overlap. (i.e. arr[0] will always have the biggest values, arr1 will be at least an order of 10 magnitude smaller etc).
The absolute values of the differences do not count when determining least different. Only, the number of differing array indices matter.
Positional differences do have a weighting. Thus in my example stockArr1 is "more different" thought it too - like its stockArr[0] & stockArr[3] counterparts - differs in only one index position because that index position is bigger.
The number of stockArrays elements will typically be less than 10 but could potentially be much more (though never into 3 figures)
The stock arrays will always have the same number of elements. The test array will have the same or fewer elements. However, when fewer testArr would be padded out so that potentially matching elements are always in the same place as the stockArray. e.g.
$testArray(29400,140)
would be transformed to
$testArray(0,29400,140);
prior to being subjected to difference testing.
Finally, a tie is possible. For instance my example above the matches would be stockArrays[0] and stockArrays[3].
In my example the result would be
$result = array(0=>array(0,0,1),3=>array(0,0,1));
indicating that the least different stock arrays are at indices 0 & 3 with the differences being at position 2.
In PHP I would handle all of this with array_diff as my starting point. For Node/JavaScript I would probably be tempted to the php.js array_diff port though I would be inclined to explore a bit given that in the worst cast scenario it is an O(n2) affair.
I am a newbie when it comes to Golang so I am not sure how I would implement this problem there. I have noted that Node does have an array_diff npm module.
One off-beat idea I have had is converting the array to a padded string (smaller array elements are 0 padded) and effectively do an XOR on the ordinal value of each character but have dismissed that as probably a rather nutty thing to do.
I am concerned with speed but not at all costs. In an ideal world the same solution (algorithm) would be used in each target language though in reality the differences between them might mean that is not possible/not a good idea.
Perhaps someone here might be able to point me to less pedestrian ways of accomplishing this - i.e. not just array_diff ports.
Here's the equivalent of the array_diff solution: (assuming I didn't make a mistake)
package main
import "fmt"
func FindLeastDifferent(needle []float64, haystack [][]float64) int {
if len(haystack) == 0 {
return -1
}
var currentIndex, currentDiff int
for i, arr := range haystack {
diff := 0
for j := range needle {
if arr[j] != needle[j] {
diff++
}
}
if i == 0 || diff < currentDiff {
currentDiff = diff
currentIndex = i
}
}
return currentIndex
}
func main() {
idx := FindLeastDifferent(
[]float64{2.05080E6, 29400, 420},
[][]float64{
{2.05080E6, 29400, 0},
{2.05080E6, 9800, 420},
{1.715E6, 24500, 280},
{2.05080E6, 29400, 140},
{2.05080E6, 4900, 7},
{2.05080E6, 29400, 420},
},
)
fmt.Println(idx)
}
Like you said its O(n * m) where n is the number of elements in the needle array, and m is the number of arrays in the haystack.
If you don't know the haystack ahead of time, then there's probably not much you can do to improve this. But if, instead, you're storing this list in a database, I think your intuition about string search has some potential. PostgreSQL for example supports string similarity indexes. (And here's an explanation of a similar idea for regular expressions: http://swtch.com/~rsc/regexp/regexp4.html)
One other idea: if your arrays are really big you can calculate fuzzy hashes (http://ssdeep.sourceforge.net/) which would make your n smaller.
Is this correct? using - http://en.wikipedia.org/wiki/Binomial_probability
Looks like values are from .0000000000000000 to .9999999999999999
Probability of happening twice = p^2 = (1/9999999999999999)^2 = 1.0 e-32
I think I am missing something here?
Also, how does being a pseudo random number generator change this calculation?
Thank You.
In an ideal world Math.random() would be absolutely random, with one output being completely independent from another, which (assuming p=the probability of any given number being produced) results in a probably of p^2 for any value being repeated immediately after another (as others have already said).
In practice people want Math.random to be fast which means pseudo-random number generators are used by the engines. There are many different kinds of PRNG but the most basic is a linear congruential generator, which is basically a function along the lines of:
s(n + 1) = some_prime * s(n) + some_value mod some_other_prime
If such a generator is used then you won't see a value repeated until you've called random() some_other_prime times. You're guaranteed of that.
Relatively recently however it's become apparent that this kind of behaviour (coupled with seeding the PRNGs with the current time) could be used for some forms tracking have led to browsers doing a number of things that mean you can't assume anything about subsequent random() calls.
I think the probability of getting two numbers in a row is 1 divided by the range of the generator, assuming that it has a good distribution.
The reason for this is that the first number can be anything, and the second number needs to just be that number again, which means we don't care about the first number at all. The probability of getting the same number twice in a row is the same as the probability of getting any particular number once.
Getting some particular number twice in a row, e.g. two 0.5s in a row, would be p^2; however, if you just care about any number twice in a row, it's just p.
If the numbers were truly random, you'd expect them, indeed, to appear with probability 1/p, so twice that would be 1/p^2.
The value for p is not exactly the one you have though, because the numbers are being represented internally as binary. Figure out how many bits of mantissa the numbers have in javascript and use that for your combinatoric count.
The "pseudorandom" part is more interesting, because the properties of pseudorandom number generators vary. Knuth does some lovely work with that in Seminumerical Algorithms, but basically most usual PN generators have at least some spectral distributiuon. Cryptograp0hic PN generators are generally stronger.
Update: The amount of time shouldn't be significant. Whether it's a millisecond or a year, as long as you don't update the state The probabilities will stay the same.
The probability that you would get 2 given numbers is (1/p)^2, but the probability that you get 2 of same numbers (any) is 1/p. That is because the first number can be anything, and the second just needs to match that.
You can kind of find out, just let it run a few days :)
var last = 0.1;
var count = 0 | 0;
function rand(){
++count;
var num = Math.random();
if(num === last){
console.log('count: '+count+' num: '+num);
}
last = num;
}
while(true) rand();