# Now I know my ABCs, won't you come and golf with me?

Write a program or function that outputs this exact text, case-insensitive:

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.


(Based on the alphabet song that many American kids learn to help memorize the alphabet, though edited for more compressibility.)

The output must look exactly the same as the above (again, case-insensitive), but may contain trailing spaces on each line and/or trailing newlines. Notice the period at the end.

This is code-golf, so the shortest code in bytes wins.

• For regex based languages consider a 0 width lookahead... /(?=[HQTW])/ – Magic Octopus Urn Sep 30 '16 at 18:24
• I thought it was H, I, J, K, LMNO, P? – David says Reinstate Monica Sep 30 '16 at 21:00
• Shouldn't the last line end with "Y and Z."? – KM. Oct 2 '16 at 12:36
• @KM. This was discussed in the sandbox, and we decided to stick with this version to make the challenge less complicated. – ETHproductions Oct 2 '16 at 18:26
• Golf seems boring. Cricket is better. – m4n0 Oct 3 '16 at 19:49

# Vim, 42, 40 keystrokes/bytes

:h<_<cr>jjYZZP:s/./&, /g<cr>7f r<cr>9;.3;.3;.$ch.  Thanks to Lynn and her awesome vim answer for the tip to grab the alphabet from help. Thanks to RomanGräf for saving two bytes! Explanation: :h<_<cr> " Open up vim-help jj " Move down two lines Y " Yank this line (containing the alphabet) ZZ " Close this buffer P " Paste the line we just yanked :s/./&, /g<cr> " Replace every character with that character followed by a comma and a space 7f " Find the seven space on this line r<cr> " And replace it with a newline 9; " Repeat the last search (space) 9 times . " Repeat the last edit (replace with a newline) 3; " Third space . " Replace with newline 3; " Third space . " Replace with newline  Then, we move the end of the of the line with $, change back a character with ch and insert a dot.

• You mustn't convert to uppercase. The OP said " this exact text, case-insensitive". – Roman Gräf Sep 30 '16 at 20:25
• @RomanGräf Thanks for the tip! – James Sep 30 '16 at 20:26
• Ha! Getting the alphabet from vim help is genius! Did you know that or did you look it up for this challenge? – Christian Rondeau Sep 30 '16 at 22:54
• @christianRondeau I did not come up with it. Lynn did in this answer – James Oct 1 '16 at 1:52
• @RomanGräf +1 for using mustn't – FantaC Nov 27 '17 at 20:40

# 05AB1E, 16 bytes

Code

A',â79334S£»¨'.J


Explanation:

A                  # Push the alphabet.
',â               # Cartesian product with ','.
79334S         # Push [7, 9, 3, 3, 4].
£        # Contigious substring, pushes the substrings [0:7], [7:7+9],
[7+9:7+9+3], [7+9+3:7+9+3+3], [7+9+3+3:7+9+3+3+4].
»       # Gridify, join the inner arrays with spaces and join those arrays
with newlines.
¨      # Remove the last character.
'.J   # Append a '.'-character.


Uses the CP-1252 encoding. Try it online!

# JavaScript (ES6), 66 65 bytes

Beating @Neil was impossible... That's why I did it. :-)

f=(i=10)=>i>34?"z.":i.toString(++i)+","+
[9568512>>i-9&1]+f(i)


Golfed 1 byte thanks to a trick from @LevelRiverSt. Using String.fromCharCode is 7 bytes longer:

f=(i=65)=>i>89?"Z.":String.fromCharCode(i,44,i%86%83%80%71?32:10)+f(i+1)


### How it works

This recursively generates each character of the alphabet from a to y, using .toString(). A comma is appended after each letter, plus a newline if 9568512>>i-9&1 is 1, or a space otherwise. When the recursion gets past 34, i.e. to z, the function simply returns "z.".

• Wait what how does this even— explanation pls? :3 – Downgoat Sep 30 '16 at 23:09

# Bash + GNU utilities, 36

• 5 bytes saved thanks to Neil.
echo {A..Y}, Z.|sed 's/[HQTW]/\n&/g'


Ideone.

• Why not just echo {A..Y}, Z.|sed 's/[HQTW]/\n&/g' ? – Neil Sep 30 '16 at 19:05
• @Neil Ooh very good! thanks! – Digital Trauma Sep 30 '16 at 19:54

# Python 2.7, 67 66 63 bytes

