76
\$\begingroup\$

Ever fancied creating cool twitter hashtags such as #brexit or #brangelina? this golf is for you.


Write a program that accepts two strings A & B as input and merges them according to the following algorithm:

  1. let n be the number of vowels groups in A (e.g. britain has 2 vowels groups : i in position 3 and ai in position 5).
    • if n = 1 : truncate A starting at its first vowel group position (example: bill => b)
    • if n > 1 : truncate A starting at its n-1th vowel group position (example: programming => progr, britain => br)
  2. remove all consonants at the beginning of B (jennifer => ennifer)
  3. concatenate the modified A & B

Vowels are aeiou; consonants are bcdfghjklmnpqrstvwxyz.

Input

You can assume the input strings are lowercase and contain at least one vowel and one consonant.

Examples

brad + angelina      => brangelina
britain + exit       => brexit
ben + jennifer       => bennifer
brangelina + exit    => brangelexit
bill + hillary       => billary
angelina + brad      => angelad
programming + puzzle => progruzzle
code + golf          => colf
out + go             => o
\$\endgroup\$
  • 65
    \$\begingroup\$ New test case? donald trump. \$\endgroup\$ – Stewie Griffin Sep 26 '16 at 7:45
  • 5
    \$\begingroup\$ These are essentially portmanteaus. \$\endgroup\$ – mbomb007 Sep 26 '16 at 14:48
  • 3
    \$\begingroup\$ Related \$\endgroup\$ – ETHproductions Sep 27 '16 at 2:07
  • 1
    \$\begingroup\$ @ETHproductions this seems to produce much different combinations, such as Django + Angular = Djular \$\endgroup\$ – Pureferret Sep 27 '16 at 13:00
  • \$\begingroup\$ What's "n-1th vowel group position" \$\endgroup\$ – l4m2 May 23 '18 at 23:18

15 Answers 15

24
\$\begingroup\$

Ruby, 44 43 40 + 1 = 41 bytes

+1 byte for -p flag. Takes space-separated input on STDIN.
-1 byte thanks to Martin Ender
-2 bytes thanks to histocrat

sub /([aeiou]+([^aeiou]*)){,2} \g<2>/,""

Try it online!

GNU sed, 39 37 + 1 = 38 bytes

+1 byte for -E flag. Takes space-separated input on STDIN.
-1 byte thanks to Martin Ender

s/([aeiou]+[^aeiou]*){,2} [^aeiou]*//

Try it online!

Not posting this as a separate answer because it is literally the same solution.

\$\endgroup\$
  • \$\begingroup\$ Nice regex! Mind if I use part of it in my JS answer? \$\endgroup\$ – ETHproductions Sep 26 '16 at 3:06
  • \$\begingroup\$ Sure, go crazy. \$\endgroup\$ – Jordan Sep 26 '16 at 3:08
  • 3
    \$\begingroup\$ You can golf the regex a bit more by capturing the [^aeiou] as a subexpression: /([aeiou]+([^aeiou]*)){,2} \g<2>/ \$\endgroup\$ – histocrat Sep 26 '16 at 17:28
  • 5
    \$\begingroup\$ Crossed out 44 is still regular 44 ;( \$\endgroup\$ – Celeo Sep 26 '16 at 18:28
  • 1
    \$\begingroup\$ @Anko See "Special invocations" in this answer. TL;DR: Only count bytes in addition to the default invocation. The default invocation for Ruby is ruby -e "...". For this it's ruby -pe "...", so it only adds one byte. \$\endgroup\$ – Jordan Sep 28 '16 at 16:47
12
\$\begingroup\$

MATL, 31 30 bytes

t13Y2XJmFwhdl=fql_):)itJmYsg)h

Try it Online

Explanation

