13
\$\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\$
11
  • 13
    \$\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\$ Commented Sep 15, 2021 at 17:19
  • 2
    \$\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\$ Commented Sep 15, 2021 at 17:38
  • 1
    \$\begingroup\$ Can we take input as an array of characters? \$\endgroup\$
    – Shaggy
    Commented Sep 15, 2021 at 18:28
  • 1
    \$\begingroup\$ @Shaggy Yes, you can. \$\endgroup\$ Commented Sep 15, 2021 at 18:32
  • 1
    \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$
    – hyperneutrino
    Commented Sep 17, 2021 at 18:19

52 Answers 52

13
\$\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
8
\$\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
  • 4
    \$\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\$ Commented Sep 15, 2021 at 20:49
  • \$\begingroup\$ Typo here: captial. \$\endgroup\$
    – A.L
    Commented Sep 17, 2021 at 9:13
  • 1
    \$\begingroup\$ @A.L Fixed, thanks. \$\endgroup\$
    – chunes
    Commented Sep 17, 2021 at 19:36
6
\$\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
  • 4
    \$\begingroup\$ ...but this doesn't even have an n in it??? \$\endgroup\$ Commented Sep 15, 2021 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
    Commented Sep 15, 2021 at 19:13
  • \$\begingroup\$ @cairdcoinheringaahing, explanation added \$\endgroup\$
    – Shaggy
    Commented Sep 16, 2021 at 9:02
6
\$\begingroup\$

Python 3, 37 bytes

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

Try it online!

-1 thanks to @xnor

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

JavaScript, 32 31 bytes

-1 thanks to @Arnauld

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

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ 31 bytes \$\endgroup\$
    – Arnauld
    Commented Sep 15, 2021 at 17:48
4
\$\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\$
4
\$\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\$ Commented Sep 15, 2021 at 19:32
  • \$\begingroup\$ Make that 9 bytes \$\endgroup\$ Commented Sep 15, 2021 at 19:39
4
\$\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
    Commented Sep 16, 2021 at 12:18
  • \$\begingroup\$ @YetiCGN You're right, maybe it comes from my stuttering :D \$\endgroup\$
    – Kaddath
    Commented Sep 16, 2021 at 12:32
  • \$\begingroup\$ strrrrrrripos!!! ;-) \$\endgroup\$
    – YetiCGN
    Commented Sep 16, 2021 at 12:35
  • 1
    \$\begingroup\$ 33 bytes as a standalone program! \$\endgroup\$
    – 640KB
    Commented Sep 16, 2021 at 21:01
  • 1
    \$\begingroup\$ or also 33 bytes doing it another crazy way! \$\endgroup\$
    – 640KB
    Commented Sep 16, 2021 at 21:03
3
\$\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\$
3
\$\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\$
4
  • 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
    Commented Sep 18, 2021 at 1:15
  • \$\begingroup\$ @emanresuA so we don't have to do it in 'strict mode' ('use strict';) \$\endgroup\$ Commented Sep 18, 2021 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
    Commented Sep 18, 2021 at 1:39
  • \$\begingroup\$ a=(s)=>{return 'a'+('AEIOUaeiou'.includes(s.charAt(0))?"n":"");} is shorter. \$\endgroup\$ Commented May 3 at 16:08
3
\$\begingroup\$

Scratch, 69 bytes

Run it here

(The executing script does not need to be counted. Look inside and find the custom block for the code)

define(x
say(join[a](letter<[aeiouAEIOU]contains(letter(1)of(x))>of[n

code

\$\endgroup\$
2
\$\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
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\$

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\$
2
\$\begingroup\$

Java (JDK), 39 bytes

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

Try it online!

\$\endgroup\$
2
\$\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\$
2
\$\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
    Commented Sep 17, 2021 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
    Commented Sep 17, 2021 at 13:40
2
\$\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\$
2
\$\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\$
2
\$\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\$
2
\$\begingroup\$

JavaScript (ES6), 37 bytes

s=>'a'+(/[aeiou]/i.test(s[0])?"n":"")
\$\endgroup\$
2
\$\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\$
2
\$\begingroup\$

jq, 33 bytes

(match("^[aeiou]";"i")|"an")//"a"

Try it online!

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

Zsh --continue-on-error, 25 bytes

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

Attempt This Online!

When [aeiou]* fails to match (i.e., the word begins with a consonant), Zsh would normally exit with a "fatal" error. The aptly named option CONTINUE_ON_ERROR overrides this, and simply skips the assignment line s=n instead.

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

International Phonetic Esoteric Language, 40 bytes

0h"aeiouAEIOU"dʔdpʌɔ|a|"an"ɔ|e||a|"a"|e|

Expects a string, leaves the string and a "a" or "an".

Ungolfed:

               (s -- a/an)
0h             (first char)
"aeiouAEIOU"dʔ (is c a vowel?)
dp             (discard vowels)
ʌɔ|a|          (if c is not a vowel, go to |a|)
|an|"an"ɔ|end| (when c is a vowel)
|a|"a"         (when c is not a vowel)
|end|
\$\endgroup\$
2
\$\begingroup\$

GAIA, 32 bytes

{(⟨₵v&!!⟩⟨₵V&!!⟩v}⟨“a”p⟩⟨“an”p⟩?

Try it online!

Probably could be shortened, especially on the second section.

Explanation:

( -takes first letter of the input

₵v& - is member (&) of string aeiou (₵v) -> returns the contained letter if member, empty if not.

₵V& - is member (&) of string AEIOU (₵V) -> returns the contained letter if member, empty if not.

!! - if the passed value is empty returns 0, otherwise 1

v - is logical or

{(⟨₵v&!!⟩⟨₵V&!!⟩v} - so this checks if the first letter is member of either lower or upper case vowels

⟨“a”p⟩⟨“an”p⟩? - this checks for the value passed by the first section, if true executes the first member, if false the second.

p -prints a string
\$\endgroup\$
2
\$\begingroup\$

K (ngn/k), 21 bytes

Solution:

{$`an`a@^"aeiou"?*_x}

Try it online!

Explanation:

{                   } / function taking implicit x argument
                  _x  / convert x to lowercase
                 *    / take first
         "aeiou"?     / find right in left
        ^             / null?
  `an`a@              / index into 2-item list (`a;`an)
 $                    / convert to string
\$\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.