How do I sort an array of words that represent numbers? - javascript

How can we Sort numbers in words (one, two, three) in Javascript (Angularjs)
My array has some numeric words
$scope.Numbers = ["three", "one", "five", "two", ...... "hundred", "four"];
I want the result to be:
one
two
three
four
...
...
...
hundred
I have searched Google for the solution, but I have not found anything
Also i have tried array.sort(), but it is sorting alphabetically.

Here is a simple multi-step solution:
convert the words to numbers.
Sort the array with .sort(function(a,b){ return a-b; }).
convert the array back to words.
We effectively reduced the problem of sorting words to the problem of sorting numbers and the problem of converting numbers to and from words.
The greater picture is that by reusing the solutions of 3 smaller problems we solved a bigger issue. This is a fundamental part of programming anywhere and here in particular - by finding smaller subproblems and applying them to the task at hand we've solved it quickly and without ever having to actually implement a sorting function on words themselves.

Going to elaborate a bit on what people have written in the comments for you. Simply put, the compiler can't know which word is higher or lower than any other, since words are just a collection of chars. It's pretty much like saying: Which word has a higher value, "chicken" or "car"? Or how can the compiler know that you are even writing in English? What happens if you write the numbers in words but in other languages? Basically, to the compiler each string is a set of chars and it doesn't care which letters or words they are since it doesn't matter from its point of view. If you compare it to a number instead, a number is a legit structure which has properties and mathematical rules to follow. I believe this is the reason people are downvoting your question.
There is no basis for a sorting algorithm to start. Thus, you need to convert the strings to integers first, then sort them, and then convert them back to strings if you want to have them ordered - just like Benjamin above explained.

Related

How can I convert this UTF-8 string to plain text in javascript and how can a normal user write it in a textarea [duplicate]

