I have been working on reverse engineering some code for a couple days and I've gotten quite stuck. It's basically just a logic problem that I can't wrap my min around, me and my partner are both stuck on this.
The setup:
function decrypt(s) {
var r = "";
var tmp = s.split("9812265");
s = unescape(tmp[0]);
k = "4849604567466";
var temp, temp2, temp3, tempf;
for( var i = 0; i < s.length; i++) {
temp = parseInt(k.charAt(i%k.length));
temp2 = s.charCodeAt(i);
temp3 = (temp^temp2)-3;
tempf = String.fromCharCode(temp3);
r += tempf;
}
return r;
}
I have this function, and the loop is what we can't reverse. What is meant to happen is to turn HTML into a bunch of characters then escape those characters. I wrote a method that can escape any string, so that part is easy. The loop that preforms the change is just to hard of a logic problem for me.
function encrypt(output)
{
var SecretNumber = "4849604";
var returnValue = "";
for(var n = 0; n < output.length; n++)
{
returnValue += String.fromCharCode(parseInt(SecretNumber.charAt(n%SecretNumber.length))^(output[n].charCodeAt(0))+3);
}
return escapeAny(returnValue) + 9812265 + (escapeAny(SecretNumber));
}
Paired with the function for escaping string mentioned earlier:
function escapeAny(string)
{
var list1 = [];
var list2 = [];
for(i = 16; i < 255; i++)
{
list1[i-16] = ("%" + i.toString(16).toString());
list2[i-16] = (unescape(list1[i-16]));
}
var charAr = string.split('');
var newChat = [];
for(i = 0; i < charAr.length; i++)
{
var currentChar = charAr[i];
var charNumber = list2.indexOf(currentChar);
var ret = list1[charNumber];
newChat[i] = ret;
}
String.prototype.replaceAll = function(search, replacement) {
var target = this;
return target.replace(new RegExp(search, 'g'), replacement);
};
return newChat.join().replaceAll(",", "");
}
This solution seems to have worked well.
Related
I just registered in HackerEarth and trying to solve the first basic problem: Monk and rotation. When I am running the code by entering single input it works fine but when I submit the solution it does not work.
https://www.hackerearth.com/practice/codemonk/
It seems I am reading the input incorrectly
Can someone please help.
process.stdin.resume();
process.stdin.setEncoding("utf-8");
var stdin_input = "";
process.stdin.on("data", function (input) {
stdin_input += input; // Reading input from STDIN
});
process.stdin.on("end", function () {
let lines = stdin_input.split('\n');
let len = lines.length;
let inputArr = [];
const numberTestCase = lines[0]
const output = new Array()
for (i = 1; i < lines.length; i++) {
let lineInput = lines[i].split(' ');
let noOfElement = 0;
let stepRotation = 0;
let skipLineUpto = 0;
let inputData = false;
if (lineInput.length === 2) {
inputData = true;
noOfElement = lineInput[0]
stepRotation = lineInput[1]
skipLineUpto = parseInt(i) + 2;
}
if (inputData) {
let stringOfArray = lines[i + 1];
let arrayData = stringOfArray.split(' ');
let mod = 0
mod = stepRotation % noOfElement;
if (mod != 0) {
let unReversedArray = arrayData.splice(-mod);
let ff = unReversedArray.concat(arrayData)
inputArr.push(ff.join(' '))
} else {
let ff = arrayData
console.log(ff.join(' '))
inputArr.push(ff.join(' '))
}
}
}
main(inputArr)
});
function main(input) {
process.stdout.write(input.join("\n")); // Writing output to STDOUT
}
When you submit you can see why your code is not valid.
Your solution is for when scenarios where input is 3 lines (1 test case), like in their example, but you can see their test cases where they have inputs of multiple lines (T test cases).
Without any prototype method something like this would work (not working because time exceeded):
let lines = stdin_input.split('\n');
let loops = lines[0];
for(i = 1; i < lines.length; i+=2) {
let steps = lines[i].split(' ')[1];
let arr = lines[i+1].split(' ');
for (j = 0; j < steps; j++) {
var x = arr[arr.length-1], i;
for (k = arr.length-1; k > 0; k--) {
arr[k] = arr[k-1];
}
arr[0] = x;
}
main(arr);
}
With pop() and unshift() only one test case is failing due to time exceeded but should get you close to the final solution:
let lines = stdin_input.split('\n');
let loops = lines[0];
for(i = 1; i < lines.length; i+=2) {
let steps = lines[i].split(' ')[1];
let arr = lines[i+1].split(' ');
for (j = 0; j < steps; j++) {
arr.unshift(arr.pop());
}
main(arr);
}
I'm trying to do a reverse-word script in javascript. I have written this function, but it does not work and I can't understand why. What is wrong? Is there any other way to do it?
function inverser(x)
{
var newString ="";
var index=(x.length - 1);
var y=0;
for (var i=index ; i>=0 ; i--)
{
x[i] = newString [y++];
}
return (newString );
}
console.log(inverser("test"));
You need to add to concatenate newString instead of trying to assign an index to it. The logic of your function should be
newString[y++] += x[i];
Link to code
when you use newString[y++], newString is still empty string and doesn't have cell 1 or 2 or 3 .... and can't assign string to this cell.
simply if you remove y variable and make some move on line 9 can get answer.
here the code worked for me:
function inverser(x) {
var newString = "";
var index = (x.length - 1);
for (var i = index; i >= 0; i--)
{
newString += x[i];
}
return (newString);
}
Use reverse():
function inverser(x)
{
return x.split("").reverse().join("");
}
It's simple if you don't need build in function, please comment, i will update my answer :)
Update
The assignment statements are wrong in your code, it should have been:
newString += x[i];
"use strict";
function wordReverse() {
const str1 = "God is Good";
const str2 = str1.split(" ");
//console.log(str2);
const reverseWord = [];
const len = str2.length;
//console.log(len);
for (let i = len - 1; i >= 0; i--) {
reverseWord.push(str2[i]);
}
return reverseWord;
}
console.log(wordReverse().join(" "));
const word = "reverse";
const reverseString = (str) => str.split("").reverse().join("");
reverseString(word);
function reverseWord(str) {
const splittedString = str.split(" ");
const wordreverse = [];
const len = splittedString.length;
for (let i = len - 1; i >= 0; i--) {
wordreverse.push(splittedString[i]);
}
return wordreverse.join(" ");
}
function reverseWord(str) {
const splittedString = str.split(" ");
const wordreverse = [];
const len = splittedString.length;
for (let i = len - 1; i >= 0; i--) {
wordreverse.push(splittedString[i]);
}
return wordreverse.join(" ");
}
console.log(reverseWord("hello world"))
I need string Double each letter in a string
abc -> aabbcc
i try this
var s = "abc";
for(var i = 0; i < s.length ; i++){
console.log(s+s);
}
o/p
> abcabc
> abcabc
> abcabc
but i need
aabbcc
help me
Use String#split , Array#map and Array#join methods.
var s = "abc";
console.log(
// split the string into individual char array
s.split('').map(function(v) {
// iterate and update
return v + v;
// join the updated array
}).join('')
)
UPDATE : You can even use String#replace method for that.
var s = "abc";
console.log(
// replace each charcter with repetition of it
// inside substituting string you can use $& for getting matched char
s.replace(/./g, '$&$&')
)
You need to reference the specific character at the index within the string with s[i] rather than just s itself.
var s = "abc";
var out = "";
for(var i = 0; i < s.length ; i++){
out = out + (s[i] + s[i]);
}
console.log(out);
I have created a function which takes string as an input and iterate the string and returns the final string with each character doubled.
var s = "abcdef";
function makeDoubles(s){
var s1 = "";
for(var i=0; i<s.length; i++){
s1 += s[i]+s[i];
}
return s1;
}
alert(makeDoubles(s));
if you want to make it with a loop, then you have to print s[i]+s[i];
not, s + s.
var s = "abc";
let newS = "";
for (var i = 0; i < s.length; i++) {
newS += s[i] + s[i];
}
console.log(newS);
that works for me, maybe a little bit hardcoded, but I am new too))
good luck
console.log(s+s);, here s holds entire string. You will have to fetch individual character and append it.
var s = "abc";
var r = ""
for (var i = 0; i < s.length; i++) {
var c = s.charAt(i);
r+= c+c
}
console.log(r)
var doubleStr = function(str) {
str = str.split('');
var i = 0;
while (i < str.length) {
str.splice(i, 0, str[i]);
i += 2;
}
return str.join('');
};
You can simply use one of these two methods:
const doubleChar = (str) => str.split("").map(c => c + c).join("");
OR
function doubleChar(str) {
var word = '';
for (var i = 0; i < str.length; i++){
word = word + str[i] + str[i];
};
return word;
};
function doubleChar(str) {
let sum = [];
for (let i = 0; i < str.length; i++){
let result = (str[i]+str[i]);
sum = sum + result;
}
return sum;
}
console.log (doubleChar ("Hello"));
How can I get a certain nth element from a string. Like if I want to get every 3rd element from the word GOOGLE how can i do that. SO far i've done this but i dont know what to type after the If
function create_string( string ) {
var string_length=string.length;
var new_string=[];
for( var i=0; i<string_length; i++) {
if(string[i]%3==0) {
}
new_string.push(string[i]);
}
return new_string;
}
Use the charAt() function of String which returns the char at a specific index passed to the function. Using charAt, I have created a script that will return every third character.
var result = "";
for(var i = 2; i < test.length; i+=3){
result += test.charAt(i);
}
If you would like to turn this script into a more reusable function:
var test = "GOOGLE";
function getEveryNthChar(n, str){
var result = "";
for(var i = (n-1); i < test.length; i+=n){
result += str.charAt(i);
}
return result;
}
alert(getEveryNthChar(1,test));
alert(getEveryNthChar(2,test));
alert(getEveryNthChar(3,test));
alert(getEveryNthChar(4,test));
Working Demo: http://jsfiddle.net/Q7Lx2/
Documentation
How about this?
function create_string( string ) {
var string_length=string.length;
var new_string=[];
for( var i=2; i<string_length; i+=3) { // instead of an if, use +=3
new_string.push(string.charAt(i));
}
return new_string.join(""); // turn your array back into a string
}
Note that if you start making this compact, you'll end up with the same answer as Kevin's ;-)
function create_string( s ) {
var new_string = '';
for( var i=2; i<s.length; i+=3) { // instead of an if, use +=3
new_string += s.charAt(i);
}
return new_string;
}
Here's a function that will work for any number, not just 3:
function stringHop(s, n) {
var result = "";
for (var i = 0; i < s.length; i+= n) {
result += s.charAt(i);
}
return result;
}
var foo = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
var bar = stringHop(foo, 2); // returns "ACEGIKMOQSUWY"
var baz = stringHop(foo, 3); // returns "ADGJMPSVY"
String.charAt(index) will return the character at the specified index, from 0 to String.length - 1. So:
String.prototype.every = function(n) {
var out = '';
for (var i = 0; i < this.length; i += n) {
out += this.charAt(i);
}
return out;
}
var str = "GOOGLE";
console.log(str.every(3)) // Outputs: GG
If you don't want to include the first character, then change the for loop to:
for (var i = n - 1; i < this.length; i += n) {
I'm looking for the fastest method I can use to search a body of text for the indexes of multiple characters.
For example:
searchString = 'abcdefabcdef';
searchChars = ['a','b'];
// returns {'a':[0,6], 'b':[1,7]}
You should be able to use a regular expression to find all occurances of each character. Something like:
function findIndexes(find, str) {
var output = {};
for (var i = 0; i < find.length; i++) {
var m = [];
var r = new RegExp('.*?' + find[i], 'g');
var ofs = -1;
while ((x = r.exec(str)) != null) {
ofs += x[0].length;
m.push(ofs);
}
output[find[i]] = m;
}
return output;
}
Edit:
Did some changes, and now it works. :) However, as Javascript doesn't have a matches method to get all matches at once, it's not really any improvment over using indexOf... :P
Edit 2:
However, you can use a regular expression to find any of the characters, so you only need to loop the string once instead of once for each character. :)
function findIndexes(find, str) {
var output = {};
for (var i = 0; i < find.length; i++) output[find[i]] = [];
var r = new RegExp('.*?[' + find.join('') + ']', 'g');
var ofs = -1;
while ((x = r.exec(str)) != null) {
ofs += x[0].length;
output[x[0].substr(x[0].length-1,1)].push(ofs);
}
return output;
}
Assuming few letters to search for and many letters to search against (i.e. low number of letter, long strings), the latter is the most efficient, since you only go through the string once, and then test each letter.
The other one goes through the string as many times as there are letters to search for.
After timing a few single pass algorithms and Guffa's regex, I ended up going with this:
function findIndexesMultiPass(str,find) {
var x, output = {};
for (var i = 0; i < find.length; i++) {
output[find[i]] = [];
x = 0;
while ((x = str.indexOf(find[i], x)) > -1) {
output[find[i]].push(x++);
}
}
return output;
}
var searchString = "abcd abcd abcd";
var searchChars = ['a', 'b'];
var result = findIndexesMultiPass(searchString, searchChars);
// {'a':[0,5,10], 'b':[1,6,11]}
This turned out to be pretty slow:
function findIndexesOnePass(str,find) {
var output = {};
for (var i = 0; i < find.length; i++) {
output[find[i]] = [];
}
for (var i = 0; i < str.length; i++) {
var currentChar = str.charAt(i);
if (output[currentChar] !== undefined) {
output[currentChar].push(i);
}
}
return output;
}
var searchString = "abcd abcd abcd";
var searchChars = ['a', 'b'];
var result = findIndexesOnePass(searchString, searchChars);
// {'a':[0,5,10], 'b':[1,6,11]}
Rough times (indexes of 3 characters)
Google Chrome (Mac)
findIndexesMultiPass: 44ms
findIndexesOnePass: 799ms
findIndexesRegEx: 95ms
Safari
findIndexesMultiPass: 48ms
findIndexesOnePass: 325ms
findIndexesRegEx: 293ms
Firefox
findIndexesMultiPass: 56ms
findIndexesOnePass: 369ms
findIndexesRegEx: 786ms