DEV Community

Matt Ellen
Matt Ellen

Posted on • Updated on

Reverse a string: awful answers only

Today's challenge is to write a function that when given a string returns the string with the characters in the reverse order.

E.g.

reverseString('hello');
//output: 'olleh'
Enter fullscreen mode Exit fullscreen mode

But instead of trying to make a nice shiny function, write something bad. Throw space and time optimisations out the window. Double down on cyclomatic complexity. Make the compiler sad.

Tests

reverseString('Use Markdown to write and format posts.') == '.stsop tamrof dna etirw ot nwodkraM esU';
reverseString('You can use Liquid tags to add rich content such as Tweets, YouTube videos, etc.') == '.cte ,soediv ebuTuoY ,steewT sa hcus tnetnoc hcir dda ot sgat diuqiL esu nac uoY';
reverseString('In addition to images for the post\'s content, you can also drag and drop a cover image') == 'egami revoc a pord dna gard osla nac uoy ,tnetnoc s\'tsop eht rof segami ot noitidda nI';
reverseString('') == '';
Enter fullscreen mode Exit fullscreen mode

Top comments (18)

Collapse
 
gzuidhof profile image
Guido Zuidhof • Edited

Why not use Python's [::-1], but entirely in the browser? We can load the Pyodide runtime so we can run Python in the browser through WebAssembly. We'll have to eval as no ES module is shipped, but surely that's not a problem. Also the runtime is 20MB, but it's worth it!

var stringToReverse = "hello";

const reversed = new Promise((resolve) => {
    (async() => {
        const pyodideLoaderJS = await (await fetch("https://cdn.jsdelivr.net/pyodide/v0.15.0/full/pyodide.js")).text()
        await eval(pyodideLoaderJS)

        resolve(pyodide.runPython(`
            from js import stringToReverse;
            stringToReverse[::-1]
        `))
    })();
});

reversed.then(s => console.log(s));
Enter fullscreen mode Exit fullscreen mode

Copy it into your browser console and be amazed..

Collapse
 
kallmanation profile image
Nathan Kallman • Edited

Just shuffle the characters and see if it reversed the string! We'll get the reverse eventually.... (prepare to wait a long time for strings longer than 8 characters)

