# Rosetta Challenge! -- Reverse a String

**URL:** https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644
**Category:** Coding Questions
**Created:** [May 8, 2020, 7:34pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644 "2020-05-08T19:34:09Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [May 8, 2020, 7:34pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/1 "2020-05-08T19:34:09Z")

</div>

_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](http://rosettacode.org/) and / or to [Rosetta Examples](https://github.com/jeremydouglass/rosetta_examples_p5)._

* * *

### [Reverse a String](http://rosettacode.org/wiki/Reverse_a_string)

**Task** : Take a string and reverse it.  
For example: “asdf” becomes “fdsa”.

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [May 8, 2020, 8:30pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/2 "2020-05-08T20:30:10Z")

</div>

## Processing’s Java Mode:

```auto
// 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:

```auto
// 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("")), "");
}

```

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [May 8, 2020, 8:54pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/3 "2020-05-08T20:54:34Z")

</div>

## Processing’s Python Mode:

```auto
# 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]

```

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [May 8, 2020, 10:16pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/4 "2020-05-08T22:16:00Z")

</div>

### Processing.R (R mode)

```auto
# 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

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [May 8, 2020, 10:21pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/5 "2020-05-08T22:21:41Z")

</div>

## p5.js:

```auto
// 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('');
}

```

---

<div class="post-metadata">

### Author: ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)
#### Post date: [May 8, 2020, 10:47pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/6 "2020-05-08T22:47:11Z")

</div>

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

```auto
String inputString = "àéïõû";
println(inputString);
String outString = "";
for (char c : inputString.toCharArray()) {
  outString = c + outString;
}
println(outString);

```

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [May 9, 2020, 4:43am UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/7 "2020-05-09T04:43:48Z")

</div>

> [@noel](#):
>
> maybe answers should be low-leveled

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:

```auto
println(paste(rev(strsplit("asdf", "")[[1]]), collapse = ""))

```

> fdsa

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [May 9, 2020, 4:48am UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/8 "2020-05-09T04:48:15Z")

</div>

…and in p5py, the immediate mode sketch would be two lines:

```auto
from p5 import *
print("asdf"[::-1])

```

> fdsa

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [May 9, 2020, 4:50am UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/9 "2020-05-09T04:50:43Z")

</div>

Python Mode’s 1-liner: `print u'àéïõû'[::-1]`  
Python 3’s 1-liner: `print('àéïõû'[::-1])`

---

<div class="post-metadata">

### Author: ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)
#### Post date: [May 9, 2020, 4:55am UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/10 "2020-05-09T04:55:56Z")

</div>

Yes. An example of what I mean is the task [Draw a sphere.](https://rosettacode.org/wiki/Draw_a_sphere#Processing) 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?

---

<div class="post-metadata">

### Author: ![Sven](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/sven/32/8293_2.png) [@Sven](https://discourse.processing.org/u/Sven)
#### Post date: [May 9, 2020, 1:43pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/11 "2020-05-09T13:43:18Z")

</div>

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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split#Parameters) (not Unicode characters). `Array.from` or `...` (spread syntax) could be used instead:

```javascript
const reverseStr = s => [...s].reverse().join('');

```

---

<div class="post-metadata">

### Author: ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)
#### Post date: [May 9, 2020, 1:50pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/12 "2020-05-09T13:50:02Z")

</div>

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”.

---

<div class="post-metadata">

### Author: ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)
#### Post date: [May 9, 2020, 2:19pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/13 "2020-05-09T14:19:56Z")

</div>

Is this measurable?  
Slowest always fastest.

```auto
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()));
}

```

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [May 9, 2020, 3:14pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/14 "2020-05-09T15:14:59Z")

</div>

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. 🐌

```auto
// 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();
}

```

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [May 9, 2020, 4:44pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/15 "2020-05-09T16:44:16Z")

</div>

> [@noel](#):
>
> Included in the task, and it is driving me mad.

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,

- [Reverse Unicode – Online Unicode Tools](https://onlineunicodetools.com/reverse-unicode)

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.

---

<div class="post-metadata">

### Author: ![noel](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/noel/32/213_2.png) [@noel](https://discourse.processing.org/u/noel)
#### Post date: [May 9, 2020, 5:02pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/16 "2020-05-09T17:02:21Z")

</div>

> [@jeremydouglass](#):
>
> PDE 3 can’t display these characters anyway – either in the editor or in output

How so?

![ide](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/9/96a6322ac113674824c7e4148a1018dd2e5f617d.jpeg) ![screen](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/9/9495ed31a5bc99bf5afd6045bfd38d52df29c368.jpeg)

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [May 9, 2020, 5:14pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/17 "2020-05-09T17:14:53Z")

</div>

> [@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:

![Screen Shot 2020-05-09 at 10.09.46 AM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/b/b1485eba456ed12bb6b8ecd5b37a68894230d5b0.png)

and then draws with open boxes, like this:

![Screen Shot 2020-05-09 at 10.09.25 AM](https://canada1.discourse-cdn.com/flex036/uploads/processingfoundation1/original/2X/f/f2bc880bf2166935e38c2aa7ee61c775f6c89c6c.png)

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [May 9, 2020, 6:09pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/18 "2020-05-09T18:09:45Z")

</div>

> [@jeremydouglass](#):
>
> … but I haven’t seen one for Java 8 – let alone a simple one.

How about this 1 relying on CharSequence::**codePoints()**? 😉  
[Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/CharSequence.html#codePoints()](http://Docs.Oracle.com/en/java/javase/11/docs/api/java.base/java/lang/CharSequence.html#codePoints())

```java
// 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);
}

```

---

<div class="post-metadata">

### Author: ![GoToLoop](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/gotoloop/32/86_2.png) [@GoToLoop](https://discourse.processing.org/u/GoToLoop)
#### Post date: [May 9, 2020, 6:19pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/19 "2020-05-09T18:19:53Z")

</div>

And apparently Python Mode doesn’t need any changes at all: 🥳

```auto
# 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

---

<div class="post-metadata">

### Author: ![jeremydouglass](https://yyz2.discourse-cdn.com/flex036/user_avatar/discourse.processing.org/jeremydouglass/32/20_2.png) [@jeremydouglass](https://discourse.processing.org/u/jeremydouglass)
#### Post date: [May 9, 2020, 7:27pm UTC](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644/20 "2020-05-09T19:27:58Z")

</div>

> [@GoToLoop](#):
>
> How about this 1 relying on CharSequence:: **codePoints()**?

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”.

[Next page](https://discourse.processing.org/t/rosetta-challenge-reverse-a-string/20644.md?page=2)
