String reversing x times
Inspired by CodeWars
We have a string
s
Let's say you start with this: "String"
The first thing you do is reverse it: "gnirtS"
Then you will take the string from the 1st position and reverse it
again: "gStrin"
Then you will take the string from the 2nd position and reverse it
again: "gSnirt"
Then you will take the string from the 3rd position and reverse it
again: "gSntri"
Continue this pattern until you have done every single position, and
then you will return the string you have created. For this particular
string, you would return: "gSntir"
The Task:
In this kata, we also have a numberx
take the above reversal function, and apply it to the stringx
times.
Return the result of the string after applying the reversal function to itx
times.
Note:
String lengths may exceed 2 million andx
may exceed a billion.
Be ready to optimize.
My solution works but times out and I am having trouble optimizing much further. The code contains a lot of useful comments but here is a summary of what I have attempted to do.
Cycle Length Calculation
Because the above algorithm generates cycles, we can calculate a strings cycle length and perform x % cycleLength
to determine exactly how many iterations we must perform to get our end result, instead of having to calculate all the duplicate cycles. More on cycle lengths can be fouind here and here.
This method is better than nothing but can still get quite demanding on high cycle lengths. Potentially there is a better way of calculating the cycle length without so many iterations?
public final class XIterations {
public static String xReverse(String s, long x) {
// Using the cycle length and modular arithmetic,
// We can find the exact number of reverse operations we will need to perform.
// This way we will only perform operations we need to complete.
long iterationsRequired = x % calculateCycleLength(s.length());
// TODO: There may exist an algorithm that allows a linear transformation given x
while (iterationsRequired > 0) {
s = reverse(s);
iterationsRequired--;
}
return s;
}
// The xReverse algorithm produces cycles and therefore duplicates.
// This helper method determines the length of the cycle using the number of characters a string contains.
// More detail on the algorithm can be found at:
// https://oeis.org/A003558
// https://oeis.org/A216066
// TODO: There may exist an algorithm that requires less iterations to find the cycle length
private static int calculateCycleLength(int n) {
// Cache these so we only calculate them once.
final int a = 2 * n + 1;
final int b = 2 * n;
int cycleLength = 1;
while (true) {
double c = Math.pow(2, cycleLength);
if (c % a == 1 || c % a == b) {
return cycleLength;
}
cycleLength++;
}
}
public static String reverse(String s) {
StringBuilder sb = new StringBuilder();
int front = 0;
int back = s.length() - 1;
// Does not account for odd length strings. Will not add the middle character.
while (front < back) {
sb.append(s.charAt(back--));
sb.append(s.charAt(front++));
}
// Account for odd length strings. Add the middle character that was never added by loop.
if (front == back) {
sb.append(s.charAt(front));
}
return sb.toString();
}
}
I am mostly interested in optimization tips but of course any feedback is welcome.
java performance strings programming-challenge
add a comment |
Inspired by CodeWars
We have a string
s
Let's say you start with this: "String"
The first thing you do is reverse it: "gnirtS"
Then you will take the string from the 1st position and reverse it
again: "gStrin"
Then you will take the string from the 2nd position and reverse it
again: "gSnirt"
Then you will take the string from the 3rd position and reverse it
again: "gSntri"
Continue this pattern until you have done every single position, and
then you will return the string you have created. For this particular
string, you would return: "gSntir"
The Task:
In this kata, we also have a numberx
take the above reversal function, and apply it to the stringx
times.
Return the result of the string after applying the reversal function to itx
times.
Note:
String lengths may exceed 2 million andx
may exceed a billion.
Be ready to optimize.
My solution works but times out and I am having trouble optimizing much further. The code contains a lot of useful comments but here is a summary of what I have attempted to do.
Cycle Length Calculation
Because the above algorithm generates cycles, we can calculate a strings cycle length and perform x % cycleLength
to determine exactly how many iterations we must perform to get our end result, instead of having to calculate all the duplicate cycles. More on cycle lengths can be fouind here and here.
This method is better than nothing but can still get quite demanding on high cycle lengths. Potentially there is a better way of calculating the cycle length without so many iterations?
public final class XIterations {
public static String xReverse(String s, long x) {
// Using the cycle length and modular arithmetic,
// We can find the exact number of reverse operations we will need to perform.
// This way we will only perform operations we need to complete.
long iterationsRequired = x % calculateCycleLength(s.length());
// TODO: There may exist an algorithm that allows a linear transformation given x
while (iterationsRequired > 0) {
s = reverse(s);
iterationsRequired--;
}
return s;
}
// The xReverse algorithm produces cycles and therefore duplicates.
// This helper method determines the length of the cycle using the number of characters a string contains.
// More detail on the algorithm can be found at:
// https://oeis.org/A003558
// https://oeis.org/A216066
// TODO: There may exist an algorithm that requires less iterations to find the cycle length
private static int calculateCycleLength(int n) {
// Cache these so we only calculate them once.
final int a = 2 * n + 1;
final int b = 2 * n;
int cycleLength = 1;
while (true) {
double c = Math.pow(2, cycleLength);
if (c % a == 1 || c % a == b) {
return cycleLength;
}
cycleLength++;
}
}
public static String reverse(String s) {
StringBuilder sb = new StringBuilder();
int front = 0;
int back = s.length() - 1;
// Does not account for odd length strings. Will not add the middle character.
while (front < back) {
sb.append(s.charAt(back--));
sb.append(s.charAt(front++));
}
// Account for odd length strings. Add the middle character that was never added by loop.
if (front == back) {
sb.append(s.charAt(front));
}
return sb.toString();
}
}
I am mostly interested in optimization tips but of course any feedback is welcome.
java performance strings programming-challenge
add a comment |
Inspired by CodeWars
We have a string
s
Let's say you start with this: "String"
The first thing you do is reverse it: "gnirtS"
Then you will take the string from the 1st position and reverse it
again: "gStrin"
Then you will take the string from the 2nd position and reverse it
again: "gSnirt"
Then you will take the string from the 3rd position and reverse it
again: "gSntri"
Continue this pattern until you have done every single position, and
then you will return the string you have created. For this particular
string, you would return: "gSntir"
The Task:
In this kata, we also have a numberx
take the above reversal function, and apply it to the stringx
times.
Return the result of the string after applying the reversal function to itx
times.
Note:
String lengths may exceed 2 million andx
may exceed a billion.
Be ready to optimize.
My solution works but times out and I am having trouble optimizing much further. The code contains a lot of useful comments but here is a summary of what I have attempted to do.
Cycle Length Calculation
Because the above algorithm generates cycles, we can calculate a strings cycle length and perform x % cycleLength
to determine exactly how many iterations we must perform to get our end result, instead of having to calculate all the duplicate cycles. More on cycle lengths can be fouind here and here.
This method is better than nothing but can still get quite demanding on high cycle lengths. Potentially there is a better way of calculating the cycle length without so many iterations?
public final class XIterations {
public static String xReverse(String s, long x) {
// Using the cycle length and modular arithmetic,
// We can find the exact number of reverse operations we will need to perform.
// This way we will only perform operations we need to complete.
long iterationsRequired = x % calculateCycleLength(s.length());
// TODO: There may exist an algorithm that allows a linear transformation given x
while (iterationsRequired > 0) {
s = reverse(s);
iterationsRequired--;
}
return s;
}
// The xReverse algorithm produces cycles and therefore duplicates.
// This helper method determines the length of the cycle using the number of characters a string contains.
// More detail on the algorithm can be found at:
// https://oeis.org/A003558
// https://oeis.org/A216066
// TODO: There may exist an algorithm that requires less iterations to find the cycle length
private static int calculateCycleLength(int n) {
// Cache these so we only calculate them once.
final int a = 2 * n + 1;
final int b = 2 * n;
int cycleLength = 1;
while (true) {
double c = Math.pow(2, cycleLength);
if (c % a == 1 || c % a == b) {
return cycleLength;
}
cycleLength++;
}
}
public static String reverse(String s) {
StringBuilder sb = new StringBuilder();
int front = 0;
int back = s.length() - 1;
// Does not account for odd length strings. Will not add the middle character.
while (front < back) {
sb.append(s.charAt(back--));
sb.append(s.charAt(front++));
}
// Account for odd length strings. Add the middle character that was never added by loop.
if (front == back) {
sb.append(s.charAt(front));
}
return sb.toString();
}
}
I am mostly interested in optimization tips but of course any feedback is welcome.
java performance strings programming-challenge
Inspired by CodeWars
We have a string
s
Let's say you start with this: "String"
The first thing you do is reverse it: "gnirtS"
Then you will take the string from the 1st position and reverse it
again: "gStrin"
Then you will take the string from the 2nd position and reverse it
again: "gSnirt"
Then you will take the string from the 3rd position and reverse it
again: "gSntri"
Continue this pattern until you have done every single position, and
then you will return the string you have created. For this particular
string, you would return: "gSntir"
The Task:
In this kata, we also have a numberx
take the above reversal function, and apply it to the stringx
times.
Return the result of the string after applying the reversal function to itx
times.
Note:
String lengths may exceed 2 million andx
may exceed a billion.
Be ready to optimize.
My solution works but times out and I am having trouble optimizing much further. The code contains a lot of useful comments but here is a summary of what I have attempted to do.
Cycle Length Calculation
Because the above algorithm generates cycles, we can calculate a strings cycle length and perform x % cycleLength
to determine exactly how many iterations we must perform to get our end result, instead of having to calculate all the duplicate cycles. More on cycle lengths can be fouind here and here.
This method is better than nothing but can still get quite demanding on high cycle lengths. Potentially there is a better way of calculating the cycle length without so many iterations?
public final class XIterations {
public static String xReverse(String s, long x) {
// Using the cycle length and modular arithmetic,
// We can find the exact number of reverse operations we will need to perform.
// This way we will only perform operations we need to complete.
long iterationsRequired = x % calculateCycleLength(s.length());
// TODO: There may exist an algorithm that allows a linear transformation given x
while (iterationsRequired > 0) {
s = reverse(s);
iterationsRequired--;
}
return s;
}
// The xReverse algorithm produces cycles and therefore duplicates.
// This helper method determines the length of the cycle using the number of characters a string contains.
// More detail on the algorithm can be found at:
// https://oeis.org/A003558
// https://oeis.org/A216066
// TODO: There may exist an algorithm that requires less iterations to find the cycle length
private static int calculateCycleLength(int n) {
// Cache these so we only calculate them once.
final int a = 2 * n + 1;
final int b = 2 * n;
int cycleLength = 1;
while (true) {
double c = Math.pow(2, cycleLength);
if (c % a == 1 || c % a == b) {
return cycleLength;
}
cycleLength++;
}
}
public static String reverse(String s) {
StringBuilder sb = new StringBuilder();
int front = 0;
int back = s.length() - 1;
// Does not account for odd length strings. Will not add the middle character.
while (front < back) {
sb.append(s.charAt(back--));
sb.append(s.charAt(front++));
}
// Account for odd length strings. Add the middle character that was never added by loop.
if (front == back) {
sb.append(s.charAt(front));
}
return sb.toString();
}
}
I am mostly interested in optimization tips but of course any feedback is welcome.
java performance strings programming-challenge
java performance strings programming-challenge
edited 35 mins ago
200_success
128k15150412
128k15150412
asked 40 mins ago
JSextonn
411211
411211
add a comment |
add a comment |
active
oldest
votes
Your Answer
StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210529%2fstring-reversing-x-times%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Code Review Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
Use MathJax to format equations. MathJax reference.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f210529%2fstring-reversing-x-times%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown