5
\$\begingroup\$

Given a string consisting of only upper and lower case letters, output an if it begins with a vowel, and a if not. For the purposes of this challenge, we'll ignore normal grammar rules, and use a very basic rule instead: if the input begins with a vowel (any of AEIOUaeiou), then output an. Otherwise, output a.

Your program should be case insensitive (computer and CoMpUtER are the same). This is , so the shortest code in bytes wins

Test cases

airplane: an
water: a
snake: a
hybrid: a
igloo: an
WATER: a
IglOO: an
HoUr: a
unIverSe: an
youTH: a

Note that for the last 3, they contradict typical grammar rules, in favour of our simplified rule, and that y is not counted as a vowel

\$\endgroup\$
5
  • 9
    \$\begingroup\$ An hour in the Sandbox is far too short. You should wait, as a minimum, 3 days so that plenty of users can see it and offer feedback. I'd suggest adding hour, universe and youth as test cases \$\endgroup\$ Sep 15 at 17:19
  • 1
    \$\begingroup\$ This post came up in the review queues as it has a couple of close votes (closing as "unclear/needs details"). Because of this, I've done some edits to try to clarify the challenge. Feel free to revert anything you dislike/I've gotten wrong \$\endgroup\$ Sep 15 at 17:38
  • 1
    \$\begingroup\$ Can we take input as an array of characters? \$\endgroup\$
    – Shaggy
    Sep 15 at 18:28
  • 1
    \$\begingroup\$ @Shaggy Yes, you can. \$\endgroup\$
    – Alan Bagel
    Sep 15 at 18:32
  • 1
    \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$
    – hyper-neutrino
    Sep 17 at 18:19

28 Answers 28

12
\$\begingroup\$

C (gcc), 44 bytes

f(int*s){printf("a%.*s",2130466>>*s&1,"n");}

Try it online!

Commented

f(int *s) {     // *s = input string
  printf(       // print ...
    "a%.*s",    //   the letter 'a' followed by a string with
                //   a dynamic length
    2130466     //   using the bitmask of vowels:
                //     1000001000001000100010
                //     ^     ^     ^   ^   ^
                //     utsrqponmlkjihgfedcba_
    >> *s & 1,  //   output 1 character if the first character
                //   is a vowel, or zero otherwise
                //   (assumes that the shift is modulo 32,
                //   which is guaranteed on Intel and may be
                //   true on ARM as well)
    "n"         //   where the string to be printed is "n"
  );            //
}               //

C (clang), 39 bytes

This version was suggested by Johan du Toit.

f(*s){write(1,"an",(2130466>>*s&1)+1);}

Try it online!


C (clang), 36 bytes

This one was suggested by dingledooper.

f(*s){puts(2130466>>*s&1?"an":"a");}

Try it online!

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

Factor + english, 15 bytes

[ >lower a/an ]

Almost a builtin. For whatever reason, a/an doesn't handle capital letters properly so we need to make it lowercase first. Luckily it's simplistic enough that it doesn't return the correct article for 'universe.'

Doesn't work on TIO because the english vocabulary postdates build 1525 (the one TIO uses), so have a picture:

enter image description here

\$\endgroup\$
3
  • 3
    \$\begingroup\$ Interesting that it goes off of the first letter, rather than attempting to mimic the actual grammatical rules about when to use a vs an \$\endgroup\$ Sep 15 at 20:49
  • \$\begingroup\$ Typo here: captial. \$\endgroup\$
    – A.L
    Sep 17 at 9:13
  • 1
    \$\begingroup\$ @A.L Fixed, thanks. \$\endgroup\$
    – chunes
    Sep 17 at 19:36
4
\$\begingroup\$

Japt v2.0a0 -mg, 9 8 bytes

Takes input as an array of characters.

è\v îÍia

Try it

è\v çÍia     :Implicit map of each element in input array
è            :Count the occurrences of
 \v          :  RegEx /[aeiou]/gi
    ç        :Repeat that many times
     Í       :  "n"
      ia     :Prepend "a"
             :Implicit output of first element

The Í is Japt's shortcut for n2<space> (Mainly intended for converting binary strings to decimal) The space close the ç method and the n and the 2 are passed to it as individual arguments but as ç only expects one argument the 2 is ignored.

\$\endgroup\$
3
  • 2
    \$\begingroup\$ ...but this doesn't even have an n in it??? \$\endgroup\$ Sep 15 at 18:51
  • \$\begingroup\$ Japt magic, @cairdcoinheringaahing ;) The Í is the shortcut for n2, which gets passed to the î as 2 arguments, which only expects 1 argument. I'll add a full explanation in the morn'. \$\endgroup\$
    – Shaggy
    Sep 15 at 19:13
  • \$\begingroup\$ @cairdcoinheringaahing, explanation added \$\endgroup\$
    – Shaggy
    Sep 16 at 9:02