t       % Implicitly grab the input and duplicate it
13Y2    % Push the string literal 'aeiouAEIOU'
XJ      % Store this in clipboard J for later use
m       % Check which characters from the input are vowels (true for vowel)
Fwh     % Prepend FALSE to this logical array
dl=     % Compute the difference and find where we went from not-vowel to vowel
f       % Find the indices of these transitions
q       % Subtract 1 to get the location of the last consonant in each transition
l_)     % Get the next-to-last one of these
:)      % Grab the first string up to this location

% Now for the second component!

it      % Explicitly grab the input and duplicate
J       % Retrieve the string literal 'aeiouAEIOU' from clipboard J
m       % Find where the vowels are (true for vowel)
Ys      % Compute the cumulative sum along the array. The result will be 0
        % for all characters before the first vowel and non-zero after
g)      % Convert to logical and use this as an index so any characters
        % after the first value are retrieved

% Now to combine them

h       % Horizontally concatenate the first and second pieces together
        % Implicitly display the result
\$\endgroup\$
  • 1
    \$\begingroup\$ I always upvote happy code \$\endgroup\$ – Andras Deak Oct 14 '16 at 15:00
12
\$\begingroup\$

JavaScript (ES6), 81 73 72 bytes

Saved 8 bytes thanks to @Jordan, 1 thanks to @DavidConrad

a=>b=>a.match(/.*?(?=(?:[aeiou]+[^aeiou]*){1,2}$)/)+b.match(/[aeiou].*/)

Even though .match returns an array, array+array returns a string with the contents of the arrays concatenated (i.e. [0]+[1] returns "01").

Test snippet

f=a=>b=>console.log(a,"+",b,"=",a.match(/.*?(?=(?:[aeiou]+[^aeiou]*){1,2}$)/)+b.match(/[aeiou].*/))
f("brad")("angelina")
f("britain")("exit")
f("ben")("jennifer")
f("brangelina")("exit")
f("bill")("hillary")
f("angelina")("brad")
f("programming")("puzzle")
f("code")("golf")
f("progruzzle")("colf")
f("out")("go")
<input id=A value="super">
<input id=B value="chafouin">
<button onclick="f(A.value)(B.value)">Run</button>

Jordan's excellent Ruby solution would be 53 bytes in JS:

x=>x.replace(/([aeiou]+[^aeiou]*){1,2} [^aeiou]*/,"")
\$\endgroup\$
  • \$\begingroup\$ Maybe could just throw out the match bit and use a replace? \$\endgroup\$ – Conor O'Brien Sep 26 '16 at 3:13
  • \$\begingroup\$ @ConorO'Brien That kinda feels like stealing Jordan's answer :/ \$\endgroup\$ – ETHproductions Sep 26 '16 at 3:14
  • \$\begingroup\$ You quite literally read my mind. And yeah, that's true \$\endgroup\$ – Conor O'Brien Sep 26 '16 at 3:14
  • 1
    \$\begingroup\$ Currying (a,b)=> to a=>b=> saves 1 byte. \$\endgroup\$ – David Conrad Sep 26 '16 at 20:19
7
\$\begingroup\$

Jelly, 23 22 bytes

eۯcT
ǵḟ‘-ị’
Ç⁸ḣ⁹ÑḢ⁹ṫ

TryItOnline

How?

eۯcT    - Link 1, vowel indexes: s   e.g. "colouring"
  Øc     - yield vowels, "AEIOUaeiou"
e€       - in for each                     [0,1,0,1,1,0,1,0,0]
    T    - truthy indexes (1-based)        [2,4,5,7]

ǵḟ‘-ị’  - Link 2, n-1th or only vowel group index start - 1: s
 µ       - monadic chain separation
Ç        - call last link (1) as a monad   [2,4,5,7]
   ‘     - increment                       [3,5,6,8]
  ḟ      - filter out                      [2,4,7]
    -    - -1
     ị   - index value                     [4]
               (Jelly is 1-based and has modular indexing,
                so the last but one item is at index -1,
                and when there is only 1 item in the list it is also at index -1)
      ’  - decrement                       [3]

