This is a Rosetta Challenge. Gratefully accepting answers for Processing, p5.js, processing.js, processing.py, p5py, JRubyArt, Processing.R, et cetera – including multiple approaches in one mode. Answers may be cross-posted to the linked Rosetta Code wiki and / or to Rosetta Examples .
Task : Take a string and reverse it.
For example: “asdf” becomes “fdsa”.
Processing’s Java Mode:
// Discourse.Processing.org/t/rosetta-challenge-reverse-a-string/20644/2
// GoToLoop (2020/May/08)
static final String STR = "àéïõû";
void setup() {
println(STR);
println(reverseFast(STR));
println(reverseSlow(STR));
exit();
}
static final String reverseFast(final CharSequence s) {
return new StringBuilder(s).reverse().toString();
}
static final String reverseSlow(final String s) {
return new String(reverse(s.toCharArray()));
}
Java/Pjs Cross-Mode:
// Discourse.Processing.org/t/rosetta-challenge-reverse-a-string/20644/2
// GoToLoop (2020/May/08)
static final String[] TEXTS = { "asdf", "àéïõû" };
void setup() {
println(TEXTS);
println(reverseStr(TEXTS[0]) + " " + reverseStr(TEXTS[1]));
exit();
}
static final String reverseStr(final String s) {
return join(reverse(s.split("")), "");
}
1 Like
Processing’s Python Mode:
# Discourse.Processing.org/t/rosetta-challenge-reverse-a-string/20644/3
# GoToLoop (2020/May/08)
TEXTS = 'asdf', u'àéïõû'
def setup():
print TEXTS[0], TEXTS[1]
print reverseStr(TEXTS[0]), reverseStr(TEXTS[1])
exit()
def reverseStr(s): return s[::-1]
2 Likes
Processing.R (R mode)
# ReverseAString in Processing.R
# Jeremy Douglass 2020-05-08 -- Processing 3.4
# https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/2
setup <- function() {
println(strrev("asdf"))
println(strrev("àéïõû"))
println(strrev("Lorem ipsum"))
}
strrev <- function(txt) {
return(paste(rev(strsplit(txt, "")[[1]]), collapse = ""))
}
fdsa
ûõïéà
muspi meroL
2 Likes
p5.js:
// Discourse.Processing.org/t/rosetta-challenge-reverse-a-string/20644/5
// GoToLoop (2020/May/08)
const TEXTS = [ 'asdf', 'àéïõû' ];
function setup() {
noCanvas();
print(TEXTS);
print(reverseStr(TEXTS[0]), reverseStr(TEXTS[1]));
}
function reverseStr(s) {
return [...s].reverse().join('');
//return s.split('').reverse().join('');
}
2 Likes
noel
May 8, 2020, 10:47pm
6
For me, this raises a question towards how to respond to tasks. With Flood Fill there are languages with a build-in function, but maybe answers should be low-leveled
String inputString = "àéïõû";
println(inputString);
String outString = "";
for (char c : inputString.toCharArray()) {
outString = c + outString;
}
println(outString);
1 Like
I suppose another part of that is to present the answer in immediate mode (no setup, no draw).
So, in Processing.R, this is also a complete sketch:
println(paste(rev(strsplit("asdf", "")[[1]]), collapse = ""))
fdsa
1 Like
…and in p5py, the immediate mode sketch would be two lines:
from p5 import *
print("asdf"[::-1])
fdsa
Python Mode’s 1-liner: print u'àéïõû'[::-1]
Python 3’s 1-liner: print('àéïõû'[::-1])
1 Like
noel
May 9, 2020, 4:55am
10
Yes. An example of what I mean is the task Draw a sphere. Should it be responded as it is, or like Phyton, right below it which takes a third of the page? What criteria should be prioritized?
Sven
May 9, 2020, 1:43pm
11
Love this! Short and tasty implementation.
If one wants support for emojis (who doesn’t?! ), split
will fail, though, as it splits by UTF-16 code units (not Unicode characters). Array.from
or ...
(spread syntax) could be used instead:
const reverseStr = s => [...s].reverse().join('');
2 Likes
noel
May 9, 2020, 1:50pm
12
Included in the task, and it is driving me mad. Until now just frustration. Anyone!
Extra credit
Preserve Unicode combining characters.
For example, “as⃝df̅” becomes “f̅ds⃝a”, not “̅fd⃝sa”.
noel
May 9, 2020, 2:19pm
13
Is this measurable?
Slowest always fastest.
static final String STR = "àéïõû";
int start_time;
void setup() {
println(STR);
start_time = millis();
for (int i = 0; i <= 100000000; i++) {
String temp = reverseSlow(STR);
}
println(millis()-start_time);
start_time = millis();
for (int i = 0; i <= 100000000; i++) {
String temp = reverseFast(STR);
}
println(millis()-start_time);
}
static final String reverseFast(final CharSequence s) {
return new StringBuilder(s).reverse().toString();
}
static final String reverseSlow(final String s) {
return new String(reverse(s.toCharArray()));
}
2 Likes
Nice catch @noel !
I’ve just assumed a solution w/ StringBuilder would be faster, but I was wrong.
Actually reverseSlow() is more than 2x faster than reverseFast() !
However the Java/Pjs cross-mode reverseStr() is absurdly slower than the Java-only versions.
// Discourse.Processing.org/t/rosetta-challenge-reverse-a-string/20644/14
// GoToLoop (2020/May/09)
static final String STR = "àéïõû";
static final int ITERS = 10_000_000, LOOPS = 3, FUNCTS = 4;
final IntList timers = new IntList(LOOPS * FUNCTS);
void setup() {
println("reverseStr(), reverseUnicode(), reverseSlow(), reverseFast()");
for (int i = 0; i < LOOPS; ++i) {
reverseStrMillis();
reverseUnicodeMillis();
reverseSlowMillis();
reverseFastMillis();
println(timers);
}
exit();
}
void reverseStrMillis() { // slowest
final int start = millis();
String s;
for (int i = 0; i < ITERS; ++i) s = reverseStr(STR);
timers.append(millis() - start);
}
void reverseUnicodeMillis() { // slow
final int start = millis();
String s;
for (int i = 0; i < ITERS; ++i) s = reverseUnicode(STR);
timers.append(millis() - start);
}
void reverseSlowMillis() { // fastest
final int start = millis();
String s;
for (int i = 0; i < ITERS; ++i) s = reverseSlow(STR);
timers.append(millis() - start);
}
void reverseFastMillis() { // fast
final int start = millis();
String s;
for (int i = 0; i < ITERS; ++i) s = reverseFast(STR);
timers.append(millis() - start);
}
static final String reverseStr(final String s) { // slowest
return join(reverse(s.split("")), "");
}
static final String reverseUnicode(final CharSequence s) { // slow
final int[] reversedUnicodes = reverse(s.codePoints().toArray());
return new String(reversedUnicodes, 0, reversedUnicodes.length);
}
static final String reverseSlow(final String s) { // fastest
return new String(reverse(s.toCharArray()));
}
static final String reverseFast(final CharSequence s) { // fast
return new StringBuilder(s).reverse().toString();
}
2 Likes
I found it frustrating too. I believe that in order to correctly do this you need to correctly parse the unicode string into graphemes and reverse the grapheme list. Clearly there are implementations that are able to do this,
but I haven’t seen one for Java 8 – let alone a simple one. StringBuilder may have built-in support for this in some Java version… but given that PDE 3 can’t display these characters anyway – either in the editor or in output – I honestly don’t see the point of that part of the task for most Processing users.
noel:
How so?
Hmm. I may have launched 3.4 by habit.
So it looks like, in PDE 3.5.4,
as⃝df̅ … is the string
a sdf- … is what the editor can display, and
a sdf̅ … is what the window draws. So there is partial support.
In 3.4, the main difference is just the circle. The string in the editor separates the f and includes a broken-box image for the circle rather than silently dropping it, like this:
and then draws with open boxes, like this:
How about this 1 relying on CharSequence ::codePoints() ?
Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/CharSequence.html#codePoints()
// Discourse.Processing.org/t/rosetta-challenge-reverse-a-string/20644/18
// GoToLoop (2020/May/09)
static final String TXT = "I💖🎮!";
void setup() {
noLoop();
background(#0000FF);
fill(#FFFF00);
textAlign(CENTER, BASELINE);
println(TXT);
text(TXT, width >> 1, height >> 2);
final String rev = reverseUnicode(TXT);
println(rev);
text(rev, width >> 1, 3 * height >> 2);
}
static final String reverseUnicode(final CharSequence s) {
final int[] reversedUnicodes = reverse(s.codePoints().toArray());
return new String(reversedUnicodes, 0, reversedUnicodes.length);
}
1 Like
And apparently Python Mode doesn’t need any changes at all:
# Discourse.Processing.org/t/rosetta-challenge-reverse-a-string/20644/19
# GoToLoop (2020/May/09)
TEXTS = 'asdf', u'àéïõû', u'I💖🎮!'
def setup():
print TEXTS
print TEXTS[0], TEXTS[1], TEXTS[2]
print reverseStr(TEXTS[0]), reverseStr(TEXTS[1]), reverseStr(TEXTS[2])
exit()
def reverseStr(s): return s[::-1]
(‘asdf’, u’\xe0\xe9\xef\xf5\xfb’, u’I\U0001f496\U0001f3ae!’)
asdf àéïõû I💖🎮!
fdsa ûõïéà ! I
2 Likes
Very cool! but not quite yet. When I run that,
“as⃝df̅” incorrectly becomes “̅fd⃝sa” – with bar ahead of f, and circle on fd, not sa. That is the example of bad output that the wiki task gives.
It should output “f̅ds⃝a”.