4
\$\begingroup\$

Python 3, 37 bytes

lambda x:'a'+'n'*(x[0]in'aeiouAEIOU')

Try it online!

-1 thanks to @xnor

\$\endgroup\$
2
  • 4
    \$\begingroup\$ 1 shorter to just do lambda x:'a'+'n'*(x[0]in'aeiouAEIOU'). \$\endgroup\$
    – xnor
    Sep 15 at 21:55
  • \$\begingroup\$ @xnor nice! Sometimes i miss the obvious things 😅😅 \$\endgroup\$
    – wasif
    Sep 16 at 16:47
3
\$\begingroup\$

JavaScript, 32 31 bytes

-1 thanks to @Arnauld

s=>/^[aeiou]/i.test(s)?"an":"a"

Try it online!

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

jq, 36 bytes

1?*(test("^[aeiou]";"i")//"a")//"an"

Try it online!

Some longer alternatives:

"an"[:match("^[aeiou]?";"i").length+1]

Try it online!

.[:1]|1?*(inside("aeiouAEIOU")//"a")//"an"

Try it online!

"a"+sub("^([^aeiou](?<x>))?.*";.x//"n";"i")

Try it online!

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

Vyxal r, 11 9 bytes

hk∨c›‛anẎ

Try it Online!

hk∨c›‛anẎ
h          - First character of input
 k∨       - All vowels ("aeiouAEIOU")
    c      - A in B? ("h" in "k∨"?)
     ›     - Increment
      `an  - Two-byte string literal "an"
         Ẏ - Slice until B (A[0:B])

9 bytes thanks to @Aaron Miller

\$\endgroup\$
2
  • \$\begingroup\$ Nice one! I messed with some flags and was able to get it down to a pretty jank 10 bytes \$\endgroup\$ Sep 15 at 19:32
  • \$\begingroup\$ Make that 9 bytes \$\endgroup\$ Sep 15 at 19:39
3
\$\begingroup\$

Dyalog APL, 21 chars

'an'↑⍨1+'aeiou'∊⍨⊃∘⎕c

Same logic as this Jelly answer. This answer feels too long...

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

PowerShell Core, 33 bytes

"a"+"n"*("$args"-match"^[AEIOU]")

Try it online!

Or 36 bytes without regex

"a"+"n"*($args[0]-in("AEIOU"|% t*y))

Try it online!

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

PHP, 36 34 bytes

fn($s)=>stripos(_aeiou,$s[0])?an:a

Try it online!

Straightforward PHP code. Ignoring accented vowels of course, the _ is ignored, it is only there so that the index in the string is truthy

EDIT: saved 2 bytes thanks to YetiCGN's suggestions

\$\endgroup\$
8
  • \$\begingroup\$ Why strripos and not stripos for -1 byte? With a single character match you need not care about using the first or last occurence of the needle. Also, à is two bytes in UTF-8 for one character, you could substitute it for _ to save 2 bytes. \$\endgroup\$
    – YetiCGN
    Sep 16 at 12:18
  • \$\begingroup\$ @YetiCGN You're right, maybe it comes from my stuttering :D \$\endgroup\$
    – Kaddath
    Sep 16 at 12:32
  • \$\begingroup\$ strrrrrrripos!!! ;-) \$\endgroup\$
    – YetiCGN
    Sep 16 at 12:35
  • 1
    \$\begingroup\$ 33 bytes as a standalone program! \$\endgroup\$
    – 640KB
    Sep 16 at 21:01
  • 1
    \$\begingroup\$ or also 33 bytes doing it another crazy way! \$\endgroup\$
    – 640KB
    Sep 16 at 21:03
2
\$\begingroup\$

Zsh, 29 bytes

grep -qi ^[aeiou]&&s=n
<<<a$s

Attempt This Online!

Zsh, 29 bytes

>${1:l}
<[aeiou]*&&s=n
<<<a$s

Attempt This Online!

If it weren't for a strange behaviour that I suspect is a bug in Zsh, we could have:

Zsh, 27 bytes

>${1:l}
s=n<[aeiou]*
<<<a$s

Attempt This Online!

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

TI-Basic, 43 bytes

Input Str1
"a
If inString("AEIOUaeiou",sub(Str1,1,1
"an

Ouput is stored in Ans.

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

R, 47 bytes

function(s)"if"(grepl("^[aeiou]",s,T),"an","a")

Try it online!

Other solutions:

function(s)c("a","an")[1+grepl("^[aeiou]",s,T)]   # 47 bytes
function(s)paste0("a","n"[grepl("^[aeiou]",s,T)]) # 49 bytes
\$\endgroup\$
2
\$\begingroup\$

JavaScript, 91 73 bytes

-18 from @emanresuA

a=(s)=>{return 'a'+('AEIOU'.includes(s.charAt(0).toUpperCase())?"n":"");}

Explanation

a=                        declares variable
(s)=>{                    ES6 Arrow Function
return 'a'+               return statement
('AEIOU'.includes(        check if in string 'AEIOU'
s.charAt(0)               first letter of string
.toUpperCase())           case insensitivity
?                         ternary operator
"n"                       if true, add 'n'  (an)
:"");                     else, add nothing (a)
}                         finish function

Try it Online!

Old TIO link

first time here so let me know if I missed something

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Welcome to Code Golf, and nice first answer! A couple of golfing tips: - Strings have a includes method, so you can go 'AEIOU'.includes(; s doesn't need to be in parentheses, and you don't need the let at the start. \$\endgroup\$
    – emanresu A
    Sep 18 at 1:15
  • \$\begingroup\$ @emanresuA so we don't have to do it in 'strict mode' ('use strict';) \$\endgroup\$ Sep 18 at 1:17
  • 1
    \$\begingroup\$ No, you don't. See our Tips for golfing in Javascript page for more tips to make your code shorter. \$\endgroup\$
    – emanresu A
    Sep 18 at 1:39
1
\$\begingroup\$

Jelly, 9 bytes

ḢeØc‘⁾anḣ

Try it online!

The footer simply extracts the test case from the : separated string

How it works

ḢeØc‘⁾anḣ - Main link. Takes a string S on the left
Ḣ          - Extract the first character of S
  Øc       - Yield vowels; "AEIOUaeiou"
 e         - Is the first character in that string? Yield 1 if so, else 0
    ‘      - Increment, yielding 2 for vowel-starting strings, 1 otherwise
      ⁾anḣ - Take that many characters of the string ⁾an
\$\endgroup\$
0
1
\$\begingroup\$

Perl 5 + -pl, 19 bytes

$_=a.n x/^[aeiou]/i

Try it online!


Perl 5 + -lpF/^([aeiou]).*$/i, 11 bytes

Using -F and the resulting $#F can save a bunch of bytes.

$_=a.n x$#F

Try it online!

\$\endgroup\$
6
  • \$\begingroup\$ Do the standard golfing rules allow treating code as a flag? You should be adding the flags to your score anyway. \$\endgroup\$
    – CJ Dennis
    Sep 16 at 1:34
  • \$\begingroup\$ @CJDennis codegolf.meta.stackexchange.com/a/14339/92901 \$\endgroup\$
    – Dingus
    Sep 16 at 5:57
  • 1
    \$\begingroup\$ To be honest, I do enjoy exploring what useful flags you can use on Perl answers, but I am aware that this one is particularly cheeky. It's entirely possible to have the whole program be passed in via -F but does go against the spirit. When using Perl to parse files, -F is a standard feature I use a lot so I like to share what can be done, though it does often get me negative attention. \$\endgroup\$ Sep 17 at 6:54
  • 1
    \$\begingroup\$ I think this is extra contentious now with one of the golfing langs having some flags that help it a lot, so it might garner more negative attention than these ones do. I have however considered it too, like, another Perl flag that would wrap the code in for(/./g){...;;print}, or similar. I don't think anything is stopping you from doing that, technically. But it might not earn points... It's a valid discussion though for sure. I guess the process is open a meta discussion if you think it needs clarification. \$\endgroup\$ Sep 17 at 6:58
  • 1
    \$\begingroup\$ @CJDennis What you describe has actually been done before. My interpretation is that the point about ‘cheating flags’ covers this kind of approach: yes you can do it, but it probably won’t win you any favour. All 0-byte answers in the ‘flag language’ are equivalent so there’s no possible competition. \$\endgroup\$
    – Dingus
    Sep 17 at 7:04
1
\$\begingroup\$

Ly, 35 bytes

"aeiou">ir'aL' *+s<l~s<'al['nf!]p&o

Try it online!

Takes advantage of the constraints on the input, meaning we can assume it's only upper or lower case letters....

"aeiou"                             - Push codepoints for the vowels on the stack
       >i                           - Switch to clean stack, read input
         r                          - Reverse stack (first char/codepoint to top)
          'aL                       - Is it uppercase?
             ' *                    - Push "32" and multiple w/ test results
                +                   - Add to the codepoint (maps it to lowercase)
                 s<                 - Save the resulting codepoint, switch stacks
                   l~               - Load the char/codepoint, search on stack
                     s<             - Save boolean result, switch to clean stack
                       'a           - Push "a" on the stack
                         l[  f!]p   - if/then "true" if a vowel
                           'n       - Push "n" on the stack
                                 &o - Print the stack
\$\endgroup\$
1
\$\begingroup\$

Nim, 61 bytes

proc a(i:string):string=
 if i[0]in "aeiouAEIOU":"an"else:"a"

Try it online!

Simple explanation + ungolfed code:

# Define function
proc a(i: string): string =
 # If the first character of 'i' is in "aeiouAEIOU",
 # Then it is a "an"
 if i[0] in "aeiouAEIOU":
  return "an"
 # Else, return "a"
 else:
  return "a"
\$\endgroup\$
1
\$\begingroup\$

Java (JDK), 39 bytes

s->s.matches("(?i)^[aeiou].*")?"an":"a"

Try it online!

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

05AB1E, 12 11 bytes

„anžMIнlå>∍

Try it online or verify all test cases.

Explanation:

„an          # Push "an"
   žM        # Push builtin constant "aeiou"
     I       # Push the input-string
      н      # Pop and leave just its first character
       l     # Convert it to lowercase
        å    # Check if this lowercase first letter is in the vowels-string
         >   # Increase it by 1
          ∍  # Shorten the "an" to this length
             # (after which the result is output implicitly)
\$\endgroup\$
1
\$\begingroup\$

Kotlin, 39 bytes

{if(it[0]in "AEIOUaeiou")"an" else "a"}

Try it online!

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

Perl 5 -p, 28 20 bytes

27 bytes for the actual code; +1 byte for -E to get say

-8 bytes by golfing further

$_=/^[aeiou]/i?an:a

Try it online!

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

Haskell, 80 76 74 64 40 35 bytes

-24 thanks to @Franky
-5 thanks to @ovs

a(x:_)='a':['n'|elem x"aeiouAEIOU"]

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Data.Char.toLower has 17 bytes minimum. Expanding "aeiou" to "aeiouAEIOU" just costs 5 bytes. Using that and guards instead of if gets me down to 39 bytes \$\endgroup\$
    – Franky
    Sep 17 at 8:06
  • \$\begingroup\$ pattern matching (a(x:_)|elem x"...) and 1>0 instead of True both save a byte. Using a list comprehension to conditionally append a n saves a few more bytes: TIO \$\endgroup\$
    – ovs
    Sep 17 at 13:40
1
\$\begingroup\$

F#, 61 bytes

let a(i:string)=if"aeiouAEIOU".Contains(i.[0])then"an"else"a"

Try it online!

Alternative 66 bytes solution:

let a(i:string)=if"aeiouAEIOU".Contains(i.Chars(0))then"an"else"a"

Try it online!

Check if the input's first character is in aeiouAEIOU or not (if"aeiouAEIOU".Contains(i.Chars(0))), if true, return "an" (then"an"), else, return "a" (else"a")

Ungolfed version:

let anOrA (inpt : string) =
 if "aeiouAEIOU".Contains(inpt.Chars(0)) then "an" else "a"
\$\endgroup\$
1
\$\begingroup\$

Vim, 20 bytes

lD:s/[aeiou]\c/an
ra

Try it online!

Explanation:

lD                 # Keep only the first character
  :s/[aeiou]\c/an  # Replace any of AEIOUaeiou with 'an'
ra                 # Replace the first character with 'a'
\$\endgroup\$
1
\$\begingroup\$

C (clang), 34 bytes

f(*s){puts("a\00an"+('A\04D'>>*s&2));}

Try it online!

Partial based on dingledooper's answer.

\00 and \04 should be replaced by raw bytes instead of using escaped character sequences.

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

JavaScript (ES6), 37 bytes

s=>'a'+(/[aeiou]/i.test(s[0])?"n":"")
\$\endgroup\$
1
\$\begingroup\$

Python, 42 37 bytes

lambda s:'a'+'n'*(2130466>>s[0]%32&1)

Uses the same logic as this C answer, but I have to take %32 because python bit shifts aren't modulo 32.

Note that I take advantage of order of operations by using %32 and &1 (which is %2) to avoid needing parentheses.

(-5): Removed the ord() by taking a bytestring (bytes) instead of a str.

\$\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.