a=65;exec"print'%c'%a+',.'[a>89]+'\\n'[a%42%39%9^2:],;a+=1;"*26


Dennis saved a byte.

• Using exec instead of for should save a byte. – Dennis Sep 30 '16 at 20:21

# Jelly, 19 18 bytes

ØAp”,ṁ79334DR¤GṖ”.


Thanks to @Adnan for golfing off 1 byte!

Try it online!

### How it works

ØAp”,ṁ79334DR¤GṖ”.  Main link. No arguments.

ØA                  Yield "ABCDEFGHIJKLMNOPQRSTUVWXYZ".
p”,               Cartesian product with ','; append a comma to each letter.
¤      Combine the two links to the left into a niladic chain.
79334D          Decimal; yield [7, 9, 3, 3, 4].
R         Range; yield [[1, 2, 3, 4, 5, 6, 7], ..., [1, 2, 3, 4]].
ṁ              Mold; reshape the array of letters with commata like the
generated 2D array.
G     Grid; separate rows by spaces, columns by linefeeds.
Ṗ    Pop; discard the last comma.
”.  Print the previous result and set the return value to '.'.
(implicit) Print the return value.

• 31 seconds? Dang... – ETHproductions Sep 30 '16 at 17:52

## JavaScript (ES6), 80 74 bytes

_=>[...ABCDEFGHIJKLMNOPQRSTUVWXYZ].join, .replace(/[HQTW]/g,
$&)+.  Probably possible to shorten this with atob/btoa if you can work out how to use ISO-8859-1 encoding. Edit: Saved 6 bytes thanks to @RickHitchcock. • @RickHitchcock Yes, I just realised that myself after reading the PHP answer. – Neil Sep 30 '16 at 19:09 • @RickHitchcock You wanted .join, ? Put backslashes before the backticks. (Yes, comment markdown is different, sigh...) – Neil Sep 30 '16 at 19:10 ## Pyke, 2319 17 bytes G\,J\.+2cu /P  Try it here! G\,J\.+ - ",".join(alphabet)+"." 2c - split(^, size=2) / - split_sized(^, V) u - yield list [7,9,3,3] (actual bytes u%04%07%09%03%03) P - print(^)  ## Brainfuck, 117 bytes +[++[-<]-[->->]<]+++[->++>+++>+>+<<<<<--<<->>>]>+[[-<<<<<+.>-.+>.>>>]>[[-<+>]>]<<[<]<.>>]<<-[---<<<+.>-.+>.>]<<<+.>+.  The first four lines each have a trailing space, and the program assumes 8-bit cells. Try it online! (Handling the last line is tricky...) # R, 83 71 bytes a=rbind(LETTERS[-26],","," ");a[3,7+3*c(0,3:5)]="\n";cat(a,"Z.",sep="")  Try it online! Makes a matrix of 3 rows (one with the letters, one with the commas and the other with either a space or a newline). Edit: Thanks Billywob! • cat(a,sep="") saves a few bytes: a=rbind(LETTERS,","," ");a[3,7+3*c(0,3:5)]="\n";cat(a[,-26],"Z.",sep="") – Billywob Oct 11 '16 at 8:05 • Thanks! That helped a lot! Using the [-26] on LETTERS directly saves yet another byte. – plannapus Oct 11 '16 at 15:01 ## CJam, 26 bytes 'A79333Ab{{',S2$)}*N\}/'.@


Online interpreter

'A                             Push 'A'
79333Ab                      Push [7 9 3 3 3]
{           }/        For each number n in the previous array...
{      }*              Execute n times...
',S                     Push a comma and a space
2$) Copy last letter and increment N\ Place a newline under the letter on top '.@ Push '.' and rotate  ## Perl, 37 bytes Credits to @Dom Hastings for this solution (3 bytes shorter than mine, see bellow). say+(map"$_, ".$/x/[GPSV]/,A..Y),"Z."  Run with -E (or -M5.010) flag : perl -E 'say+(map"$_, ".$/x/[GPSV]/,A..Y),"Z."'  My previous version, 3 bytes longer (total of 40 bytes) : perl -E '$_=join", ",A..Z;s/[HQTW]/\n$&/g;say"$_."'

• Slightly different approach (still uses the regex...) for 37 bytes: say+(map"$_, ".$/x/[GPSV]/,A..Y),"Z." – Dom Hastings Oct 3 '16 at 12:31
• @DomHastings Nice one, Well done. And it's more beautiful to have one statement instead of three! ;-) – Dada Oct 3 '16 at 14:31

# JavaScript (ES6), 66 64 bytes

_=>ABCDEFG
HIJKLMNOP
QRS
TUV
WXY.replace(/./g,"$&, ")+"Z."  Regex matches the characters but not the carriage returns, so, using regex replace, I can add the ", " to each character. Edit: Removed 2 characters thanks to ETHProductions • I have no idea why the other JS golfers didn't go for this solution first. Here, have an upvote. – Mama Fun Roll Oct 6 '16 at 5:45 • Dang, nice one! I think you can remove the parens in the regex if you change $1 to $&. – ETHproductions Oct 6 '16 at 13:38 # Cheddar, 70 bytes ->[65@"71,72@"80,"QRS","TUV","WXYZ"].map(@.chars.join(", ")).vfuse+'.'  Looks like it's not getting shorter than this. I've made other versions of this which use quite interesting methods but this is shortest Try it online! ## Explanation -> // Function with no arguments [ // Array, each item represents a line 65@"71, // See below on what @" does 72@"80, "QRS", "TUV", "WXYZ" ].map( // On each item... @.chars.join(", ") // Join the characters on ", " ).vfuse // Vertical fuse or join by newlines + '.' // The period at the end  The @" operator is used to generate string ranged. It generates a string starting from the left char code to the right char code. For example, 65 is the char code for A and 90 for Z. Doing 65 @" 90 would generate A through Z or the alphabet. ## C, 112102 81 bytes Thanks to cleblanc & LevelRiverSt! i,c;main(){for(c=64;++c<91;)printf("%c%c%c",c,44+c/90*2,c=="‌​GPSVZ"[i]?++i,10:32)‌​;}  • Nice solution. you can save a few bytes as 44 is 1 less than ',' and 46 1 less than '.' – cleblanc Sep 30 '16 at 19:16 • There's no need to declare int and you can make can d implicit ints as well, this is only 101 bytes i,c,d;main(){for(c=65;c<91;++c){if(c-"GPSVZ"[i])d=32;else d=10,++i;printf("%c%c%c",c,c-90?44:46,d);}} – cleblanc Sep 30 '16 at 19:21 • You can get this approach down to 82 bytes: i,c;main(){for(c=64;++c<91;)printf("%c%c%c",c,44+c/90*2,c=="GPSVZ"[i]?++i,10:32);} . Note that you can stick absolutely anything between the ?: of a ternary operator, even several expressions separated by commas (it evaluates to the last one.) – Level River St Sep 30 '16 at 20:31 # Brainfuck, 157 bytes +++++[>+>+++<<-]>>[->+>++++>+++>++<<<<]>----->+++++.>-.>++.<<<<<+[->>>+.>.>.<<<<<]+++++++++>>.<<[->>>+.>.>.<<<<<]<---[+>+++>>.<<[->>>+.>.>.<<<<<]<]>>>>+.>++.  Try it online # Ruby, 56 54 bytes $><<(?A..?Y).map{|c|c+('GPSV'[c]?",
":", ")}.join+"Z."


The first line ends with a literal newline.

Edit: saved two bytes by replacing 'A'..'Y' with ?A..?Y.

# Vim, 32 bytes

