# Prelude:

This challenge is different from "another cat program".
There's literal tons of different twists, why can't I have my own, people?
Unique things:

• It isn't reading direct input to output.
• It is manipulating the string in a way that for sure isn't a straight-up cat.

# Challenge:

Given 3 inputs (or one input, separated however you like) get three objects (words) that we're going to substitute for pens, pineapples and apples in the lyrics and output.

## Output format (according to lyrics found on AZLyrics):

Assuming (replace values with brackets with these):

• A, B, C with input words (ex. apple)
• UA, UB, UC with input words with uppercase first letters (if not uppercase already) (ex. Apple)
• FUA, FUB, FUC with respectively first uppercase letters: (ex. A)
• a/an with article respective to first letter vowel/consonant (ex. an)
[FUA]-[FUB]-[FUC]-[FUA]

I have [a/an] [A], I have [a/an] [C].
Uh! [UC]-[UA]!

I have [a/an] [A], I have [a/an] [B].
Uh! [UB]-[UA]!

[UC]-[UA], [UB]-[UA].
Uh! [UA]-[UB]-[UC]-[UA].
[UA]-[UB]-[UC]-[UA]!

# Test case:

Test with pen, pineapple and apple:

P-P-A-P

I have a pen, I have an apple.
Uh! Apple-Pen!

I have a pen, I have a pineapple.
Uh! Pineapple-Pen!

Apple-Pen, Pineapple-Pen.
Uh! Pen-Pineapple-Apple-Pen.
Pen-Pineapple-Apple-Pen!


# Rules:

• If input doesn't start with a letter, assume consonant (a) and first uppercase the first character (ex. 123 -> 1).
• , lowest amount of characters wins!
• Lets say we input pen, pineapple and 1pple; should we assume consonant a only for the first line P-P-A-P OR the other instances of '1pple ' should be changed to 'apple' as well? Dec 17 '16 at 10:21
• @officialaimm, will edit, assume first character (in your case 1). Dec 17 '16 at 10:27
• I shouldn't have googled this. Now, it's stuck in my head -_- Dec 17 '16 at 12:43
• The a/an rule treats consonants/vowels as sounds not letters. For example, you write a user, not an user. That will be difficult to get right, unless we should ignore the "real" rule for this challenge and just look at the first letter. In that case, you should specify which letters should be considered vowels. Dec 17 '16 at 16:32
• @Dennis, gonna ignore for now. Dec 17 '16 at 16:34

## JavaScript (ES6), 217 ... 187 183 bytes

Takes input as an array of 3 strings, such as ['pen', 'pineapple', 'apple'].

a=>0-1-2-0

6, 895-3!

6, 794-3!

5-3, 4-393-4-5-3.
3-4-5-3!.replace(/\d/g,n=>[u=(w=a[n%3])[0].toUpperCase(),u+w.slice(1),I have a${~'AEIOU'.search(u)?'n':''} +w,. Uh! ][n/3|0])  ### Examples let f = a=>0-1-2-0 6, 895-3! 6, 794-3! 5-3, 4-393-4-5-3. 3-4-5-3!.replace(/\d/g,n=>[u=(w=a[n%3])[0].toUpperCase(),u+w.slice(1),I have a${~'AEIOU'.search(u)?'n':''} +w,.
Uh! ][n/3|0])

console.log(f(['pen', 'pineapple', 'apple']));
console.log(f(['golf', 'puzzle', 'code']));

• 'golf', 'puzzle', 'code' IMHO
– Neil
Dec 17 '16 at 13:00

## Perl 6, 165 bytes