function reverseString(string, maxIterations = 10000, verbose = false) {
  const originalString = string.split("");
  let shuffledString = string.split("");
  let isReverse;
  let iteration = 1;
  do {
    for (let i = 0; i < shuffledString.length; i++) {
      let j = Math.floor(Math.random() * (string.length - i) + i);
      if (i != j) {
        shuffledString[i] = shuffledString[i] + shuffledString[j];
        shuffledString[j] = shuffledString[i].replace(shuffledString[j], "");
        shuffledString[i] = shuffledString[i].replace(shuffledString[j], "");
      }
    }
    if (verbose) console.log("Candidate string: ", shuffledString.join(""));
    isReverse = true;
    for (let i = 0; i < shuffledString.length; i++) {
      isReverse = isReverse && originalString[i] == shuffledString[shuffledString.length - 1 - i];
    }
    iteration++;
  } while (!(isReverse || iteration > maxIterations));
  if (isReverse) {
    return shuffledString.join("");
  } else {
    return false;
  }
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
gilfewster profile image
Gil Fewster

Perfect!

Collapse
 
mattother profile image
mattother

I'm loving this. Here my attempt:

// Reverses stuff.
function reverseString(y) {
    console.log('starting string reverse');
    console.warn('a string reverse is about to start'); q = esreveRgnirts(y);
    console.log('finished string reverse');
    return q
}

function esreveRgnirts (rts) {
  return xednIesreveRrts(rts, 0);
}

function xednIesreveRrts (rts, i) {
    if (i >= rts.length)
      return '';

  return tArahCteg(rts, rts.length - i - 1, 0) + xednIesreveRrts(rts, i+1);
}

function tArahCteg(rts, i, j) {
    if (i == j) {
        xeger = '^';
        for (q = 0; q < i; q++) {
            xeger += '.{1}';
        }
        xeger += "(.{1}).*$";
        r = new RegExp(xeger);
        return rts.match(r)[1];
    }
    return tArahCteg(rts, i, j + 1)
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
asdfdelta profile image
Christopher Graves

This is my favorite so far. The reversed signatures are a nice touch

Collapse
 
mattother profile image
mattother

Thanks! Felt very meta some how.

Collapse
 
mellen profile image
Matt Ellen

My humble submission:

function reverseString(s)
{
  let rev = s;
  for(let i = 0; i < s.length-1; i++)
  {
    let p = `(.)(.{${s.length-1-i},${s.length-1-i}})(.{${i},${i}})`;
    rev = rev.replace(new RegExp(p), '$2$1$3');
  }
  return rev;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
lionelrowe profile image
lionel-rowe • Edited

❤️ this challenge

This solution is inspired by my_first_calculator.py. It works for all lowercase alphabetic strings of length 3. The generated (non-evaled) version is 17,582 lines of code.

const reverse = eval(`str => {
${[...new Array(26).keys()].map(x =>
    [...new Array(26).keys()].map(y =>
        [...new Array(26).keys()].map(z =>
            [x, y, z]
                .map(n => String.fromCharCode(n + 'a'.charCodeAt(0)))
        )
    )
)
    .flat()
    .flat()
    .map(([x, y, z]) =>
        `    if (str === '${[x, y, z].join('')}') return '${[z, y, x].join('')}'`)
    .join('\n')}

    throw new RangeError(
        'Sorry, your string is not supported yet. Please try again in 3–6 months.'
    )
}`)
Enter fullscreen mode Exit fullscreen mode
Collapse
 
dwighthaul_52 profile image
Paul Hubert

When I open the "my_first_calculator.py" file it took so long, I thought something was wront with the git site ou my internet was down. Then I saw the file and I understood

Collapse
 
mdbetancourt profile image
Michel Betancourt • Edited

so easy

function reverse(val: string) {
  if(val==='a'){
    return 'a'
  } else if(val==='aa') {
    return 'aa'
  } else if(....) {} // 75 years later
  else if (val === 'aucn') {
    return 'ncua'
  }  else if(....) {} // 2000 years later
  else if (val === 'asynchronous') {
    return 'suonorhcnysa'
  }
}
console.log(reverse('asynchronous'))
Enter fullscreen mode Exit fullscreen mode

this works for any amount of chars xd

Collapse
 
yoursunny profile image
Junxiao Shi

We need a computer network.

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "strconv"
    "strings"
    "sync"
    "time"
)

func reverseString(s string) string {
    server := http.Server{
        Addr: ":8080",
        Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
            q := r.URL.Query()
            t, _ := strconv.Atoi(q.Get("t"))
            c, _ := strconv.Atoi(q.Get("c"))
            time.Sleep(time.Duration(len(s)-t) * 100 * time.Millisecond)
            w.Write([]byte{byte(c)})
        }),
    }
    go server.ListenAndServe()
    defer server.Close()
    time.Sleep(time.Second)

    client := http.Client{
        Timeout: time.Duration(len(s)) * time.Second,
    }
    var wg sync.WaitGroup
    var lock sync.Mutex
    var b strings.Builder
    for t, c := range []byte(s) {
        wg.Add(1)
        go func(t int, c byte) {
            defer wg.Done()
            res, e := client.Get(fmt.Sprintf("http://localhost:8080/?t=%d&c=%d", t, c))
            if e != nil {
                panic(e)
            }

            defer res.Body.Close()
            body, e := ioutil.ReadAll(res.Body)
            if e != nil {
                panic(e)
            }

            lock.Lock()
            defer lock.Unlock()
            b.Write(body)
        }(t, c)
    }

    wg.Wait()
    return b.String()
}