26o<C-V><C-V>64,<Esc>r.V{g<C-A>8Jj9Jj3Jj.j4JcH<C-R>"

Leaves a blank line at the end, which was allowed, but it's weird being this clumsy. Even worse, I'm ending in insert mode. I've seen some other folks do it here, so I guess it's allowed? It feels dirty.

• 26o<C-V><C-V>64,<Esc>: The first <C-V> makes the second one insert literally. The <C-V>64s this leaves in the buffer will be turned into ASCII code points, then into letters. Commas already in.
• r.: Never going to be at the end again, so do the . now.
• V{g<C-A>: Uses visual increment to turn all the 64s into the ASCII code points of the capital letters.
• 8Jj9Jj3Jj.j4J: The arbitrary line joins. First one is 8J instead of 7J because we're dealing with the blank line. The repeated 3Js are eligible for a dot repeat.
• cH<C-R>": People usually think of i<C-R> as an insert mode paste, but it's more like an insert mode macro. Stuff like <C-V>65 will run as if typed, and interpreted as a decimal code point. This leaves an extra (allowed) line at the end, and stays in insert mode.
• if you have an issue with a policy (or a lack thereof), take it up on meta, not in an answer. – Mego Oct 11 '16 at 12:50

## PowerShell v3+, 6078 67 bytes

-join(65..90|%{[char]$_+'.,'[$_-le89]+" "+"n"*($_-in71,80,83,86)})  OK. I've actually read, understood, and followed the spec this time. Promise. :D Takes the array 65..90 and loops over each element |%{...}. Each iteration, we're constructing a new string using concatenation, indexing, and multiplication. First, we take the current number and char cast it to make it an ASCII letter. That's concatenated with another char, based on indexing into the string '.,' whether we're at 90 or not (i.e., to account for Z. while having all the rest be commas). That's string concatenated with " " to space-separate the letters, and string multiplication of "n" based on Boolean value for whether the current element is -in the specified array (i.e., whether we need to concatenate on a newline character). The resulting string is left on the pipeline. Those strings are encapsulated in parens, and -joined together into a new string, which is then also left on the pipeline and implicit Write-Output at the end prints the result. Since we have n in the string, it's automatically converted to newlines upon printing. Requires v3+ for the -in operator. Has a trailing space on each line, which is OK per the challenge specs. ### Example PS C:\Tools\Scripts\golfing> .\now-i-know-my-abc.ps1 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.  • The period at the end is missing. – Downgoat Sep 30 '16 at 18:12 • Shouldn't there be a comma at the end of the first four lines? – Neil Sep 30 '16 at 19:07 • @Neil Good gravy. I'm going to delete this until I can actually understand the spec. – AdmBorkBork Sep 30 '16 at 19:08 # PHP, 62 Bytes <?=preg_filter("# ([HQTW])#","\n$1",join(", ",range(A,Z)));?>.


only for comparison 87 Bytes

<?="A, B, C, D, E, F, G,\nH, I, J, K, L, M, N, O, P,\nQ, R, S,\nT, U, V,\nW, X, Y, Z.";

• You can save a byte by using an actual newline in place of the \n. – Alex Howansky Oct 2 '16 at 23:03
• As you're allowed trailing spaces on each line you can save a byte by dropping the space from the regex. Also you can save a byte by using the (deprecated and removed in 7.0) ereg_replace as it lets you skip the delimiters in the regex. – user59178 Oct 3 '16 at 11:24
• @user59178 I could save 3 Bytes but i would avoid this. Yes the trailing space is allowed. I could wrote as regex "# (?=[HQTW])#" and short the replace to "\n" same bytes and makes it clearer. To use a deprecated function can confuse beginners. And the physical break can interpreted wrong on other systems then Unix. You can post it as your own sugesstion. – Jörg Hülsermann Oct 3 '16 at 12:40

# MATL, 38 29 bytes

9 bytes saved thanks to @Luis!

1Y2X{', '&Zc46h1[CEII]I*11hY{


Try it Online!

Explanation

1Y2     % Push the upper-case alphabet to the stack
X{      % Break the character array into a cell array (similar to a list)
% where each element is a letter
', '&Zc % Combine back into a string with ', ' between each element
46h     % Append '.' (via ASCII code) to the end of the string
1       % Push the number 1
[CEII]  % Push the array: [7, 9, 3, 3]
I*      % Multiply this array by 3: [21, 27, 9, 9]
llh     % Append an 11 to this array: [21, 27, 9, 9, 11]
Y{      % Break our comma-separated list of characters into groups of this size
% Implicitly display the result


## R, 146 bytes

L=LETTERS
f=function(x,y=""){paste(x,collapse=paste0(", ",y))}
cat(f(c(f(L[1:7]),f(L[8:16]),f(L[17:19]),f(L[20:22]),f(L[23:26])),"\n"),".",sep="")


Explanation:

LETTERS is predefined for uppercase letters.
The f function is for concatenating vector x on , with additional y (used for newlines).
The cat is the used as it prints \n as newlines. f is called on the letters to form rows and then on the rows again to form the whole output.

Probably golfable - I don't like the multiple calls of f...

• The raw output is only 77 bytes long. Printing that directly might be shorter... – Lynn Sep 30 '16 at 21:54
• @Lynn, I know, but here I see some golfing possibilities. – pajonk Oct 1 '16 at 16:09

# CJam, 31 bytes

'[,65>", "*7933Ab{3*/(\:+}%N*'.


Explanation:

'[,65>                             push uppercase alphabet
", "*                        ", " between all letters
7933Ab                  push [7 9 3 3]
{3*/(\:+}%        slices of lengths 21, 27, 9, 9
N*'.    join slices with newlines, add final "."


Try it online

# Julia, 71 bytes

f()=join(join.(['A':'G','H':'P',"QRS","TUV","WXYZ"],[", "]),",\n")*"."


Requires 0.5 or better for broadcasting .()

• On the one hand, this currently does not have a trailing period, and doesn't it need a print/function definition? On the other hand, not saving join to a variable saves a byte. – Sp3000 Oct 2 '16 at 13:27
• My bad wrt missing the ".", and thanks for the pointer on join. I misscounted. Running the program returns the string. Isn't a program returning a string a valid output? (Or is it only functions that are allowed to return things to count as output. if so f()= is shorter thant print()) – Lyndon White Oct 2 '16 at 13:55
• Sure, f()= or ()-> is fine - I think the idea is that functions are assignable and can be run multiple times, and in contrast this would be a code snippet. – Sp3000 Oct 2 '16 at 14:18

# Cheddar, 57 bytes

->(65@"90).sub(/[GPSV]/g,"$0 ").sub(/[^Z\n]/g,"$0, ")+"."


Try it online! Isn't that beautiful? It's a nice rectangle.

Two regex substitutions. (65@"90) is the uppercase alphabet, .sub(/[GPSV]/g,"$0\n") replaces GPSV with itself and "\n", .sub(/[^Z\n]/g,"$0, ") replaces all non newline and Z characters with itself and ", ", and "." adds a final ..

• Nice technique, and nice job outgolfing Downgoat ;) – ETHproductions Oct 2 '16 at 18:27

# Japt, 24 bytes

;B¬qJ+S r"[HQTW]"@R+XÃ+L


Test it online!

### How it works

;                        // Reset various variables. B is set to "ABC...XYZ", J is set to ",", and L is set to ".".
B¬                      // Take the uppercase alphabet and split into chars.
qJ+S                  // Join with ", ".
r"[HQTW]"        // Replace each H, Q, T, or W with
@R+XÃ   //   a newline plus the character.
+L // Append a period to the result.
// Implicit: output last expression


# Java, 116109105 104

String f(){String s="";for(char c=65;c<91;)s=s+c+(c>89?46:',')+("GPSV".indexOf(c++)<0?' ':10);return s;}


Ungolfed:

String f() {
String s = "";
for (char c = 65; c < 91;) {
s = s + c
+ (c > 89 ? 46 : ',')
+ ("GPSV".indexOf(c++) < 0 ? ' ' : 10);
}
return s;
}

• You can golf it by 7 bytes: All three || to | (-3); changing c==90 to c>89 (-1); changing '.' to 46 (-1); and changing '\n' to 10 (-2). – Kevin Cruijssen Oct 3 '16 at 9:06
• @KevinCruijssen thanks, I tried using decimals but it looks like if I replace both character constants in a ternary it changes the expression type to integer, which broke it. Changing one constant worked and squeezed out a few bytes. – user18932 Oct 3 '16 at 13:43
• @KevinCruijssen thanks. If I had enough coffee in me I would have remembered to update it myself. – user18932 Oct 3 '16 at 13:47
• 2 more bytes: "GPSV".contains(""+c) instead of c==71|c==80|c==83|c==86. – TNT Oct 3 '16 at 17:57
• @TNT I was able to do slightly better. I knew that part could be improved, thanks for the push in the right direction. – user18932 Oct 3 '16 at 20:05

# q, 46 bytes

-1@'(", "sv/:0 7 16 19 22_,:'[.Q.A]),'",,,,.";


# Retina, 43 bytes


Z
{2
$ }T01L_L .$&,
[HQTW]
¶$& ,$
.

Leading newline is significant. Try it online!

This is my first time using Retina, so any golfing tips are appreciated...

# Pyth, 25 bytes

+Pjmj\ dc*G\,j94092 23)\.


A program that prints the result to STDOUT.

Try it online

How it works

+Pjmj\ dc*G\,j94092 23)\.  Program. Input: none
G                Yield string literal'abcdefghijklmnopqrstuvwxyz'
* \,              Cartesian product of that with ',', yielding a list of
characters with appended commas
j94092 23)    Yield the integer 94092 in base-23, giving [7, 16, 19, 22]
c                  Split the comma-appended character list at those indices
mj\                     Join each element of that on spaces
j                        Join that on newlines
P                         All but the last element of that, removing trailing ','
+                      \.  Append '.'
Implicitly print
`