Your task: write a program/function that when given a string containing only ASCII characters, outputs/returns the string in reverse-ish.


1) Input

Hello, World!

2) Number unique characters in input. (Input string separated by pipes (|) for readability)

H|e|l|l|o|,| |W|o|r|l|d|!
1 2 3   4 5 6 7   8   9 10

3) For duplicate characters, find the first occurrence of that character and number the duplicate character with the same number as the first.

H|e|l|l|o|,| |W|o|r|l|d|!
1 2 3 3 4 5 6 7 4 8 3 9 10

4) Reverse the string, but not the numbers.

!|d|l|r|o|W| |,|o|l|l|e|H
1 2 3 3 4 5 6 7 4 8 3 9 10

5) Delete the characters above repeat numbers. (Deleted characters represented with an asterisk.)

!|d|l|*|o|W| |,|*|l|*|e|H
1 2 3 3 4 5 6 7 4 8 3 9 10

6) Replace the deleted characters with the character that appears over the first occurrence of the number that the deleted character is over.

!|d|l|l|o|W| |,|o|l|l|e|H
1 2 3 3 4 5 6 7 4 8 3 9 10

7) Output

!dlloW ,olleH

Test cases:

Input -> Output
"Hello, World!" -> "!dlloW ,olleH"
"18464399" -> "99343488"
"Code Golf" -> "floG eloC"
"abcdefgABCDEFG" -> "GFEDCBAgfedcba"
"Mmm, marshmallows" -> "swwllwmhsrwm  mms"
"15147" -> "74751"
  • \$\begingroup\$ For those who can see deleted posts, the sandbox was here. \$\endgroup\$ – Comrade SparklePony Oct 6 '17 at 17:00
  • \$\begingroup\$ Is the string guaranteed to only contain ASCII characters? \$\endgroup\$ – Leaky Nun Oct 6 '17 at 19:37
  • \$\begingroup\$ @LeakyNun Yes, I will edit. \$\endgroup\$ – Comrade SparklePony Oct 6 '17 at 19:53

16 Answers 16


Pyth, 1 byte


Verify all the test cases.

Pyth has wonderful built-ins :-)

Pyth,  8  7 bytes


Verify all the test cases.

How it works

This is the more interesting non-built-in approach.

sm@_QxQ  - Full program.

 m       - Map over the input.
  @_Q    - Get the index in the reversed input.
     xQ  - Of the first index of each character in the String.
s        - Join the list.
  • 4
    \$\begingroup\$ Why does Pyth have this as a built in? How is it useful other than this question? \$\endgroup\$ – Jerry Jeremiah Oct 9 '17 at 6:58
  • \$\begingroup\$ @JerryJeremiah You can read more about this function here. It is the translate function in Pyth, but if the third argument is missing, the reverse of the second argument is used instead. \$\endgroup\$ – Mr. Xcoder Nov 5 '17 at 15:08

Python 2, 46 41 bytes

-5 bytes thanks to Artyer

lambda x:''.join(x[~x.find(n)]for n in x)

Try it online!

  • 1
    \$\begingroup\$ You can just do lambda x:''.join(x[~x.find(n)]for n in x) instead of reversing then indexing \$\endgroup\$ – Artyer Oct 7 '17 at 12:59

Jelly, 5 bytes


Try it online!


CJam, 7 bytes


Try it online!


q   e# Read all input.
__  e# Make two copies.
W%  e# Reverse the third copy.
er  e# Transliterate the input, mapping the input to its own reverse. Due
    e# to the way transliteration works in CJam, if a character in the source
    e# of the mapping is repeated, all but the first occurrence of that
    e# character are ignored.
  • \$\begingroup\$ I wish Jelly's y worked like that. \$\endgroup\$ – Erik the Outgolfer Oct 6 '17 at 17:49
  • \$\begingroup\$ @EriktheOutgolfer I wish Alice's y worked like that. :P \$\endgroup\$ – Martin Ender Oct 6 '17 at 17:49

MATL, 6 bytes


Try it online!

           implicit input
P          flip
 Gt        paste input back to stack and dup
   &m      alternate ismember, returns duplicated indices
     )     apply indices to the reversed char array
           implicit output, print as char

05AB1E, 2 bytes


Try it online!


R  Reverse input
 ‡ Transliterate the input with itself and its reverse (as above) (it only keeps first occurrences)

Alice, 17 bytes


Try it online!



This is just the usual template for linear code in Ordinal mode. If we unfold this, the actual program simply becomes:


The idea here is similar to that of my CJam answer. Since Alice has no easy way of indexing into strings with integers, it's easiest to replicate this behaviour with transliteration (y in Alice). However, Alice's transliteration semantics are a lot more general than CJam's, which means that Alice doesn't just disregard repeated mappings. For example, if we just wanted to transliterate Mmm, marshmallows to its reverse, this would represent the following list of mappings:

M -> s
m -> w
m -> o
, -> l
  -> l
m -> a
a -> m
r -> h
s -> s
h -> r
m -> a
a -> m
l ->  
l -> ,
o -> m
w -> m
s -> M

