Reverse the consonants

42

6

The program should take a string as input and reverse the consonants in it, while keeping the order of vowels. All the letters will be lowercase, so you don't have to worry about casing. Examples follow.

  1. Input: a test case.
    The consonants here are t,s,t,c,s. They should come in reversed order, i.e. s,c,t,s,t and inserted back into the string to the same positions where the pre-reversed characters were located: a sect sate.

  2. Input: well-done. Output: nedl-lowe.

  3. Input: reverse the consonants. Output: setenne sne cohtosarvr.

This is the code golf, the shortest solution wins.

Y should be considered vowel regardless of what it is and not reversed.

Anything, as well as numbers, punctuation, quotes, and other symbols (@#$%^&*(){}[]\|/<>~-_+=`), could potentially appear in the input.

nicael

Posted 2016-06-17T16:09:46.440

Reputation: 4 585

Answers

16

Retina, 22 21 20 17

O#^`[b-z-[eiouy]]

Try it online!

1 byte thanks to Leaky Nun!

4 bytes thanks to Martin!

O means sort, and # means to sort by numeric value. Since none of the matched characters will ever have a numeric value, all letters have the same weight: 0. ^ means to reverse the order of the sorted values, which thanks to stable sorting means the values are reversed.

The -[...] means to do the setwise difference between the outer character class and this inner class. This is part of .NET and you can read more at the MSDN.

FryAmTheEggman

Posted 2016-06-17T16:09:46.440

Reputation: 16 206

Very nice. Is -[...] specific to retina, or specific to .net regexes or is it a general regex feature that I've overlooked until now? – Digital Trauma – 2016-06-17T17:42:17.837

@DigitalTrauma With this syntax I think it's specific to .NET. Other flavours have character class intersection as well, but then I think the syntax is usually [...&&[^...]]. – Martin Ender – 2016-06-17T17:44:00.763

@MartinEnder I'll have to try these with sed and grep. Unlikely sed has it, but perhaps PCRE-mode grep. – Digital Trauma – 2016-06-17T17:52:23.840

1Perl 6 uses <[b..z] - [eiouy]> or <:Ll - [aeiouy]> to do set difference – Brad Gilbert b2gills – 2016-06-18T01:34:08.940

15

Python 2, 86 bytes

s='';c=()
for x in input():b='{'>x not in'aeiouy'<x;s+=b*'%s'or x;c=(x,)*b+c
print s%c

Takes input as a string in quotes. Iterates through the input, replacing each consonant with %s in s. The tuple c stores the consonants encountered in reversed order. Then, string formatting replaces the %s's in s with the consonants in c.

Thanks to Sp3000 for the consonant check, which saved 4 bytes over listing the consonants.

xnor

Posted 2016-06-17T16:09:46.440

Reputation: 115 687

1This is a beautiful bit of code golf :) – Lynn – 2016-06-18T11:06:46.053

Really elegant, and surprisingly short, this being Python – DevilApple227 – 2016-06-18T20:03:17.773

9

Jelly, 22 20 bytes

Øaḟ“<1Ṛż»
e€¢œpżf¢Ṛ$

Try it online!

How it works

Øaḟ“<1Ṛż»   Helper link. No arguments.

Øa          Yield the lowercase alphabet/
   “<1Ṛż»   Decompress that string, yielding "oui aye".
  ḟ         Filter; remove the characters from the right string from the left one.


e€¢œpżf¢Ṛ$  Main link. Argument: s (string)

  ¢         Call the helper link, yielding the string of all consonants.
e€          Test each character of s for membership.
   œp       Partition s at members/consonants.
         $  Combine the three links to the left into a monadic chain.
      f¢    Filter by presence in the consonant string.
        Ṛ   Reverse the result.
     ż      Zipwith; interleave chunks of non-consonants and reversed consonants.

Dennis

Posted 2016-06-17T16:09:46.440

Reputation: 196 637

6

JavaScript ES6, 82 81 80 78 bytes

Saved a byte thanks to each of Martin and Leaky Nun, and 2 bytes to Neil!

a=>a.replace(r=/(?[_aeiouy])\w/g,e=>[...a].reverse().join``.match(r)[i++],i=0)

Testing