func main() {
    fmt.Println(reverseString("Use Markdown to write and format posts."))
    fmt.Println(reverseString("You can use Liquid tags to add rich content such as Tweets, YouTube videos, etc."))
    fmt.Println(reverseString("In addition to images for the post's content, you can also drag and drop a cover image"))
    fmt.Println(reverseString(""))
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
krussellsmith profile image
K. Russell Smith • Edited
#include <stdio.h>
#include <stdlib.h>
int len(const char*str)
{
    int result=0;
GETATIT:
    if (*(str+result++)=='\0') goto END;
    goto GETATIT;
END:
    return result;
}
char*reversed(const char* str)
{
    #define reset i=0
    char*result=(char*)malloc(sizeof(char)*len(str));
    int reset;
YOUCANDOIT:
    if ((*(result+len(str)-1-i)=*(str+i))=='\0')
        goto ONEMORESTEP;
    ++i;
    goto YOUCANDOIT;
ONEMORESTEP:
    reset;
    LOOP:
    *(result+i)=*(result+i+1);
    if (i++>=len(result)-1) goto WEDIDIT;
    goto LOOP;
WEDIDIT:
    *(result+i)='\0';
    return result;
}
int main(int argc, char*argv[])
{
    const char*str="Foo!";
    char*reverse=reversed(str);
    printf("%s\n",reverse);
    free(reverse);
    return 0;
}
Enter fullscreen mode Exit fullscreen mode

WEDIDIT 🎉

Collapse
 
pontakornth profile image
Pontakorn Paesaeng

I am too lazy to implement the reverse function so I made cursed version instead.

#include <stdio.h>
// Credit: https://www.programmingsimplified.com/c-program-reverse-string
#define function int
#define main main() {
#define consolelog printf
#define Systemscanf gets
#define konodioda return
function main
   char s[1000], r[1000];
   int begin, end, count = 0;

   consolelog("Input a string\n");

   Systemscanf(s);

   // Calculating string length

   while (s[count] != '\0')
      count++;

   end = count - 1;

   for (begin = 0; begin < count; begin++) {
      r[begin] = s[end];
      end--;
   }

   r[begin] = '\0';

   consolelog("%s\n", r);

   konodioda 0;
}
Enter fullscreen mode Exit fullscreen mode
Collapse
 
_garybell profile image
Gary Bell • Edited
function reverseString(string $input): string
{
    $reverseCode = '';
    for ($i = strlen($input) -1; $i >= 0; $i--) {
        //$reverseCode .= 'substr("' . str_replace("'", "\'", $input) . '", ' . $i . ', 1) . ';
        $reverseCode .= 'substr(\"' . $input . '\", ' . $i . ', 1) . ';
    }
    $reverseCode .= '\"\";';
    $reversedString = exec("php -r \"echo $reverseCode\"");
    return $reversedString;
}
Enter fullscreen mode Exit fullscreen mode

Ok, so this monstrosity uses the built-in substr method. But instead of using that to determine the string, it builds a whole bund of PHP code to execute within the shell, calls that via exec, and returns the string.

Awfully bad practice, inefficient, and dangerous. It's the type of code which gives PHP a bad name!

Collapse
 
edh_developer profile image
edh_developer • Edited

Go - convert the string to a slice of runes, swap the runes in the slice via some bit manipulation, then convert the slice back to string and return it.

Remember, to swap the values of two integers a and b...

a = a XOR b
b = a XOR b
a = a XOR b

func reverse(s string) string {
    characters := []rune(s)

    for i, j := 0, len(characters)-1; i < j; {
        characters[i] ^= characters[j]
        characters[j] ^= characters[i]
        characters[i] ^= characters[j]
        i++
        j--
    }

    return string(characters)
}
Enter fullscreen mode Exit fullscreen mode

Update: it occurred to me that the solution above may be odd, but it's not that inefficient. We can do better. So... take 2:

type charNode struct {
    C rune
    I int
}

func sortNodes(nodes []charNode) {

    var cn charNode

    for outer := len(nodes) - 1; outer > 0; outer-- {
        for inner := len(nodes) - 1; inner > 0; inner-- {
            if nodes[inner].I > nodes[inner-1].I {
                cn = nodes[inner]
                nodes[inner] = nodes[inner-1]
                nodes[inner-1] = cn
            }
        }
    }

}

func reverseViaSort(s string) string {
    nodes := make([]charNode, len(s))

    for i, r := range []rune(s) {
        nodes[i] = charNode{r, i}
    }

    sortNodes(nodes)
    sortedRunes := make([]rune, len(s))
    for i, n := range nodes {
        sortedRunes[i] = n.C
    }

    return string(sortedRunes)
}
Enter fullscreen mode Exit fullscreen mode

We split the string into a slice of ordered rune-index pairs, reverse the slice by sorting based on the indices, then get the resulting string from the reordered slice. It's pretty inefficient to begin with, and choosing bubblesort as our sorting algorithm gets us some O(N^2) fun.

Collapse
 
akashkava profile image
Akash Kava

Recursive reverse.

function reverse(s) {
if(!s) return “”;
return reverse(s.substring(1)) + s[0];
}

Collapse
 
y1s1h1 profile image
y1s1h1

include

using namespace std;
int main(){
cout << "Syntax error";
return 0;
}

Collapse
 
codemouse92 profile image
Jason C. McDonald

OOoooooooooooo, I love it! Bit late to this party (we'll see if I can get a terrible answer in later), but I hope you make a habit of posting these! My kind of challenge. :D