38
loading...
This website collects cookies to deliver better user experience
The repeat()
method constructs and returns a new string which contains the specified number of copies of the string on which it was called, concatenated together.
repeat
. replicate
sounds cool. String.prototype.replicate
now :-String.prototype.replicate = function(count) {
let input = this;
let result = "";
for (let index = 0; index < count; index++) {
result += input;
}
return result;
}
result
to ""
and start a for
loop in which we iterate till count
and simply keep appending the input
to the result
variable. Very straightforward but meh!!. String.prototype.replicate = function(count) {
let input = this;
let result = this.valueOf();
for (var index = 2; index < count; index*=2) {
result += result;
}
let remainingCount = count - index/2;
return remainingCount > 0 ? result + input.replicate(remainingCount) : result;
}
'hey'.replicate(10)
:-
input
initialized to this
and result
initialized to this.valueOf()
. The valueOf()
bit helps in decreasing the implicit conversion time that's happening whenever later result
will be concatenated to itself. for
loop stuff -
index
is intialized to 2
.index
should be less than count
index
should be multiplied each time by 2
result
will be appended to itself each time in the iteration:-
result
for index = 2
will become heyhey
result
for index = 4
will become heyheyheyhey
result
for index = 8
will become heyheyheyheyheyheyheyhey
index
will become 16
which is greater than 10
and we exit the loop.remainingCount
will be 10
- 16/2
= 2
;remainingCount
will be greater than 0
, we will recurse by calling input.replicate(remainingCount)
and add its result to current result
or simply return result
. 'hey'.replicate(10)
scenario :-O(log(8) + log(2))
. And if I am doing maths correct, log(a) + log(b) = log(ab)
O(log(8) + log(2))
is O(log(16))
which is greater than O(log(10))
(the optimal solution). String.prototype.replicate = function(count) {
let result = ''
let pattern = this.valueOf();
while (count > 0) {
if (count & 1)
result += pattern;
count >>= 1
if (count) pattern += pattern;
}
return result;
};
count
is 5 then it can be represented as 101
in binary. So it's possible for us to repeat the string count
times by just resorting to binary calculations. If we try to differentiate between 4 and 5, we know there is an extra 1 in latter case. Now instead of seeing the above code as some binary work of art, replace count&1 by count%2!==0 and count>>=1 by count=Math.floor(count/2). What this means is that, whenever count
is odd, we would want to save the pattern
till now in result
variable. What is pattern
? pattern
is repeated concatenation of itself similar to our earlier algorithm so it will always repeat in powers of 2. It's necessary to take care of the situation when count
is not divisible by 2 and store the current pattern
in result
as we go until count
becomes 0. typeof null
-> object
🤷♂️.String.prototype.replicate = function(count) {
var str = '' + this;
count = +count;
count = Math.floor(count);
if (str.length == 0 || count == 0)
return '';
var maxCount = str.length * count;
count = Math.floor(Math.log(count) / Math.log(2));
while (count) {
str += str;
count--;
}
str += str.substring(0, maxCount - str.length);
return str;
}
count
, we use the same ideology as in the optimal solution for concatenating and doubling length of str
every time. But after that for the remaining length, it uses substring
and appends that to str
again. It's the second step of substring
which makes it a costly operation. Though it does better than the initial Meh solution of 108 ops/s, it's still no where near around the best optimal solution I found online or even mine 😎.