An A , or An An?

Perl, 48 bytes

Saved 1 byte due to Ton Hospel.

#!perl -p
s;[?];A.n x$'=~/^ [aeiou]/i^$"x/[^.?!] G/;eg

Counting the shebang as one, input is taken from stdin.


#!perl -p               # for each line of input, set $_, auto-print result

s;                      # begin regex substitution, with delimiter ;
[?]                   # match [?] literally, and replace with:
A.n x$'=~/^ [aeiou]/i   # 'A', concatenate with 'n' if post-match ($')
                        #   matches space followed by a vowel
^$"x/[^.?!] G/         # if the match is preceded by /[^.?!] /, xor with a space
                        #   this will change An -> an

;eg                     # regex options eval, global

Sample Usage

$ echo Hello, this is [?] world! | perl
Hello, this is a world!

$ echo How about we build [?] big building. It will have [?] orange banana hanging out of [?] window. | perl
How about we build a big building. It will have an orange banana hanging out of a window.

$ echo [?] giant en le sky. [?] yarn ball? | perl
A giant en le sky. A yarn ball?

$ echo [?] hour ago I met [?] European. | perl
A hour ago I met an European.

Ruby, 78 72 bytes

->s{s.gsub(/(^|. )?K[?]( [aeiou])?/i){"anAn"[$1?2:0,$2?2:1]+"#$2"}}
  • Saved 6 bytes thanks to @Jordan


def f(s)
    s.gsub(/(^|. )?[?]( [aeiou])?/i) do |m|
        capitalize = $1
        vowel = $2
        replacement = if vowel then
            capitalize ? "An" : "an"
            capitalize ? "A" : "a"
        m.sub('[?]', replacement)

V, 41 bytes

ÍãÛ?Ý ¨[aeiou]©/an
Í^aü[.!?] a/A

Try it online!, which conveniently can also be used to verify all test cases with no extra byte count.

This takes advantage of V’s “Regex Compression”. It uses a lot of unprintable characters, so here is a hexdump:

0000000: cde3 db3f dd85 20a8 5b61 6569 6f75 5da9  ...?.. .[aeiou].
0000010: 2f61 6e0a cddb 3fdd 2f61 0acd 5e61 fc5b  /an...?./a..^a.[
0000020: 2e21 3f5d 2093 612f 41                   .!?] .a/A

Leave a Comment