I think I'm asking this kind of question in the right place, the "discussion" tag's description seems to fit. If I'm mistaking, well I'm sorry :s
So here goes, my question concerns a codefights challenge. The challenge was:
Given a string, transform it (by shuffling its contents) into a palindrome!
A palindrome is a string that reads the same left-to-right and right-to-left.
Example:
"abcd"->"imp"
"cdcd"->"cddc"
"AABBaabb33!!??"->"!3?ABabbaBA?3!"
The input is a string and can contain letters ,digits and/or ? ,!
If it is not possible you should return imp (for impossible) and if there is more than one solution return the first one in the lexicographic order
I failed solving it so I went and had a look at the best solution the day after:
function outputString(s) {
s = s.split(a = b = c = "").sort()
i = 0
while (x = s[i])
x == s[++i] ?
[a += x, c = x + c, i++] :
b += x
return b[1] ? "imp" : a+b+c
}
But I don't understand it.
Let me try to explain what I don't understand exactly:
What exactly is this input for the split function ?
I understand that inside the while there is a shorthand if but what is done in it is incomprehensible for me :s
I understand that these kind of question don't really have their place here but I think I managed to make it so that a short, to the point answer is possible.
If someone could break these two elements down for me. I'd appreciate it.
The split is actually split("") which returns an array of single character strings. The assignment is returning what was assigned, so the code is also initializing a, b and c there, but it doesn't affect the split.
In the while the program is looping through the ordered characters and creates the result the following way: add the letter after a and in front of c if the next letter is the same and step two ahead (note the additional i++), otherwise add the letter to b. In the end if there was more than one single letter (only one can be in the middle) return "imp" otherwise a+b+c (which will be the first solution when this algorithm is used).
See expanded version of Andreas.
Related
I am trying to create a button that displays the text from the "TextCollector" input as numbers seperated by commas and ignores any symbol that is not in the alphabet. Update: I also need it to ignore the fact that a letter is capitalized.
Example:
a = 1
b = 2
c = 3
and so on...
So if I typed in "cat's" in the input at the bottom would display "3,1,20,19".
Here's what I've tried so far:
<form action="">
<input type="text" id="TextCollector" name="TextCollector" placeholder="Type in something">
<br>
<input type="button" value="Submit" onclick="ShowMe()">
</form>
<h1 id="numbers"></h1>
<script>
function ShowMe() {
var text = document.getElementById("TextCollector").value;
var textnum = text.charCodeAt(0) - 97;
document.getElementById("numbers").innerHTML = textnum;
}
</script>
But the code I tried halfly works, it just displays the first letter as a number and ignores the rest. Also with my code "0" is "a", but I need "1" to be "a".
Can someone help me? I hope I made myself clear...
First .replace all non-alphabetical characters with the empty string, then you can turn the resulting string into an array, .map each character to its character code, and join it by commas:
function ShowMe() {
const replaced = document.getElementById("TextCollector").value.replace(/[^a-z]/gi, '').toLowerCase();
document.getElementById("numbers").textContent = [...replaced]
.map(char => char.charCodeAt(0) - 96)
.join(', ');
}
<form action="">
<input type="text" id="TextCollector" name="TextCollector" placeholder="Type in something">
<br>
<input type="button" value="Submit" onclick="ShowMe()">
</form>
<h1 id="numbers"></h1>
Allow me to introduce to you a few concepts which I highly recommend you learn instead of copy-pasting any code given to you. I'm not going to go into great detail because, honestly, all you have to know is how to ask the correct question on the google search bar to get your answer. I'll also talk about how you can develop a strategy to solving problems such as this one at the end of the post.
Loops
You use a loop in programming when you want to repeat a set of instructions multiple times. There are multiple ways to write a loop, the two most popular ways of writing a loop are: the for loop, and the while loop. Other less popular methods include do loop, recursion, etc.
Types
Javascript is weakly typed, which makes for a lot of weird and unexpected behavior i you try to add a bool value with an integer. Examples of primitive types are: Integer, Boolean, Char, String, etc. Numbers can be represented in multiple ways: integer, double, float. Don't worry too much about the differences between each of these, but if you need to use decimals and negative values, use floats. Boolean is either TRUE or FALSE. Char (short for Character) is a map between a number and a letter. (Read this document if you care to learn why your code outputs a "0" instead of a "1" when you run this line:
text.charCodeAt(0) - 97;
Operators
You should know what +, -, *, /, do grade school math class. You should also know > (greater than), < (less than), >= (greater than or equal), <= (less than or equal), == (equals), != (not equal), && (intersection, also known as AND), || (union, also known as OR). There are also some quality of life operators such as: ++ (increment value by 1), -- (decrement value by 1), += (increase target value by given amount), -= (decrease target value by given amount) etc etc....
THE ANSWER
Tie all this knowledge together, and we arrive at a solution.
string text = document.getElementById("TextCollector").value;
var i;
var textnum;
//create empty string variable to append char values to
var myString = '';
for (i = 0; i < text.length; i++)
{
//Convert char to number
textnum = text.charCodeAt(i) - 96;
//concatenate textnum to string, and add a comma at the end
myString = myString + textnum + ",";
}
//remove the last unwanted comma by applying "substr" method to the string
myString = myString.substr(0,myString.length - 1);
document.getElementById("numbers").innerHTML = textnum;
I encourage you to ask questions you do not understand from the solution above.
**Edit: The strategy to solving any problem is to break it down into sub-problems. Your goal is turn a bunch of characters from a string into numbers. Ask yourself these questions:
How can I turn characters into numbers?
Well, from the looks of your code it looks like you already knew how. Next question
How can I turn all characters into numbers, not just the starting character?
Ok, take a closer look to the method you applied to your "text" value
charCodeAt(0)
That zero represents the index of a string. A string is an array of char, and if you understand how arrays work, it should be no surprise why it only returns the first character.
Ok so, how can I apply this charCodeAt() method to ALL my characters?
This is a little tricky because if you don't know the concept of loops in programming (or recursion), you are not adequately equipped to solve these problems. There are many free online resources for learning basic programming concepts such as loops. I recommend this site here: https://www.w3schools.com/
Ok I can turn multiple characters to numbers. How do I glue them together into a single string?
This is something you can google. That's what I did. Hint: how to add chars to the end of a string
How do I get rid of the last comma in my string?
Google: How do I remove last char in a string?
Sources:
https://en.wikipedia.org/wiki/Control_flow#Loops
https://en.wikipedia.org/wiki/Primitive_data_type
https://www.w3schools.com/js/js_loop_for.asp
https://www.w3schools.com/js/js_string_methods.asp
https://codehandbook.org/remove-character-from-string/
This pertains to any language that you think will work. Is there a way to change the look of a text input to replace every second space (space as in when the space bar is hit it makes a space) i need to a way almost like a counter that once it counts 2 spaces then it replaces that 2nd space to a letter or symbol. if someone could help me with this it would be amazing and the purpose is just to change the way the text looks in this way functionality does not matter as long as it reads like normal text. ( if it helps it would be every odd number of spaces gets changed.)
for example i want to be able to copy and paste something in like this> "i went down to the sea to pick up many sticks for my collection"
and have it return something like this
i%went down%to the%sea to%pick up%many sticks%for my%collection
the end goal is for the symbol to be a different color so it stands out from the text so if that would be possible that would be amazing.
I chose javascript, but there are multiple languages that you could choose and there are multiple ways to accomplish this. This is the train of thought that you should use when solving this problem:
Determine the characters that you want to replace
Determine the character that you want to replace it with
Since we don't want to replace every single one, what is the pattern/frequency that you want to replace found occurrences with.
For the 3rd question, you've said that you want to replace every other occurrence, so we need to keep track of the count of occurrences. And replace it when occurrence modulo 2 = 1. This says replace every odd occurrence.
I chose to use regex to find all the spaces in the sentence, have a counter n and increment the counter every time I find a space.
This leaves us with the following code:
const input = "i went down to the sea to pick up many sticks for my collection";
let n = 0;
const output = input.replace(/\s/g, (m, i, og) => {
return (n++ % 2) ? m : '%';
});
// output = "i%went down%to the%sea to%pick up%many sticks%for my%collection"
Also please take a look at String.prototype.replace() so you can learn about using regex, and to learn about what the function does. This will help you learn and solve similar problems by yourself in the future.
you can use a boolean variable to count odd and even spaces and string.prototyoe.replace with a callback function:
var str = 'i went down to the sea to pick up many sticks for my collection';
var odd = true;
str = str.replace(/\s/gi, (spaceChar)=>{
odd = !odd;
return !odd ? spaceChar : '%'; // this is what you wrote (every second)
// return odd ? spaceChar : '%'; // this is what your expected result shows (every second starting with the first occurence)
});
Tested in latest Firefox and Chrome (which have a 'de' locale on my system):
"Ä".localeCompare("A")
gives me 1, meaning that it believes "Ä" should appear after "A" in a sorted order, which is correct.
But:
"Ägypten".localeCompare("Algerien")
gives me -1, meaning that it believes "Ägypten" should appear before "Algerien" in a sorted order.
Why? Why does it look past the first character of each string, if it says that the first character of the first string should appear after the first character of the second string when you check it on its own?
Here you have method just for your needs, copy paste this method:
Recursive parse of strings and give char locale compare result not string :)
FINAL RESULT
Bug Fixed, added compare (incorrect stoppage or recursive loop) to entire strings:
String.prototype.MylocaleCompare = function (right, idx){
idx = (idx == undefined) ? 0 : idx++;
var run = right.length <= this.length ? (idx < right.length - 1 ? true : false) : (idx < this.length - 1 ? true : false);
if (!run)
{
if (this[0].localeCompare(right[0]) == 0)
{
return this.localeCompare(right);
}
else
{
return this[0].localeCompare(right[0])
}
}
if(this.localeCompare(right) != this[0].localeCompare(right[0]))
{
var myLeft = this.slice(1, this.length);
var myRight = right.slice(1, right.length);
if (myLeft.localeCompare(myRight) != myLeft[0].localeCompare(myRight[0]))
{
return myLeft.MylocaleCompare(myRight, idx);
}
else
{
if (this[0].localeCompare(right[0]) == 0)
{
return myLeft.MylocaleCompare(myRight, idx);
}
else
{
return this[0].localeCompare(right[0])
}
}
}
else
{
return this.localeCompare(right);
}
}
http://en.wikipedia.org/wiki/Diaeresis_(diacritic)#Printing_conventions_in_German
“When alphabetically sorting German words, the umlaut is usually not distinguished from the underlying vowel, although if two words differ only by an umlaut, the umlauted one comes second […]
“There is a second system in limited use, mostly for sorting names (colloquially called "telephone directory sorting"), which treats ü like ue, and so on.”
Assuming the second kind of sorting algorithm is applied, then the results you are seeing make sense.
Ä would become Ae, and that is “longer” then your other value A, so sorting A before Ae and therefor A before Ä would be correct (and as you said yourself, you consider this to be correct; and even by the first algorithm that just treats Ä as A it would be correct, too).
Now Ägypten becomes Aegypten for sorting purposes, and therefor it has to appear before Algerien in the same sorting logic – the first letters of both terms are equal, so it is up to the second ones to determine sort order, and e has a lexicographically lower sort value than l. Therefor, Aegypten before Algerien, meaning Ägypten before Algerien.
German Wikipedia elaborates even more about this (http://de.wikipedia.org/wiki/Alphabetische_Sortierung#Einsortierungsregeln_f.C3.BCr_weitere_Buchstaben), and notes that there are two variants of the relevant DIN 5007.
DIN 5007 variant 1 says, ä is to be treated as a, ö as o and ü as u, and that this kind of sorting was to be used for dictionaries and the like.
DIN 5007 variant 1 says the other thing, ä to be treated as ae, etc., and this is to be used mainly for name listings such as telephone books.
Wikipedia goes on to say that this takes into account that there might be more than one form of spelling for personal names (someone’s last name might be Moeller or Möller, both versions exist), whereas for words in a dictionary there is usually only one spelling that is considered correct.
Now, I guess the price question remaining is: Can I get browsers to apply the other form of sorting for German locale? To be frank, I don’t know.
It might surely be desirable to be able to chose between those two forms of sorting, because as the Wikipedia says personal names Moeller and Möller exist, but there is only Ägypten and not Aegypten when it comes to a dictionary.
If you take a piece of code like this:
var string = "javascript";
var search = string.search("");
console.log(search);
and then you take this piece of code:
var string = "javascript";
var search = string.search("j");
console.log(search);
both pieces of code evaluate to 0. It's fairly annoying since I would imagine it should amount to -1 since there is no match, nothing and the. This is a problem in a script I am trying to write because these both evaluate to the exact same number even though they aren't the same value and this is making me move all my data in my .json file over by one space from this:
"heman",
"candy",
"powerpuffgirls",
"oranges"
to this:
" heman",
" candy",
" powerpuffgirls",
" oranges"
because when I test for a match from the input field the user enters to the .json data I have no way of evaluating whether the data was blank or one matching character was entered (since the javascript search method evaluates both as the same amount '0'). This incapacity of javascript to know the difference between a 'nothing' and a 'single matching char' moved along at zero index (since it's a single matching char) has forced me to move all of .json data over one space.
This feels...wrong to do, like not good practice. It's a solution but it seems like a lame one. Does anybody know any work arounds for a problem like this? Seems like a pretty simple common problem. Is there some way through this, perhaps with regular expressions or something?
Remember this:
Always, whatever be the value of the variable string (including empty string)
string.search("") = 0
So, check for length of the string!
if (string.length == 0) // Empty string
var search = query.length === 0 ? -1 : string.search(query);
This question already has answers here:
How do I replace a character at a particular index in JavaScript?
(30 answers)
Closed 9 years ago.
SITUATION
I started to implement the game "HANGMAN" using only JavaScript and HTML on client side machines. I have completed all the logical work. Now only the aesthetics are remaining. And I am stuck up because we can't write to strings in JS.
a = "abcd"; a[0] = "e"; -- This type of thing is not allowed.
What I have done
CODE
The code I have tried, This does not work:
See here
I now have the following three arrays:
a -- The array that contains the letters of the word(for gel this would be g,e,l)
gai -- This array consists of the letters that have been entered by the user and are there in the word.(like g or e)
ag -- This array consists of the letters that have been entered by the user regardless of whether or not they are there in the word to be guessed or not.
What I need to do
I need to generate the output that would show the letter in case it has been guessed by the user and is there in the word(letters in the array gai) and _ in place of letters that have not yet been entered by the user.
What I want
A function that will return the desired output, as explained in the following example.
Example
Let the word to be guessed be:
together
User enters e:
The function should return: _ _ _ e _ _ e _
User then enters d, my program will prompt him to say that this letter is not there in the word.
User enters r
Function should return: _ _ _ e _ _ e r
And so on....
I hope you get the idea!
In case you don't get it(owing to my bad explanation or otherwise!!)
You can play a game of hangman here: Hangman
Just watch the output at the bottom of the screen... Thats what I want this function to generate.
Kindly help me with this issue!
Reading just the start of your question (because no other code is provided), there is a problem which could be solved using native javascript functions.
var strarr = "Hello world!".split(''); // this will give you an array of characters to be manipulated
strarr[6] = "X"; // so you can do this
console.dir(strarr.join('')); // test it!
As an idea (not mine, its from comments) one could even wrap this simple code as a missing toCharArray() function and use that.
Another thing is that this method is fast enough even for relatively large bulk of text. For a test I used lorem ipsum with 1000 words. On my rather old dev machine, manipulation executes in milliseconds.
For more information, see this discussion.
Also you can use this function to set char at specified index of string:
function setCharAt(str,index,chr) {
if(index > str.length-1) return str;
return str.substr(0,index) + chr + str.substr(index+1);
}
You could use regex to mask letters in a word using String.replace.
var word = "together"
, correct = "";
function guess(c) {
if (word.indexOf(c) > -1) {
correct += c;
}
console.log(word.replace(new RegExp("[^" + correct + "]", "g"), "_"));
}