16
\$\begingroup\$

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!
\$\endgroup\$
6
  • 1
    \$\begingroup\$ 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? \$\endgroup\$
    – 0xffcourse
    Commented Dec 17, 2016 at 10:21
  • \$\begingroup\$ @officialaimm, will edit, assume first character (in your case 1). \$\endgroup\$ Commented Dec 17, 2016 at 10:27
  • 13
    \$\begingroup\$ I shouldn't have googled this. Now, it's stuck in my head -_- \$\endgroup\$ Commented Dec 17, 2016 at 12:43
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Dennis
    Commented Dec 17, 2016 at 16:32
  • \$\begingroup\$ @Dennis, gonna ignore for now. \$\endgroup\$ Commented Dec 17, 2016 at 16:34

7 Answers 7

10
\$\begingroup\$

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']));

\$\endgroup\$
1
  • 3
    \$\begingroup\$ 'golf', 'puzzle', 'code' IMHO \$\endgroup\$
    – Neil
    Commented Dec 17, 2016 at 13:00
4
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

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.

\$\endgroup\$
3
\$\begingroup\$

Python 3.6 - 351 287 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.

\$\endgroup\$
2
  • \$\begingroup\$ 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. \$\endgroup\$
    – nedla2004
    Commented Dec 18, 2016 at 0:41
  • \$\begingroup\$ @nedla2004 Using '\n' will actually be longer. Skipping " will save only 2 bytes, but \n will add 12 bytes. \$\endgroup\$ Commented Jan 22, 2017 at 7:40
1
\$\begingroup\$

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.

Input: pen, pineapple, apple

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!
\$\endgroup\$
1
  • 1
    \$\begingroup\$ To whoever the anon user was: please don't make edits to golf people's code. (just in case they come back) \$\endgroup\$
    – Riker
    Commented Dec 18, 2016 at 0:33
1
\$\begingroup\$

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!

\$\endgroup\$
0
\$\begingroup\$

TypeScript's Type System, 348 bytes

//@ts-nocheck
type P<S>=Capitalize<S>
type U<S>=P<S extends`${infer A}${any}`?A:S>
type N<S>=`I have a${U<S>extends"A"|"E"|"I"|"O"|"U"?"n":""} ${S}`
type F<A,B,C,D=P<A>,E=P<B>,F=P<C>,G=`${D}-${E}-${F}-${D}`>=`${U<A>}-${U<B>}-${U<C>}-${U<A>}

${N<A>}, ${N<C>}.
Uh! ${F}-${D}!

${N<A>}, ${N<B>}.
Uh! ${E}-${D}!

${F}-${D}, ${E}-${D}.
Uh! ${G}.
${G}!`

Try it at the TypeScript playground!

Composes helper types to avoid repeating as much code as possible, then uses them in a type F<A,B,C>.

Explanation:

type P<S>=Capitalize<S>   // alias the built-in to uppercase the first 
                          // letter of a string type, since it is 
                          // used a lot.

type U<S>=.               // to get the initial of the string, we
  P<S extends             // capitalize the result of matching against
    `${infer A}${any}`    // a string-type to match the first letter
      ?A                  // select that letter to capitalize
      :S>                 // unless the match failed somehow.

type N<S>=                // to get the "I have [a/an] [S]" bit, we
  `I have a${             // take "I have a" and
    U<S>extends           // check if the initial of the word matches
      "A"|"E"|"I"|"O"|"U" // an uppercase vowel
        ?"n":""           // if it does, insert "n", otherwise ""
  } ${S}`                 // finally, we append a space and the word.

type F<A,B,C,             // take the three words A, B, and C
  D=P<A>,E=P<B>,F=P<C>,   // assign D, E, F to A, B, C capitalized
  G=`${D}-${E}-${F}-${D}` // assign G to the "Pen-Pineapple-Apple-Pen"
>=
`${U<A>}-${U<B>}-${U<C>}-${U<D> /* the P-P-A-P bit */}

${N<A>}, ${N<C> /* I have a pen, I have an apple */}.
Uh! ${F}-${D /* Apple-Pen */}!

${N<A>}, ${N<B> /* I have a pen, I have a pineapple. */}.
Uh! ${E}-${D /* Pineapple-Pen */}!

${F}-${D /* Apple-Pen */}, ${E}-${D /* Pineapple-Pen */}.
Uh! ${G /* Pen-Pineapple-Apple-Pen */}.
${G /* Pen-Pineapple-Apple-Pen */}!`
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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