f=
a=>a.replace(r=/(?![aeiouy])[a-z]/g,e=>[...a].reverse().join``.match(r)[i++],i=0)
;
q.onchange=q.onkeydown=q.onkeyup=function(){
  o.innerHTML = "";
  o.appendChild(document.createTextNode(f(q.value)));
}
*{font-family:Consolas,monospace;}
<input autocomplete="off" id=q>
<div id=o></div>

Conor O'Brien

Posted 2016-06-17T16:09:46.440

Reputation: 36 228

1That's the worse abuse of function arguments. – Leaky Nun – 2016-06-17T16:39:05.300

/(?![aeiouy])[a-z]/g – Leaky Nun – 2016-06-17T16:40:41.183

Would /(?[_aeiouy])\w/g work? – Neil – 2016-06-17T17:07:19.513

@Neil No, that would match _, which is a symbol the OP wants to keep in place. – Conor O'Brien – 2016-06-17T17:10:36.140

/(?![eiouy])[b-z]/g thanks to Martin – Leaky Nun – 2016-06-17T17:24:01.317

@CᴏɴᴏʀO'Bʀɪᴇɴ I think you'll find that (?[_aeiouy]) won't match _... – Neil – 2016-06-17T18:26:30.350

1In your demo, you can change q.onchange=q.onkeydown=q.onkeyup= to just q.oninput=... – Patrick Roberts – 2016-06-17T21:10:34.410

Nice solution. I was playing around with the demo and starting typing this... :P – Oliver – 2019-03-19T20:15:26.413

5

Python 2, 106 bytes

s=input()
b=[x for x in s if x in'bcdfghjklmnpqrstvwxz']*2
print''.join(x in b and b.pop()or x for x in s)

Expects input in "quotes", which I think is allowed.

Lynn

Posted 2016-06-17T16:09:46.440

Reputation: 55 648

4

Pyke, 18 bytes