Note that we've got, for example, m -> w, m -> o, m -> a and m -> a. CJam would just discard all except the first mapping, but Alice would instead cycle through these. So the first m would be mapped to w, the second to o, the fifth again to w and so on. In this case that isn't helpful, because in general if we perform y on AAB (for some strings A and B) as we did in CJam, we'll always just get B in Alice.

So how do we compute a mapping that works for y (i.e. how do we discard the repeated mappings manually)? Of course, by using another transliteration. :)

The source of the mapping we want has to be the nub of the input (i.e. the deduplicated input). If we apply the above mapping to the nub, then each character only appears once, so we're only making use of the first of each of the repeated mappings. So by transliterating the nub with the input and its reverse, we're effectively simply discarding the duplicated mappings. We can then use the nub and this new result as a mapping for the original input. I'm sure that made sense to someone...

So the code:

i   Read input.                   ["Mmm, marshmallows"]
.!  Store a copy on the tape.
?D  Push the nub of the input.    ["Mmm, marshmallows" "Mm, arshlow"]
.   Duplicate.                    ["Mmm, marshmallows" "Mm, arshlow" "Mm, arshlow"]
?   Retrieve input.               ["Mmm, marshmallows" "Mm, arshlow" "Mm, arshlow" "Mmm, marshmallows"]
.R  Push its reverse.             ["Mmm, marshmallows" "Mm, arshlow" "Mm, arshlow" "Mmm, marshmallows" "swollamhsram ,mmM"]
y   Transliterate.                ["Mmm, marshmallows" "Mm, arshlow" "swllmhsr mm"]]
y   Transliterate.                ["swwllwmhsrwm  mms"]
o   Output.                       []

Pyke, 7 bytes


Try it here!

L@      - Get the index of the first index of each character.
  Q     - Push the input to the stack.
   _    - Reverse it.
    M@  - Get the element at (each) position in ^^^ in ^.
      s - Join.

Perl 5, 23 + 1 (-p) = 24 bytes


Try it online!

Thanks to @MartinEnder's Alice entry for the transliteration idea


JavaScript ES6 50 bytes

3 bytes saved thanks to Justin Mariner


Test it:


let inp = document.getElementById("inp");
let out = document.getElementById("out");

function change() {
  out.innerText = f(inp.value);

<input id="inp" type="text" oninput="change()" value="Hello, World!" /><br>
<p id="out"></p>


R, 68 65 bytes


Verify test cases!

Ports Erik's 05AB1E method for 3 bytes less. It wasn't the first, but it was the first one I saw.

old version:


Verify all test cases -- prints out the vector with the input as names and the output in quotes below.

A fairly naive implementation, but I don't think this gets shorter in R (and I look forward to being wrong about that). It's essentially an R port of Rod's python answer but it was developed independently.

Ungolfed explanation:

 s <- el(strsplit(s,''))      # string to characters
 r <- rev(s)                  # reverse s
 idx <- match(s,s)            # indices of first matches
 r <- r[idx]                  # do the replacement of duplicates
 paste(r, collapse = "")      # characters to string
}                             # implicit return of last evaluated statement

C (gcc), 98 bytes


Try it online!

Argument must be a modifiable string; string is modified in-place.


Röda, 27 bytes

f x{x|[x[-1-indexOf(_,x)]]}

Try it online!

This takes a list of characters as input and returns a stream of characters.

Using string datatype (40 bytes):

f x{x=x/""x|[x[-1-indexOf(_,x)]]|concat}

Try it online!


C (gcc), 57 bytes

int f(char*a){for(int u=strlen(a);--u>=0;)putchar(a[u]);}

Try it online!

  • 2
    \$\begingroup\$ This doesn't quite work -- the output for "Hello, World!" should be "!dlloW ,olleH" but it appears that this is just reversing the string. Feel free to edit your answer to try to conform to the challenge specifications! \$\endgroup\$ – Giuseppe Oct 8 '17 at 19:01

Python, 191 128 bytes

for x in range(0,len(word)):
back = []
for x in chars:
final = ""
for x in back:
  final = final + x

Try it online

  • 4
    \$\begingroup\$ Hi, and welcome to PPCG! This is a great answer, but it is not golfed (it has more bytes than it needs too). Please try to remove some bytes (for example by shortening the variable names) and edit your post. \$\endgroup\$ – NoOneIsHere Oct 8 '17 at 17:15

Java 10, 100 99 97 bytes

s->{var a=new char[256];int l=s.length,i=l;for(;i>0;a[s[--i]]=s[l+~i]);for(;i<l;s[i]=a[s[i++]]);}

Port of @LeakyNun's C answer. I doubt it can be done shorter without doing something similar in Java.
-1 byte thanks to @ceilingcat.

Input as char[] (character-array), and modifies this input instead of returning a new one to save bytes.

Try it here.

  • \$\begingroup\$ @ceilingcat Thanks! \$\endgroup\$ – Kevin Cruijssen Dec 20 '19 at 10:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.