Ç⁸ḣ⁹ÑḢ⁹ṫ - Main link: a, b                      e.g. "colouring", "pencils"
Ç        - call last link (2) as a monad with a      [3]
 ⁸       - link's left argument, a
  ḣ      - head a[:y]                                "col"
   ⁹  ⁹  - link's right argument, b
    Ñ    - call next link (1) as a monad                          [2,5]
     Ḣ   - pop head                                               [2]
       ṫ - tail b[y-1:]                                           "encils"
         - implicit print                            "colencils"
\$\endgroup\$
  • \$\begingroup\$ Beautifully explained! \$\endgroup\$ – Pureferret Sep 27 '16 at 16:26
5
\$\begingroup\$

PowerShell v2+, 76 bytes

param($n,$m)($n-replace'([aeiou]+[^aeiou]*){1,2}$')+($m-replace'^[^aeiou]*')

Apparently this is a popular regex ... ;-)

Uses the -replace operator to pull off the appropriate pieces, then string-concatenates the results together. Adds on a $ to the first to ensure we pull the end of the string, and adds a ^ to the second to ensure we pull off the front of the string.

\$\endgroup\$
4
\$\begingroup\$

Retina, 35 bytes

([aeiou]+[^aeiou]*){1,2} [^aeiou]*

Try it online! (The first line enables a linefeed-separated test suite.)

Simply removes all matches of the regex on the first line.

\$\endgroup\$
  • 1
    \$\begingroup\$ Any plans to add vowel and non-vowel classes? ;-) \$\endgroup\$ – ETHproductions Sep 26 '16 at 14:54
  • \$\begingroup\$ @ETHproductions If I can ever be bothered to implement my own regex flavour (or at least tokenise it so that it can be transpiled to .NET regex), sure! :P \$\endgroup\$ – Martin Ender Sep 26 '16 at 15:06
  • \$\begingroup\$ Ruby can do pattern backreferences (same pattern that can match a different sequence of characters). These would be useful here. For example, matching parentheses are matched by /^((\(\g<1>\))*)$/ in Ruby. \$\endgroup\$ – John Dvorak Sep 27 '16 at 14:42
  • 1
    \$\begingroup\$ @JanDvorak Too bad Retina is written in .NET, huh? ;) I did consider bundling it with github.com/ltrzesniewski/pcre-net so that you can switch flavours, but didn't get around to that yet, and some other features are increasingly relying on .NET-specific match behaviour. \$\endgroup\$ – Martin Ender Sep 27 '16 at 14:55
  • 1
    \$\begingroup\$ Time to drop the .net specific behavior and rewrite everything in Ruby? Ruby is better anyways :-) \$\endgroup\$ – John Dvorak Sep 27 '16 at 14:59
4
\$\begingroup\$

Cinnamon Gum, 23 bytes

0000000: 64d3 884e 4ccd cc2f 8dd5 8e8e 8330 b434  d..NL../.....0.4
0000010: b108 d92b c0d9 00                        ...+...

Try it online.

Explanation

