77
\$\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\$
10
  • 66
    \$\begingroup\$ New test case? donald trump. \$\endgroup\$ Sep 26, 2016 at 7:45
  • 5
    \$\begingroup\$ These are essentially portmanteaus. \$\endgroup\$
    – mbomb007
    Sep 26, 2016 at 14:48
  • 3
    \$\begingroup\$ Related \$\endgroup\$ Sep 27, 2016 at 2:07
  • 1
    \$\begingroup\$ @ETHproductions this seems to produce much different combinations, such as Django + Angular = Djular \$\endgroup\$ Sep 27, 2016 at 13:00
  • \$\begingroup\$ What's "n-1th vowel group position" \$\endgroup\$
    – l4m2
    May 23, 2018 at 23:18

15 Answers 15

23
\$\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\$
10
  • \$\begingroup\$ Nice regex! Mind if I use part of it in my JS answer? \$\endgroup\$ Sep 26, 2016 at 3:06
  • \$\begingroup\$ Sure, go crazy. \$\endgroup\$
    – Jordan
    Sep 26, 2016 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, 2016 at 17:28
  • 5
    \$\begingroup\$ Crossed out 44 is still regular 44 ;( \$\endgroup\$
    – Celeo
    Sep 26, 2016 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, 2016 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
  • 1
    \$\begingroup\$ I always upvote happy code \$\endgroup\$ Oct 14, 2016 at 15:00
11
\$\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\$
4
  • \$\begingroup\$ Maybe could just throw out the match bit and use a replace? \$\endgroup\$ Sep 26, 2016 at 3:13
  • \$\begingroup\$ @ConorO'Brien That kinda feels like stealing Jordan's answer :/ \$\endgroup\$ Sep 26, 2016 at 3:14
  • \$\begingroup\$ You quite literally read my mind. And yeah, that's true \$\endgroup\$ Sep 26, 2016 at 3:14
  • 1
    \$\begingroup\$ Currying (a,b)=> to a=>b=> saves 1 byte. \$\endgroup\$ Sep 26, 2016 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\$
1
  • \$\begingroup\$ Beautifully explained! \$\endgroup\$ Sep 27, 2016 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\$
6
  • 1
    \$\begingroup\$ Any plans to add vowel and non-vowel classes? ;-) \$\endgroup\$ Sep 26, 2016 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\$ Sep 26, 2016 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\$ Sep 27, 2016 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\$ Sep 27, 2016 at 14:55
  • 1
    \$\begingroup\$ Time to drop the .net specific behavior and rewrite everything in Ruby? Ruby is better anyways :-) \$\endgroup\$ Sep 27, 2016 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\$
2
  • \$\begingroup\$ Would d[aeiou]+[^aeiou]*[aeiou]*[^aeiou]* [^aeiou]* be any shorter? \$\endgroup\$ Sep 27, 2016 at 2:06
  • \$\begingroup\$ @ETHproductions I tried that, it was the same byte count :( \$\endgroup\$ Sep 27, 2016 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\$
4
  • 1
    \$\begingroup\$ You can use + instead of {1,2}. \$\endgroup\$
    – Titus
    Sep 26, 2016 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\$ Sep 26, 2016 at 17:18
  • \$\begingroup\$ Use $v=aeiou; to save 3 more. \$\endgroup\$
    – Titus
    Sep 26, 2016 at 17:33
  • \$\begingroup\$ @Titus I had the same idea but with a little variant. Thank You \$\endgroup\$ Sep 26, 2016 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\$
1
  • \$\begingroup\$ Same as the sed answer linked to within, but we may as well have it in Perl also. \$\endgroup\$
    – msh210
    Sep 26, 2016 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 and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.