# Reverse-ish a string!

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

Example:

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"

• For those who can see deleted posts, the sandbox was here. – Comrade SparklePony Oct 6 '17 at 17:00
• Is the string guaranteed to only contain ASCII characters? – Leaky Nun Oct 6 '17 at 19:37
• @LeakyNun Yes, I will edit. – Comrade SparklePony Oct 6 '17 at 19:53

# Pyth, 1 byte

X


Verify all the test cases.

Pyth has wonderful built-ins :-)

# Pyth,  8  7 bytes

sm@_QxQ


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.

• Why does Pyth have this as a built in? How is it useful other than this question? – Jerry Jeremiah Oct 9 '17 at 6:58
• @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. – 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!

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

# Jelly, 5 bytes

iÐ€ịṚ


Try it online!

## CJam, 7 bytes

q__W%er


Try it online!

### Explanation

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.

• I wish Jelly's y worked like that. – Erik the Outgolfer Oct 6 '17 at 17:49
• @EriktheOutgolfer I wish Alice's y worked like that. :P – Martin Ender Oct 6 '17 at 17:49

# MATL, 6 bytes

PGt&m)


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

R‡


Try it online!

Explanation:

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


## Alice, 17 bytes

/?.R?y.@
\i.!yDo/


Try it online!

### Explanation

/...@
\.../


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

i.!?D.?.Ryyo


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

L@Q_M@s


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

eval"y/\$_/".reverse."/"


Try it online!

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

# JavaScript ES6 50 bytes

3 bytes saved thanks to Justin Mariner

s=>[...s].map(x=>s.slice(~s.indexOf(x))[0]).join


### Test it:

f=s=>s.split.map(x=>s.slice(~s.indexOf(x))[0]).join

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

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

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

# R, 68 65 bytes

function(s)chartr(paste(rev(el(strsplit(s,''))),collapse=''),s,s)


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:

function(s)paste(rev(s<-el(strsplit(s,'')))[match(s,s)],collapse='')


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:

function(s){
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

i,n,a[256];char*f(char*c){n=strlen(c);for(i=n;i>0;i--)a[c[i-1]]=c[n-i];for(;i<n;i++)c[i]=a[c[i]];}


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!

• 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! – Giuseppe Oct 8 '17 at 19:01

# Python, 191 128 bytes

w=input("")
c=[]
for x in range(0,len(word)):
chars.append(word[x])
back = []
for x in chars:
back.insert(0,x)
final = ""
for x in back:
final = final + x
print(final)


Try it online

• 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. – NoOneIsHere Oct 8 '17 at 17:15

# Java 8, 100 bytes

s->{char[]a=new char[256];int l=s.length,i=l;for(;i>0;a[s[i-1]]=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.

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

Try it here.