{"0-3-6-0

2, 897-1!

2, 594-1!

7-1, 4-191-4-7-1.
1-4-7-1!".subst: /\d/,->$x {((.tc.comb[0],.tc,"I have a{'n' if /:i^<[aeiou]>/}$_" for $_),". Uh! ").flat[$x]},:g}


Uses the same approach as Arnauld's JS answer.

## Batch, 494 490 bytes

@echo off
set s=%1
set t=%2
set u=%3
call:u %s:~,1%- %t:~,1%- %u:~,1%- %s:~,1%
echo(
call:h %1 %3
call:u Uh! %3- %1!
echo(
call:h %1 %2
call:u Uh! %2- %1!
echo(
call:u %3- %1, %2- %1.
call:u Uh! %1- %2- %3- %1.
call:u %1- %2- %3- %1!
exit/b
:h
set s=I have a %1, I have a %2.
for %%v in (a e i o u)do call set s=%%s:a %%v=an %%v%%
echo %s%
exit/b
:u
set s= %*
for %%u in (A B C D E F G H I J K L M N O P Q R S T U V W X Y Z)do call set s=%%s: %%u= %%u%%
echo%s:- =-%


Explanation: The :h subroutine handles the line I have a %, I have a %. The %s are substituted from the appropriate command-line arguments, and then the strings a a, a e, a i, a o and a u are replace with the equivalent an version. The :u subroutine handles the other lines; it takes the parameter words, and upper cases all the first letters. (An extra space is prefixed to allow the first word to be upper cased, but it is removed on output.) To handle words after -s, extra spaces are passed, but they are also deleted on output. The :u subroutine is also used for the first line, although extracting the initials is awkward.

# Python 3.6 - 351287 286 bytes

def x(a,b,c):t=(a,b,c);p,q,r=('a'+'n'*(i[0]in'aeiouAEIOU')for i in t);A,B,C=map(str.title,t);print(f"""{A[0]}-{B[0]}-{C[0]}-{A[0]}

I have {p} {a}, I have {r} {c}.
Uh! {C}-{A}!

I have {p} {a}, I have {q} {b}.
Uh! {B}-{A}!

{C}-{A}, {B}-{A}.
Uh! {A}-{B}-{C}-{A}.
{A}-{B}-{C}-{A}!""")


There is nothing fancy here except making use of the new feature of string literal formatting.

Input:
s('golf','puzzle','code')

Output:
G-P-C-G

I have a golf, I have a code.
Uh! Code-Golf!

I have a golf, I have a puzzle.
Uh! Puzzle-Golf!

Code-Golf, Puzzle-Golf.
Uh! Golf-Puzzle-Code-Golf.
Golf-Puzzle-Code-Golf!


Note - The version is 3.6 where string literal formatting was introduced. Hence, this won't work in earlier versions.

• Not sure, but since you are already indenting in your long string, I think that you could use the actual characters \n and be able to skip the triple quotes. Dec 18 '16 at 0:41
• @nedla2004 Using '\n' will actually be longer. Skipping " will save only 2 bytes, but \n will add 12 bytes. Jan 22 '17 at 7:40

# Lua, 615 607 bytes

Saved 8 bytes thanks to [an anonymous user]

Whew, long one. Try it here.

w=io.read a,b,c=w(),w(),w()function d(u)if ("aeiouAEIOU"):find(z(u))~=nil then return "an" else return "a" end end function z(y)return y:sub(1,1):upper()end f=z(c)..c:sub(2).."-"..z(a)..a:sub(2).."-"..z(b)..b:sub(2).."-"..z(a)..a:sub(2)print(z(a).."-"..z(b).."-"..z(c).."-"..z(a).."\n\nI have "..d(a).." "..a..", I have "..d(c).." "..c..".\nUh! "..z(c)..c:sub(2).."-"..z(a)..a:sub(2).."!\n\nI have "..d(a).." "..a..", I have "..d(b).." "..b..".\nUh! "..z(b)..b:sub(2).."-"..z(a)..a:sub(2).."!\n\n"..z(c)..c:sub(2).."-"..z(a)..a:sub(2)..", "..z(b)..b:sub(2).."-"..z(a)..a:sub(2)..".\nUh! "..f..".\n"..f.."!")


I am 100% certain this can be shortened. I am just lazy..

Basically uses a lot of string manipulation. There are 3 main functions and one variable:

• d(string): returns an if string is vowel (AEIOUaeiou), else returns a
• z(string): returns the first letter in uppercase
• z(s) .. s:sub(2): returns whole word, but first letter uppercase
• f: the end word (in a variable, to save some bytes). In your test case, it would be Pen-Pineapple-Apple-Pen.

## Output:

P-P-A-P

I have a pen, I have an apple.
Uh! Apple-Pen!

I have a pen, I have a pineapple.
Uh! Pineapple-Pen!

Apple-Pen, Pineapple-Pen.
Uh! Pen-Pineapple-Apple-Pen.
Pen-Pineapple-Apple-Pen!
• To whoever the anon user was: please don't make edits to golf people's code. (just in case they come back) Dec 18 '16 at 0:33

# Python 2, 283 bytes

a=input()
r='0-1-2-0\n\n9 3, 9 5.\nUh! 8-6!\n\n9 3, 9 4.\nUh! 7-6!\n\n8-6, 7-6.\nUh! 6-7-8-6.\n6-7-8-6!'
for j in range(10):r=r.replace(str(j),([i[:1].upper()for i in a]+[['a ','an '][1+'aeiouAEIOU'.find(i[:1])/9]+i for i in a]+[i[:1].upper()+i[1:]for i in a]+['I have'])[j])
print r


Try it online!