FD~c{IK_#~c{)oR@(s

Try it here!

or 16 bytes with the new version:

(Change so if for returns all string output and had string input, return string instead of a list)

FD~c{IK_#~c{)oR@

Try it here!

~c contains the consonants: bcdfghjklmnpqrstvwxz

F                - For i in input:
  ~c{I           -  if i in "bcdfghjklmnpqrstvwxz":
       _#~c{)    -    filter(reversed(input), <-- in "bcdfghjklmnpqrstvwxz")
             oR@ -   ^[o++]

Blue

Posted 2016-06-17T16:09:46.440

Reputation: 26 661

4

MATL, 18 22 21 bytes

tt2Y211Y2'y'hX-m)P5M(

1 byte saved thanks to @Luis

Unfortunately the longest part of this is getting the list of consonants (2Y211Y2'y'hX-).

Try it Online!

Explanation

            % Implicitly grab the input
tt          % Duplicate twice
2Y2         % Grab the pre-defined list of all lower-case letters
llY2        % Grab the pre-defined list of lower-case vowels (excluding 'y')
'y'h        % Add 'y' to the list of vowels
X-          % Find the set difference between these two lists (the consonants)
m           % Create a boolean array the size of the input that is true for all consonants
)           % Use this as an index to grab all consonants
P           % Reverse the order of the consonants
5M          % Get the boolean array again
(           % Re-assign the flipped consonants with the original consonant locations
            % Implicitly dislpay the result

Suever

Posted 2016-06-17T16:09:46.440

Reputation: 10 257

1 byte fewer: tt2Y211Y2'y'hX-m)P5M( – Luis Mendo – 2016-06-18T00:37:46.817

@LuisMendo Excellent idea, thanks! – Suever – 2016-06-18T00:39:44.763

4

GNU sed, 73

Score includes +1 for the -r flag passed to sed.

:
s/([b-df-hj-np-tv-xz])(.*)([b-df-hj-np-tv-xz])/\u\3\2\u\1/
t
s/./\l&/g

Ideone.

Repeatedly switches the first and the last lowercase consonant and converts them to upper case, until there are no more matches. Then convert the whole string back to lowercase.

Digital Trauma

Posted 2016-06-17T16:09:46.440

Reputation: 64 644

4

JavaScript (ES6), 72 bytes

s=>s.split(/([^\W\d_aeiouy])/).map((c,i,a)=>i&1?a[a.length+~i]:c).join``

Splitting on /([^\W\d_aeiouy])/ results in the consonants falling in the odd-numbered entries in the array. It then suffices to switch those entries with the equivalent entry counting back from the end of the array and join the result together.

Neil

Posted 2016-06-17T16:09:46.440

Reputation: 95 035

Nice job! I didn't think about splitting. – Conor O'Brien – 2016-06-17T19:32:04.657

5The CIA appears to have infiltrated your code. – Patrick Roberts – 2016-06-17T21:18:51.517

I tried the same regexp but it reverse digits too – edc65 – 2016-06-18T14:27:39.743

4

J, 53 bytes

C.~[:~.<@~.@/:~"1@(,.|.)@I.@e.&'bcdfghjklmnpqrstvwxz'

Maybe the not the best way but I wanted to use C. since this can be solved using permutations.

Usage

   f =: C.~[:~.<@~.@/:~"1@(,.|.)@I.@e.&'bcdfghjklmnpqrstvwxz'
   f 'a test case'
a sect sate
   f 'well-done'
nedl-lowe
   f 'reverse the consonants'
setenne sne cohtosarvr

Explanation

C.~[:~.<@~.@/:~"1@(,.|.)@I.@e.&'...'  Input: s
                               '...'  The list of consonants
                            e.&'...'  Generate a boolean mask where an index is true
                                      if the char at that index in s is a consonant
                         I.@          Get a list of the true indices
                  (  |.)@             Reverse that list
                  (,.  )@             Join the original and reversed list as columns
            /:~"1@                    Sort each row of that 2d list
         ~.@                          Take the distinct values in each row
       <@                             Box them
   [:~.                               Take the distinct boxes - Now represents the
                                      permutation needed to solve this in cycle notation
C.~                                   Permute s according the cycles and return

miles

Posted 2016-06-17T16:09:46.440

Reputation: 15 654

4

Perl 5 (58 + 4 = 62 bytes)

$_=<>;$r=qr/(?![eiouy])[b-z]/;@a=/$r/g;s/$r/pop@a/ge;print

+4 penalty for running with -0777 flag, which sets Perl to slurp mode to handle newlines correctly.

Accepts input through STDIN and prints to STDOUT.

Explanation

                   $_=<>;   Read the input
 $r=qr/(?![eiouy])[b-z]/;   Save the regex; we'll be using it twice
                @a=/$r/g;   Store all the consonants in an array
           s/$r/pop@a/ge;   Replace each consonant with the final value in the array and pop
                   print    Output the result

Silvio Mayolo

Posted 2016-06-17T16:09:46.440

Reputation: 1 817

4

Perl 5, 92 68 55 bytes

Saved 37 bytes thanks to @manatwork's help. ;-)

$_=<>;@b=@a=/[^\Waeiou]/g;print$_~~@b?pop@a:$_ for/./g

A translation of @Lynn Python solution to Perl.

aries

Posted 2016-06-17T16:09:46.440

Reputation: 41

Hello, and welcome to PPCG! – NoOneIsHere – 2016-06-18T03:54:37.327

1@NoOneIsHere Sorry, what is PPCG. – aries – 2016-06-18T04:01:35.817

Programming Puzzles & Code Golf. – NoOneIsHere – 2016-06-18T04:03:55.153

@NoOneIsHere yeah, Thanks. :-) – aries – 2016-06-18T04:28:01.993

1Some “g” force would help there: @s=split//;@s=/./g; and for(@s){push@a,$_ if(/[^\Waeiou]/);}@a=/[^\Waeiou]/g;. I mean, m// with g modifier returns an array of all matches. – manatwork – 2016-06-19T12:16:00.073

@manatwork Thanks you very much for your help! You taught me that trick. ;-) I updated my code just now. – aries – 2016-06-20T10:14:04.463

1The 2nd version could be reduced by joining the assignments: @b=@a=…. Also the for having a single statement in the block (in which case the ; is not necessary after it), you could transform it into statement modifier and spare the delimiters: print$_~~@b?pop@a:$_ for/./g. (Yepp, sorry, missed that: no need to store @s value in a variable.) – manatwork – 2016-06-20T10:16:46.500

@manatwork it's better. I learnt a lot from your suggestion. Thanks. – aries – 2016-06-20T10:35:28.020

You can learn much more from Tips for golfing in Perl?. ;)

– manatwork – 2016-06-20T10:40:47.553

ok, I will read that. – aries – 2016-06-20T10:45:33.733

4

JavaScript (ES6), 57 70

Edit Amazing 20% saving thx @Neil

Late to the party, but it seems all javascript people missed something

a=>a.replace(r=/[^\W\d_aeiouy]/g,_=>c.pop(),c=a.match(r))

Test

f=a=>a.replace(r=/[^\W\d_aeiouy]/g,_=>c.pop(),c=a.match(r))

function test() {
  var i=I.value
  O.textContent=f(i)
}

test()
#I { width:90% }
<input id=I oninput="test()" value="reverse the consonants."><pre id=O></pre>

edc65

Posted 2016-06-17T16:09:46.440

Reputation: 31 086

@nicael it's simply out of place (nitpick!) (but thanks for noticing) – edc65 – 2016-06-18T10:58:32.553

As if it wasn't bad enough that (due to an error in my solution) you're beating me already, it seems that you should be able to save 13 bytes by using c.pop(). – Neil – 2016-06-18T17:23:21.783

@Neil wow thanks that's a huge improvement – edc65 – 2016-06-18T23:52:09.740

3

Pyth, 26 25 24 23 bytes

s.i:Q++\[J-G"aeiouy"\]3_@J
J-G"aeiouy"sm?@dJ@_@JQ~hZ     <-- just keeping this because of the @_@
J-G"aeiouy"sm?@dJ@@JQ=tZ
sm?@dJ-G"aeiouy"@@JQ=tZ
sm|-dJ-G"aeiouy"@@JQ=tZ

Test suite.

Leaky Nun

Posted 2016-06-17T16:09:46.440

Reputation: 45 011

3

Ruby, 53 50 bytes

-3 bytes from @manatwork

->s{i=0;s.gsub(r=/[^\Waeiouy_]/){s.scan(r)[i-=1]}}

Try it here

Value Ink

Posted 2016-06-17T16:09:46.440

Reputation: 10 608

Why has the code block an unused parameter? – manatwork – 2016-06-17T22:23:09.690

1@manatwork is right. Ruby will allow you to omit the unused parameter since it's a block. You could shave off three characters there. – Silvio Mayolo – 2016-06-18T03:19:48.880

@manatwork, I was initially going to use it for something, but then I didn't and as a result forgot to remove it – Value Ink – 2016-06-18T18:26:18.407

3

Java, 319 305 261 188 bytes

Credit to @Leaky Nun for helping with this :-)

char[]r(char[]s){int i=0,j=0,n=s.length;char[]o=new char[n];for(;i<n;i++){if((s[i]+"").matches("(?![eiouy])[b-z]")){o[j++]=s[i];s[i]=65;}}for(i=0;i<n;i++)if(s[i]==65)s[i]=o[--j];return s;}

Old:

s(String p){int i=0,j=0;char[]s=p.toCharArray(),o=p.toCharArray();for(;i<s.length;i++){if(((s[i]+"").matches("[aeiouy @#$%^&*(){}\\[\\]\\|/\\\\<>~\\-_+=`]")))continue;o[j++]=(s[i]);s[i]='A';}for(i=0;i<s.length;i++)if(s[i]=='A')s[i]=o[--j];return new String(s);}

Inspiration taken from here

Ungolfed

String s(String p){
    int i = 0, j = 0;
    char[]s=p.toCharArray(),o=p.toCharArray();
    for (;i<s.length;i++) {
        if (((s[i]+"").matches("[aeiouy @#$%^&*(){}\\[\\]\\|/\\\\<>~\\-_+=`]"))) continue;
        o[j++] = (s[i]); // Store the consonant into o
        s[i] = 'A'; // Put a special character in its place
    }
    for (i=0;i<s.length;i++)
        if (s[i] == 'A') // If special character
            s[i] = o[--j]; // Put back the consonant in reverse order
    return new String(s);
}

Insane

Posted 2016-06-17T16:09:46.440

Reputation: 280

2You can use 0 as the special character (null is guaranteed not to be in the String), and you can check it by s[i]<1 (there is no negative char) – Leaky Nun – 2016-06-18T03:10:45.820

I will char you to pieces. :) – gcampbell – 2016-06-18T09:57:57.003

3

Julia, 53 bytes

!s=s[flipud(i)]=s[i=find(c->'}'>c∉"aeiouy"<"$c",s)]

This takes a character array as input and reverses its consonants in-place. Try it online!

Credit goes to @Sp3000 for the lowercase consonant check.

How it works

i=find(...,s) yields all indices of s for which the predicate ... returns true and saves them it the variable i.

c->'}'>c∉"aeiouy"<"$c" performs three tests and returns true if and only if all are positive.

  • '}'>c checks if the character c comes before {.

  • "aeiou" checks if the string c comes after a.

  • c∉"aeiouy" verifies that c is not a vowel.

Finally, s[i] yields all consonants and s[flipud(i)]=s[i] assigns them to positions in s that correspond to the reversed indices in in i.

Dennis

Posted 2016-06-17T16:09:46.440

Reputation: 196 637

What encoding does this use ()? – Adám – 2016-06-18T22:38:05.937

1UTF-8, unfortunately. – Dennis – 2016-06-18T23:33:50.243

2

Python 2, 103 98 100 bytes

import re
def r(s):a=re.split("([^\W\d_aeiouy])",s);print''.join(sum(zip(a[::2],a[-2::-2]+['']),()))

Port of my JavaScript answer. Edit: Saved 5 bytes thanks to @Dennis♦, of which I promptly had to spend two fixing digits.

Neil

Posted 2016-06-17T16:09:46.440

Reputation: 95 035

2

APLX, 31 bytes

(c/t)←⌽t/⍨c←(t←⍞)∊⎕a~'aeoiuy'
t

⎕a~'aeoiuy' lowercase alphabet without vowels
t←⍞ store character input as t
c←()∊ store Boolean "consonant?" as c
t/⍨ extract (consonants) from t
reverse
(c/t)← replace consonants with (the reversed ones)
t return the modified string

Adám

Posted 2016-06-17T16:09:46.440

Reputation: 37 779

2

R, 120 bytes

New answer:

az=function(x){
y=strsplit(x, NULL)[[1]]
a=regexpr("[bc-df-hj-np-tv-z]", y)
y[a==1]=rev(y[a==1])
paste(y, collapse="")
}

takes a character string as x

az("reverse the consonants")
[1] "setenne sne cohtosarvr"

Old response below (110 bytes) was poor form on my part, which just reversed the consonants:

xrev=function(x){y=rev(strsplit(x, NULL)[[1]])
paste(y[is.na(match(y, c("a", "e","i","o","u","y")))], collapse="")}

Tim

Posted 2016-06-17T16:09:46.440

Reputation: 21

1

PowerShell, 81 bytes

-join(($a=$args|% t*y)|%{if($_-in($c=$a-match'[^\W\d_aeiouy]')){$_=$c[--$i]};$_})

Try it online!

Less golfed:

$a          = $args|% toCharArray
$consonants = $a-match'[^\W\d_aeiouy]'
$result     = $a|%{if($_-in$consonants){$_=$consonants[--$i]};$_}
-join($result)

PowerShell, 88 bytes, -f

$i=0;-join($args|% t*y|%{if($_-match'[^\W\d_aeiouy]'){$c=,$_+$c;$_="{$i}";$i++};$_})-f$c

Try it online!

mazzy

Posted 2016-06-17T16:09:46.440

Reputation: 4 832

1

Matlab, 67 chars

For an input 'this is a string of- stuff.'

s=input('','s');si=regexp(s,'[b-df-hj-np-tv-xz]');s(si)=s(flip(si))

produces s = ffit is a fgnirt os- ssuht.

si is the indices of the consonants in the input string. The final statement replaces those characters with the same characters but in reverse order by indexing.

sintax

Posted 2016-06-17T16:09:46.440

Reputation: 291

This isn't going to handle any punctuation except -. The question says that any punctuation is valid input and should be ignored. Also, you'll need to either use input('') to grab the input or write an anonymous function because we can't accept a variable as input like this. – Suever – 2016-06-17T18:44:42.750

1Also you can use flip to reverse the string. – Suever – 2016-06-17T18:48:23.950

Punctuation was edited into the question after I posted, but I'll fix that. As regards the input, can I just use ans, as that's what a default input to the Matlab console is assigned to? – sintax – 2016-06-17T18:48:41.513

1I don't think so. it should be a self-contained solution. You would need to do s=input('') or somehow craft this into an anonymous function @(s) – Suever – 2016-06-17T18:51:27.857

Ok, I'll do that later or tomorrow. I'm away from my computer now. – sintax – 2016-06-17T19:03:15.067

Not a problem! Let me know if you have any questions! – Suever – 2016-06-17T19:03:54.353

Since this requires a variable s to be defined, the submission is a snippet, which we don't allow by default. We require all submissions to be either full programs that read from STDIN and print to STDOUT, or functions that accept arguments and return values. – Alex A. – 2016-06-18T16:40:15.010

1

Python 2.7, 144 bytes

def f(a):c='bcdfghjklmnpqrstvwxz';b=[x for x in list(a[::-1])if x in c];[b.insert(x,a[x])for x in range(len(a))if a[x]not in c];return''.join(b)

This first builds a reversed list of the consonants, then inserts each of the other characters back in at their original index.

Un-golfed:

s = 'well-done'
reverse = list(s[::-1])
consonants = [i for i in reverse if i in 'bcdfghjklmnpqrstvwxz']

for x in range(len(s)):
    if s[x] not in 'bcdfghjklmnpqrstvwxz':
        consonants.insert(x,s[x])

print(''.join(consonants))

https://repl.it/C30O

atlasologist

Posted 2016-06-17T16:09:46.440

Reputation: 2 945

You can save bytes by making a variable for 'bcdfghjklmnpqrstvwxz' and calling that variable instead – MCMastery – 2016-06-19T18:17:36.447

1

Mathematica 216 bytes

Module[{h,v,i},v=Characters["aeiouy "];h[s_]:=SortBy[Flatten[Thread/@Transpose@{v,#[[All,1]]&/@(StringPosition[s,#]&/@v)},1],Last];i[s_,{a_,n_}]:=StringInsert[s,a,n];Fold[i,StringReverse@StringReplace[#,v->""],h@#]]&

martin

Posted 2016-06-17T16:09:46.440

Reputation: 1 335

1

s-lang, 17 16 bytes (non-competing)

Saved one byte because s-lang no longer requires last argument bracket

Try it online!

r[(?![aeiouy])\w

I started working on a string manipulation golfing language (I have been wanting to do this for a time now), and I thought this would be a fun question to work on it with.

Explanation:

  • r reverses the string with a given regex character matcher (if no regex argument is given, it will default to .)
  • [ begins the optional regex argument for r
  • (?![aeiouy])\w the regex to match any consonant character excluding y (unfortunately JavaScript doesn't allow character class subtraction)
  • ] usually ends optional regex argument for r, but we don't need it since it is the last function and last argument

MCMastery

Posted 2016-06-17T16:09:46.440

Reputation: 783

1

Haskell, 157 131 bytes

k="bcdfghjklmnpqrstvwxz";f c((r:q),s)=if c`elem`k then(q,r:s)else(r:q,c:s);f c("",s)=("",c:s);g s=snd$foldr f(filter(`elem`k)s,"")s

Update

@atlasologist's solution made me realize I only need a list of the consonants instead of pairs (no need to reverse them though since I'm using right fold.)

Ungolfed

consonants = "bcdfghjklmnpqrstvwxz"

-- Combining function (right fold, improved)
f :: Char -> (String, String) -> (String, String)
f c ((r:rest), s) = if c `elem` consonants then (rest, r:s) else (r:rest, c:s)
f c ("", s) = ("", c:s)

transform :: String -> String
transform s = snd $ foldr f (filter (`elem` consonants) s, "") s


main = do
    line <- getLine
    putStrLn . transform $ line

Old

c="bcdfghjklmnpqrstvwxz";n c(a@((f,t):q),s)=if c==f then(q,t:s)else(a,c:s);n c([],s)=([],c:s);g s=let z=filter(`elem`c)s in snd$foldr n(zip (reverse z)z,"")s

Creates a list of pairs of consonants, then walks through the string replacing each consonant using said list.

A bit primitive, but I wanted to figure this out without looking at the answers first. :)

sudee

Posted 2016-06-17T16:09:46.440

Reputation: 551

4Some tips: a) use guards instead of if ... then ... else. b) f is better written as an infix operator, say %. c) no need for the inner pair of () in ((r:q),s). d) replace "" with _ in the 2nd line of f. All in all (k stays the same): c%(r:q,s)|c`elem`k=(q,r:s)|1<2=(r:q,c:s);c%(_,s)=("",c:s);g s=snd$foldr(%)(filter(`elem`k)s,"")s. – nimi – 2016-06-20T20:26:37.327

0

q/kdb+, 45 bytes

Solution:

{x[w]:x(|)w:(&)max x=/:.Q.a except"aeiouy";x}

Explanation:

Find indices of the consonants, and replace them with the reversed consonants:

{x[w]:x reverse w:where max x=/:.Q.a except "aeiouy";x} / ungolfed
{                                                   ; } / two-statement lambda
                                .Q.a except "aeiouy"    / alphabet (a..z) except vowels
                            x=/:                        / equals each-right (returns boolean lists where input is each a consonant)
                        max                             / 'or' the results together
                  where                                 / indices where results are true
                w:                                      / save in variable w
        reverse                                         / reverse this list
      x                                                 / index into input at these indices
 x[w]:                                                  / assign values to x at indices w
                                                     x  / return x

Notes:

I had 3 ways to build the consonant list, the one in the solution is slightly better than the alternatives:

  • "bcdfghjklmnpqrstvwxz" for 22 chars (most boring)
  • .Q.a _/0 3 6 11 16 19 for 21 chars (kinda cool, drop each index)
  • .Q.a except"aeiouy" for 19 chars (second most boring)

streetster

Posted 2016-06-17T16:09:46.440

Reputation: 3 635

0

Jq 1.5, 289 263 bytes

def C:"bcdfghjklmnpqrstvwxz";. as$s|[("^","")as$p|[match("([\($p)\(C)]+)";"g").captures[].string]]|.[1]|=(reduce map(length)[]as$l({s:add|explode|reverse|implode,r:[]};.r+=[.s[0:$l]]|.s=.s[$l:])|.r)|if$s[0:1]|inside(C)then[.[1,0]]else . end|transpose|map(add)|add

Explanation

def consonants:"bcdfghjklmnpqrstvwxz";

  . as $s
| [  ("^","") as $p                                              # parse string onto non-consonant
   | [match("([\($p)\(consonants)]+)";"g").captures[].string]]   # and consonant groups
| .[1] |= (
     reduce map(length)[] as $l (                                # build new for consonant groups
       {s:add|explode|reverse|implode,r:[]}                      # by adding groups from reversed string
     ; .r+=[.s[0:$l]] | .s=.s[$l:]                               
     )
     |.r
  )
| if $s[0:1]|inside(consonants) then  [.[1,0]] else . end        # put groups into proper order for merge
| transpose | map(add) | add                                     # merge groups into final string

Sample run

$ jq -MRr 'def C:"bcdfghjklmnpqrstvwxz";. as$s|[("^","")as$p|[match("([\($p)\(C)]+)";"g").captures[].string]]|.[1]|=(reduce map(length)[]as$l({s:add|explode|reverse|implode,r:[]};.r+=[.s[0:$l]]|.s=.s[$l:])|.r)|if$s[0:1]|inside(C)then[.[1,0]]else . end|transpose|map(add)|add' input
a sect sate
nedl-lowe
setenne sne cohtosarvr

Try it online

jq170727

Posted 2016-06-17T16:09:46.440

Reputation: 411

0

Java 8, 157 bytes

s->s.format(s.replaceAll("[^\\W\\d_aeiouy]","%s"),s.chars().mapToObj(c->""+(char)c).filter(c->c.matches("[^\\W\\d_aeiouy]")).reduce("",(x,y)->y+x).split(""))

Try it online!

Note: prints compiler warnings to stderr.
Explanation:

s->                                                    // Lambda function
    s.format(                                          // Format a string using the given arguments
        s.replaceAll("[^\\W\\d_aeiouy]","%s"),         // Generate the format string by replacing all consonants with "%s"
        s.chars()                                      // Stream the characters of the input string s
            .mapToObj(c->""+(char)c)                   // Map characters back to strings
            .filter(c->c.matches("[^\\W\\d_aeiouy]"))  // Filter out vowels and symbols
            .reduce("",(x,y)->y+x)                     // Build the string of consonants in reverse
            .split("")                                 // Turn into an array of single-char strings (varargs abuse)
    )                                                  // Implicit return of the formatted string

Not gonna lie, my only goal was to beat this answer

Benjamin Urquhart

Posted 2016-06-17T16:09:46.440

Reputation: 1 262

0

APL (Dyalog Extended), 22 bytes

⌽@(('aeiou'~⍨∘⌊⎕A)∊⍨⊢)

Try it online!

voidhawk

Posted 2016-06-17T16:09:46.440

Reputation: 1 796