32
\$\begingroup\$

This challenge is inspired by one of my other challenges: Pointlessly make your way down the alphabet

That challenge asked you to take a string of text, and for each letter produce a sequence of letters moving down the alphabet to 'a'.

For this challenge I'd like to decode the output of that challenge (minus the line breaks), to find a human-readable string from a much longer human readable string.


Here is some text which has been encoded using the Dreaded Alphabet Cypher™️

hgfedcbaedcbalkjihgfedcbalkjihgfedcbaonmlkjihgfedcba wvutsrqponmlkjihgfedcbaonmlkjihgfedcbarqponmlkjihgfedcbalkjihgfedcbadcba

It consists of descending alphabetical sequences, ending in an 'a'. The first character in each of these sequences is a letter in the decoded text. (A space is still a space).

The challenge

  • Write code to convert a Dreaded Alphabet Cypher™️ encoded string into a decoded, human-readable string.
  • No need to validate if it is a Dreaded Alphabet Cypher™️ string, I'm not interested in how it handles invalid input.
  • Use any language you please.
  • Please include a link to an online iterpreter.
  • The input will only consist of lower-case letters and spaces. No upper cases, punctuation etc.
  • Code golf, try to write short code, standard loopholes etc.

Test Cases

Input:

hgfedcbaedcbalkjihgfedcbalkjihgfedcbaonmlkjihgfedcba wvutsrqponmlkjihgfedcbaonmlkjihgfedcbarqponmlkjihgfedcbalkjihgfedcbadcba

Output:

hello world

Input:

abacbadcbaedcbafedcbagfedcbahgfedcbaihgfedcbajihgfedcbakjihgfedcbalkjihgfedcbamlkjihgfedcbanmlkjihgfedcbaonmlkjihgfedcbaponmlkjihgfedcbaqponmlkjihgfedcbarqponmlkjihgfedcbasrqponmlkjihgfedcbatsrqponmlkjihgfedcbautsrqponmlkjihgfedcbavutsrqponmlkjihgfedcbawvutsrqponmlkjihgfedcbaxwvutsrqponmlkjihgfedcbayxwvutsrqponmlkjihgfedcbazyxwvutsrqponmlkjihgfedcba

Output:

abcdefghijklmnopqrstuvwxyz

(beware the multiple a's)

Input:

aarqponmlkjihgfedcbaonmlkjihgfedcbanmlkjihgfedcba a aarqponmlkjihgfedcbaonmlkjihgfedcbanmlkjihgfedcbasrqponmlkjihgfedcbaonmlkjihgfedcbanmlkjihgfedcba hgfedcbaasrqponmlkjihgfedcba anmlkjihgfedcba aarqponmlkjihgfedcbadcbavutsrqponmlkjihgfedcbaarqponmlkjihgfedcbakjihgfedcba

Output:

aaron a aaronson has an aardvark

Input:

hgfedcbaaponmlkjihgfedcbaponmlkjihgfedcbayxwvutsrqponmlkjihgfedcba gfedcbaonmlkjihgfedcbalkjihgfedcbafedcbaihgfedcbanmlkjihgfedcbagfedcba

Output (is a secret, shh)

\$\endgroup\$
  • \$\begingroup\$ May the input contain leading or trailing spaces, or several spaces in a row? \$\endgroup\$ – Arnauld Nov 29 '19 at 14:17
  • \$\begingroup\$ @Arnauld I'm happy with trailing and leading spaces, but not within the result itself. \$\endgroup\$ – AJFaraday Nov 29 '19 at 14:19
  • \$\begingroup\$ Sorry, I meant the input, not the output. (I've edited my previous comment.) \$\endgroup\$ – Arnauld Nov 29 '19 at 14:20
  • \$\begingroup\$ @Arnauld The input could have trailing and leading spaces. \$\endgroup\$ – AJFaraday Nov 29 '19 at 16:43
  • 1
    \$\begingroup\$ @JonathanAllan sounds fine to me \$\endgroup\$ – AJFaraday Nov 29 '19 at 19:12

38 Answers 38

2
\$\begingroup\$

Python 2, 87 86 84 bytes

lambda i:"".join(x[:2]if'a'>x else x[0]for x in i.replace('a','a#').split('#')[:-1])

Try it online!

Non-regex effort. Replaces a with a plus a disposable character then splits on the disposable character and outputs either the first or first two letters of each list element depending on whether the first is a space or not.

\$\endgroup\$
2
\$\begingroup\$

Ruby, 20 + 1 bytes

gsub /(?<!a|\b)./,''

1 extra byte for the p command line option:

$ ruby -p alphabet_cypher.rb <<< "hgfedcbaedcbalkjihgfedcbalkjihgfedcbaonmlkjihgfedcba wvutsrqponmlkjihgfedgfedcbarqponmlkjihgfedcbalkjihgfedcbadcba"
hello world

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Charcoal, 8 bytes

Φ苧θ⊖κb

Try it online! Link is to verbose version of code. Explanation:

 θ          Input string
Φ           Filtered where
    θ       Input string
   §        Cyclically indexed by
      κ     Current index
     ⊖      Decremented
  ‹         Is less than
       b    Literal string `b`
            Implicitly print
\$\endgroup\$
2
\$\begingroup\$

Wren, 67 bytes

Non-regex effort. I can't use regex because Wren doesn't support it..

Fn.new{|x|x.replace(" "," a").split("a")[0..-2].map{|i|(i+"a")[0]}}

Explanation

Fn.new{|x|                                                        } // New anonymous function with parameter x.
          x.replace(" "," a")                                       // Append spaces with the a character in order to make them individual.
                             .split("a")                            // Split into a list with the character a.
                                        [0..-2]                     // We have a trailing unused a, so we need to remove it.
                                               .map{|i|          }  // Foreach this list:
                                                       (i+"a")      // Append this item with an a character(since we have used it for the splitting function)
                                                              [0]   // Return the first item in this list

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Java (JDK), 35 bytes

s->s.replaceAll("([b-z]).*?a","$1")

Try it online!

\$\endgroup\$
2
\$\begingroup\$

J, 18 bytes

({.;.2~'a'=])&>@;:

Try it online!

\$\endgroup\$
2
\$\begingroup\$

Burlesque, 21 19 bytes

{'`+]2CO:so)[-}ww\[

Try it online!

Non-regex solution, can save 2 bytes if permitted to return list of chars

{
 `'+] # Prefix each word with a backtick
 2CO  # Create n-grams of length 2 (abc => {ab bc})
 :so  # Filter for those which are in alphabetical order
 )[-  # Take the last letter of each n-gram
}ww   # For each word
\[    # Concatenate to string
\$\endgroup\$
1
\$\begingroup\$

PHP, 67 bytes

According to the definition, we don't have to worry about invalid input. So I'm not actually checking if all the letters between the intended letter and "a" are properly following the reverse alphabet order, or even if there's the right number of letters. Feels a bit dirty, but it works for all valid input :)

for($x=0;$c=$argn[$x++];){$l=$l?$l:$c;if(ord($c)<98){echo$l;$l=0;}}

Try it online!

\$\endgroup\$

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.