This decompresses to d([aeiou]+[^aeiou]*)([aeiou]+[^aeiou]*)? [^aeiou]*, which deletes anything matching that regex. (Note that Jordan's golfier d([aeiou]+[^aeiou]*){,2} [^aeiou]* compresses to 24 bytes due to the lack of repeated elements to compress.)

\$\endgroup\$
  • \$\begingroup\$ Would d[aeiou]+[^aeiou]*[aeiou]*[^aeiou]* [^aeiou]* be any shorter? \$\endgroup\$ – ETHproductions Sep 27 '16 at 2:06
  • \$\begingroup\$ @ETHproductions I tried that, it was the same byte count :( \$\endgroup\$ – a spaghetto Sep 27 '16 at 15:04
3
\$\begingroup\$

PHP, 95 Bytes

$t="aeiou]";echo($p=preg_filter)("#([$t+[^$t*){1,2}$#","",$argv[1]).$p("#^[^$t*#","",$argv[2]);

with preg_match instead of preg_filter 110 Bytes

$t="aeiou]";($p=preg_match)("#(.*?)([$t+[^$t*){1,2}$#",$argv[1],$m);$p("#[$t.*#",$argv[2],$n);echo$m[1].$n[0];
\$\endgroup\$
  • 1
    \$\begingroup\$ You can use + instead of {1,2}. \$\endgroup\$ – Titus Sep 26 '16 at 17:10
  • \$\begingroup\$ @Titus more important was to eliminate the bug for 1 case and now I can try to golf it down \$\endgroup\$ – Jörg Hülsermann Sep 26 '16 at 17:18
  • \$\begingroup\$ Use $v=aeiou; to save 3 more. \$\endgroup\$ – Titus Sep 26 '16 at 17:33
  • \$\begingroup\$ @Titus I had the same idea but with a little variant. Thank You \$\endgroup\$ – Jörg Hülsermann Sep 26 '16 at 17:47
3
\$\begingroup\$

Lua, 66 bytes

$ cat merge.lua
print(((...):gsub(("[]+[^]*[]*[^]*+[^]*"):gsub("]","aeiou]"),"")))
$ lua merge.lua brad+angelina
brangelina
$ lua merge.lua programming+puzzle
progruzzle
\$\endgroup\$
2
\$\begingroup\$

Perl 5, 39 bytes

38, plus 1 for -pe instead of -e

s/([aeiou]+[^aeiou]*){1,2} [^aeiou]*//

Hat tip.

\$\endgroup\$
  • \$\begingroup\$ Same as the sed answer linked to within, but we may as well have it in Perl also. \$\endgroup\$ – msh210 Sep 26 '16 at 16:50
2
\$\begingroup\$

Python 2, 139 bytes

n=lambda a,b:a[:a.index(([l for l in[[l,"!"][i!=0and a[i-1]in v]for i,l in enumerate(a)]if l in v]*2)[-2])]+b[sorted([(b+v).index(c)for c in v])[0]:]

This one was hard.

Check it out on repl.it

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

Lithp, 65 bytes

#X::((replace X (regex "([aeiou]+[^aeiou]*){1,2} [^aeiou]*") ""))

This is basically a port of the JavaScript answer above, in my Lisp-ish functional programming language.

Example usage:

(
    % Note, you can define this as a function, or assign it to a variable
    % and use the call function instead.
    (def f #X::((replace X (regex "([aeiou]+[^aeiou]*){1,2} [^aeiou]*") "")))
    (print (f "programming puzzle"))
)

No online interpreter yet. I'll provide one soon. It won't be difficult, my language is written in JavaScript.

Instead, this puzzle solution is implemented as a working example for my language. It can be run with the following command:

node run.js l_src/progruzzle-colf.lithp
\$\endgroup\$
2
\$\begingroup\$

Haskell, 111 108 bytes

v x=elem x"aeiou"
d=dropWhile
e=d v
k=d$not.v
r=reverse
f a|c<-e.k.e.k$a,""/=c=c|1<3=e.k$a
a!b=(r.f.r)a++k b

This non-regex solution turned out longer than expected. Ideone it anyway.

\$\endgroup\$
1
\$\begingroup\$

Jq 1.5, 45 bytes

gsub("([aeiou]+[^aeiou]*){1,2} [^aeiou]*";"")

Nothing special, just a port of msh210's perl solution to jq's PCRE.

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt, 18 bytes

r/\v+\V*){1,2} \V*

Try it online!

Direct port of short JS solution which is in turn the port of Jordan's Ruby solution.

How it works

Ur/\v+\V*){1,2} \V*/

Ur    Replace on the input...
/\v+\V*){1,2} \V*/  this regex with empty string.
      \v == [AEIOUaeiou], \V == [^AEIOUaeiou], `g` flag is on by default in Japt
      so the uncompressed regex is roughly /([aeiou]+[^aeiou]*){1,2} [^aeiou]*/g.
\$\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.