While reviewing JavaScript concepts, I found String.normalize(). This is not something that shows up in W3School's "JavaScript String Reference", and, hence, it is the reason I might have missed it before.
I found more information about it in HackerRank which states:
Returns a string containing the Unicode Normalization Form of the
calling string's value.
With the example:
var s = "HackerRank";
console.log(s.normalize());
console.log(s.normalize("NFKC"));
having as output:
HackerRank
HackerRank
Also, in GeeksForGeeks:
The string.normalize() is an inbuilt function in javascript which is
used to return a Unicode normalisation form of a given input string.
with the example:
<script>
// Taking a string as input.
var a = "GeeksForGeeks";
// calling normalize function.
b = a.normalize('NFC')
c = a.normalize('NFD')
d = a.normalize('NFKC')
e = a.normalize('NFKD')
// Printing normalised form.
document.write(b +"<br>");
document.write(c +"<br>");
document.write(d +"<br>");
document.write(e);
</script>
having as output:
GeeksForGeeks
GeeksForGeeks
GeeksForGeeks
GeeksForGeeks
Maybe the examples given are just really bad as they don't allow me to see any change.
I wonder... what's the point of this method?
It depends on what will do with strings: often you do not need it (if you are just getting input from user, and putting it to user). But to check/search/use as key/etc. such strings, you may want a unique way to identify the same string (semantically speaking).
The main problem is that you may have two strings which are semantically the same, but with two different representations: e.g. one with a accented character [one code point], and one with a character combined with accent [one code point for character, one for combining accent]. User may not be in control on how the input text will be sent, so you may have two different user names, or two different password. But also if you mangle data, you may get different results, depending on initial string. Users do not like it.
An other problem is about unique order of combining characters. You may have an accent, and a lower tail (e.g. cedilla): you may express this with several combinations: "pure char, tail, accent", "pure char, accent, tail", "char+tail, accent", "char+accent, cedilla".
And you may have degenerate cases (especially if you type from a keyboard): you may get code points which should be removed (you may have a infinite long string which could be equivalent of few bytes.
In any case, for sorting strings, you (or your library) requires a normalized form: if you already provide the right, the lib will not need to transform it again.
So: you want that the same (semantically speaking) string has the same sequence of unicode code points.
Note: If you are doing directly on UTF-8, you should also care about special cases of UTF-8: same codepoint could be written in different ways [using more bytes]. Also this could be a security problem.
The K is often used for "searches" and similar tasks: CO2 and CO₂ will be interpreted in the same manner, but this could change the meaning of the text, so it should often used only internally, for temporary tasks, but keeping the original text.
As stated in MDN documentation, String.prototype.normalize() return the Unicode Normalized Form of the string. This because in Unicode, some characters can have different representation code.
This is the example (taken from MDN):
const name1 = '\u0041\u006d\u00e9\u006c\u0069\u0065';
const name2 = '\u0041\u006d\u0065\u0301\u006c\u0069\u0065';
console.log(`${name1}, ${name2}`);
// expected output: "Amélie, Amélie"
console.log(name1 === name2);
// expected output: false
console.log(name1.length === name2.length);
// expected output: false
const name1NFC = name1.normalize('NFC');
const name2NFC = name2.normalize('NFC');
console.log(`${name1NFC}, ${name2NFC}`);
// expected output: "Amélie, Amélie"
console.log(name1NFC === name2NFC);
// expected output: true
console.log(name1NFC.length === name2NFC.length);
// expected output: true
As you can see, the string Amélie as two different Unicode representations. With normalization, we can reduce the two forms to the same string.
Very beautifully explained here --> https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize
Short answer : The point is, characters are represented through a coding scheme like ascii, utf-8 , etc.,(We use mostly UTF-8). And some characters have more than one representation. So 2 string may render similarly, but their unicode may vary! So string comparrision may fail here! So we use normaize to return a single type of representation
// source from MDN
let string1 = '\u00F1'; // ñ
let string2 = '\u006E\u0303'; // ñ
string1 = string1.normalize('NFC');
string2 = string2.normalize('NFC');
console.log(string1 === string2); // true
console.log(string1.length); // 1
console.log(string2.length); // 1
Normalization of strings isn't exclusive of JavaScript - see for instances in Python. The values valid for the arguments are defined by the Unicode (more on Unicode normalization).
When it comes to JavaScript, note that there's documentation with String.normalize() and String.prototype.normalize(). As #ChrisG mentions
String.prototype.normalize() is correct in a technical sense, because
normalize() is a dynamic method you call on instances, not the class
itself. The point of normalize() is to be able to compare Strings that
look the same but don't consist of the same characters, as shown in
the example code on MDN.
Then, when it comes to its usage, found a great example of the usage of String.normalize() that has
let s1 = 'sabiá';
let s2 = 'sabiá';
// one is in NFC, the other in NFD, so they're different
console.log(s1 == s2); // false
// with normalization, they become the same
console.log(s1.normalize('NFC') === s2.normalize('NFC')); // true
// transform string into array of codepoints
function codepoints(s) { return Array.from(s).map(c => c.codePointAt(0).toString(16)); }
// printing the codepoints you can see the difference
console.log(codepoints(s1)); // [ "73", "61", "62", "69", "e1" ]
console.log(codepoints(s2)); // [ "73", "61", "62", "69", "61", "301" ]
So while saibá e saibá in this example look the same to the human eye or even if we used console.log(), we can see that without normalization when comparing them we'd get different results. Then, by analyzing the codepoints, we see they're different.
There are some great answers here already, but I wanted to throw in a practical example.
I enjoy Bible translation as a hobby. I wasn't too thrilled at the flashcard option out there in the wild in my price range (free) so I made my own. The problem is, there is more than one way to do Hebrew and Greek in Unicode to get the exact same thing. For example:
בָּא
בָּא
These should look identical on your screen, and for all practical purposes they are identical. However, the first was typed with the qamats (the little t shaped thing under it) before the dagesh (the dot in the middle of the letter) and the second was typed with the dagesh before the qamats. Now, since you're just reading this, you don't care. And your web browser doesn't care. But when my flashcards compare the two, then they aren't the same. To the code behind the scenes, it's no different than saying "center" and "centre" are the same.
Similarly, in Greek:
ἀ
ἀ
These two should look nearly identical, but the top is one Unicode character and the second one is two Unicode characters. Which one is going to end up typed in my flashcards is going to depend on which keyboard I'm sitting at.
When I'm adding flashcards, believe it or not, I don't always type in vocab lists of 100 words. That's why God gave us spreadsheets. And sometimes the places I'm importing the lists from do it one way, and sometimes they do it the other way, and sometimes they mix it. But when I'm typing, I'm not trying to memorize the order that the dagesh or quamats appear or if the accents are typed as a separate character or not. Regardless if I remember to type the dagesh first or not, I want to get the right answer, because really it's the same answer in every practical sense either way.
So I normalize the order before saving the flashcards and I normalize the order before checking it, and the result is that it doesn't matter which way I type it, it comes out right!
If you want to check out the results:
https://sthelenskungfu.com/flashcards/
You need a Google or Facebook account to log in, so it can track progress and such. As far as I know (or care) only my daughter and I currently use it.
It's free, but eternally in beta.

Working with transfinite ordinals in JavaScript

I'm attempting to program a transfinite ordinal calculator in JavaScript. In other words, find a way to process ordinal arithmetic in js.
I'm planning on using ES6's classes, with some form of constructor, and methods for processing comparisons of terms and operations such as addition or multiplication over the set of ordinals. The problem is that I don't know where to start. I need firstly a way to store ordinals in an instance of an Ordinal class, and a way of comparing to Ordinals. After that point everything should be smooth sailing.
If anyone could provide any insight into how I might approach this, I'd greatly appreciate it.
In the last 6 months I've found several methods of storing ordinals, these include:
Cantor Normal Form as an array
Extended Cantor Normal Form as nested arrays of pairs
An ordinal notation (known as TAN) developed by a member of the Googology community
Veblen's Hierarchy of Fixed Points
An ordinal collapsing function
Disclaimer: I use a common convention when writing out ordinals. I use w to represent omega, the least transfinite ordinal; e to represent the epsilon numbers (fixed points of a -> w^a) or the function enumerating them; similarly, in the case of Veblen's Hierarchy I'll use phi to denote such for ordinal collapsing functions I'll use psi. When explaining how operations work I'll use this to denote the first operand and other to denote the second.
Cantor Normal Form expresses ordinals as the sum of terms in the form w^b * a and therefore has a limit of w^w, intuitively it can be expressed as an array, where the i'th element of the term represents the a in the term w^i * a, e.g. the array [4, 5, 6] represents the ordinal w^2*6 + w*5 + 4. Adding is simple enough. Based on the principle that 1 + w = w, w + w^2 = w^2 and so on, we can fill the array with 0s up to the other.length - 1'th element and then add the elements in other to their corresponding elements in this. Multiplication is more tricky. If other contains multiple non-zero elements, we can use the distributive law (which doesn't apply the other way) and return the sum of this multiplied by each of other's terms. Otherwise, if this has multiple non-zero elements, if other is finite (other.length == 1) then multiply the most significant term of this by other and return other. In the final case ignore all but the most significant term of this and multiply by other. And if both operands have only one term then shift a bunch of 0s into this (specifically other.length - 1) and return this. Exponentiation is trivial then as other must be finite otherwise the result would surpass the range of this method, and can just be done by iterating multiplication, because I'm lazy and can do better later.
Extended Cantor Normal Form is similar, though the exponents for each term can also be ordinals, which complicates things, though extends the limit of this to e0 (the least fixed point of a -> w^a. We can store ordinals as an array of pairs. The first element of the pair can be coefficient of the terms and the second element is the exponent, represented by another array of pairs. The first thing that needs to be addressed in this form would be normalization. Firstly you'd need to remove all terms which are 0, then iterate through the array and keep track of the largest exponent, if you encounter an element with a lower exponent that the current highest you'd splice it out of the array. Once this is done you check for terms with the same exponent and add the coefficient of the other to one, removing the other. The array will then be normalized (there's probably a more efficient way to do this, leave a comment). Addition follows then become trivial. Simply concatenate the arrays of other and this and normalize. Multiplication is similar to before. If other.length > 1 then we can use the distributive law (which doesn't apply the other way) and return the sum of this multiplied by each of other's terms. Otherwise, if this has multiple terms, if other is finite then multiply the most significant term of this by other and return other. In the final case ignore all but the most significant term of this and multiply by other. Then simply add the exponent of other's only term to this's only term and return this. Exponentiation is no longer trivial, but isn't difficult. Firstly, remove all but the most significant term from this, then multiply the exponent by other. Done.
A member of the Googology* community, TGR, created TAN as an extremely powerful array notation for generating large numbers, though it was essentially the fast growing hierarchy with an array-like ordinal notation. The ordinal notation isn't exactly well defined, though it can be understood well enough. TAN. Note that I would only code the arrays without 'separators' for simplicity. Ordinals can be stored as arrays where elements are either arrays or integers. Normalization can be done by popping 0s off the end of the array and checking if any elements have greater value than the outer array (without that element), if they are, then remove the outer array. This is as each of the elements of the arrays enumerates as a function of the form a + b, a * w^b, e, phi_2, phi_3 etc, and such an array just as [0, 0, [0, 0, 0, 1]] would be e(psi_2(0)) which is simply equal to phi_2(0) as phi_2(0) is a fixed point of the function enumerating the epsilon numbers. Adding in this notation is simple, take the first element of the this, and then the first element of that, and so on until we get to an integer, then if other is finite simply add it on, if other is transfinite then replace the integer in this. Multiplying is similar, though you instead increase the second term. Again applying the distributive law when necessary, and making sure that it is recognized that increasing the second element by a is the same as multiplying by w^a. As mentioned above, exponentiating is the same as multiplying the exponent and then removing the added part. This was my favourite method of storing ordinals because it's rather unique and interesting, and has a high limit which is easy to achieve.
The other two notations are likely possible, and I've had ideas for how to do so. Veblen Hierarchy could be stored similarly to TAN though storing an array of terms like CNF and ECNF, and each term is an array in Veblen Style, though each element must also be an array of terms to allow the ability to store all ordinals. Ordinal collapsing functions would be more difficult, I propose storing the symbolic string as an abstract syntax tree, the primary issue would be normalization as that could get out of control very easily,
*the study and nomenclature of large finite numbers, though as fast growing and other ordinal hierarchies play an important role in such, there is a large variety of ordinal notation developed, though most would be incredibly difficult to program.

Regex for finding all the numbers between any two numeric values (range) in JavaScript [duplicate]

This question already has answers here:
How to match numbers between X and Y with regexp?
(7 answers)
Closed 7 years ago.
First of all, i know Regular expressions isn't the best tool to achieve what I want here. I have done enough research to know that bit. Still, The problem I am stuck in requires me to make up a regex to find the values between some lower and upper bound values.
So here is the problem, I have a large set of data, let's say ranging between 1 and 1000000. That data is not under my direct control, I cannot manipulate the data directly. Only way of finding out (searching) some values from that data is regex.. Now, the user can give two values, a minimum value and a maximum value and I need to construct a regex based on these two values and then query the large data set using the regex to get all the values lying between the set range. So, if my data contains [1,5,7,9,15,30,45,87] and user sets the range min:10, max:40. The regex should filter out values 15, 30.
From whatever I have searched, I know it is very much possible to build a regex for finding out values between fixed values (if we know them beforehand) for example, values between 1 to 100 can be found by:
^(100|[1-9][0-9]?)$
But what gets so tricky about my problem is that the input range can be anything from pretty much 1 digit values to up to 10 digit values. 10000-550000 can be an example user input for a large data set.
I know this will require some complex logic and loops involved on the basis of number of digits in the lower bound and number of digits in the upper bound of the range and then some recursive or other magical logic to build a regex that covers all the number lying in that range.
I've been filling up pages to come up with a logic but I'm afraid it surpasses my knowledge of regex. If anyone has ever done something like this before or try to point me in the right direction or attempt it him/herself - it'll be quite helpful. Thanks.
The language I will be using this in is JavaScript and I read somewhere that JS doesn't support conditional regex, keeping that in mind, solution doesn't have to be in specific to a language.
If your task is to get numbers between min and max value from the dataset, you can try filter method.
Var filteredResults = Dataset.filter(function(item){
If(item < max && item > min)
Return item
}
)

Make large numbers worth less than small numbers (JS)

I need to find out how to make smaller numbers worth more than bigger numbers, and vice versa. For example, if I have numbers 1-5, I want 5 to be worth the least and 1 to be worth the most. I can't seem to find something on this topic, so it's either impossible or, I just don't quite know how to phrase the search. Either way, I didn't want to be too specific so my question can be applicable to to others, but this is a coding question I am having issues with in my game.. Thanks in advance!
You can try sorting in descending order? If the numbers are in an array the following would sort them in that order:
var arr = [1,2,3,4,5];
arr.sort(function(a,b) {
return b - a;
});
You really need to be clear about what you mean by "worth less". Are you trying to make (1<5) evaluate to false? If so, there are much much better ways of doing it.
One trick though -- you can just multiply everything by -1.

word decoder by javascript?

Implement the “Word Decoder” game. This game will present the player with a series of scrambled words (up to 20 words) and challenge him/her to attempt to unscramble them. Each time a new word is displayed, and a text input is provided for the user to write the unscrambled word.
Once the player thinks the word has been properly decoded, he clicks on the “Check answer” button. If the player’s answer is correct, his score is increased by one. If his answer is not correct, he is notified and he is then given a different word.
i understood the Question , but i dont know how to generate it , or even how to start it!!
any help please?
To start, try breaking down the problem into things you'll need; think nouns and verbs. This is simply rewriting the problem in new terms. You need:
word: just a string, but it's a noun you'll need, so list it.
dictionary: a collection of words to choose from (during testing, you don't need many)
display: these become HTML elements, since you're working with JS
scrambled word
text input
submit button to check answer
score
"wrong answer" notifier
to scramble a word
to compare words: how can you compare two words to see if one is a permutation of the other? Do it right and anagrams aren't a problem.
to check an answer
to increment score
to notify user of incorrect answer
to present a new scrambled word
Any item beginning with "to" is a verb; anything else is a noun. Nouns become objects, verbs become methods/functions.
The above is mostly a top-down approach, in contrast with bottom-up (note that top-down vs bottom-up isn't an either-or proposition). Other approaches that might help with not knowing where to start are test driven development or its offshoot, behavior driven development. With these you start by defining, in code, what the program should do, then fill in the details to make it do that.
A hint on comparing words: the problem is basically defining an equivalence class—two strings are equivalent if one is a permutation of the other. The permutations of a string, taken together, form the equivalence class for that string; two strings are in the same equivalence class if the strings are equivalent. As the linked document points out, equivalence classes are well represented by picking a single element of the class as the class representative. Lastly, you can turn the equivalence class definition around: two strings are permutations of each other if they are in the same equivalence class.
Look into loading a dictionary via XHR.
there are tons of those available online [http://www.mieliestronk.com/wordlist.html NOTE: it contains some swear words, if you're going to be doing this for academic purposes, since its your homework, you should look for a "clean" list]...
For scrambling the word: make your string into a char array, then find an array shuffle function [they are simple to write, I wrote one for my implementation of Bogosort]...
function shuffle(b)
{
var a = b.concat([]); //makes a copy of B, b won't be changed...
var final = [];
while(a.length != 0)
{
//0 -> a length-1
var targIndex = Math.round((a.length-1)*(Math.random()));
var value = a[targIndex]
a.remove(targIndex);
final.push(value);
}
return final;
}
When the user is done inputting, simply compare input with the answer [case insensitive, ignore spaces] As stated in comments, there are also the possibility of anagrams, so be sure to check for those... perhaps, you could simply verify the word exists in the dictionary.

Categories

Resources