# Draw the Sawtooth Alphabet

A simple one today. Write the shortest program that draws a "sawtooth alphabet" given a positive integer for the height. You must write the name of your programming language when you come to the letter it starts with.

For example, if your language is Python and the input is 1 the output should be:

ABCDEFGHIJKLMNOPythonQRSTUVWXYZ


If the input is 2 the output should be:

 B D F H J L N Python R T V X Z
A C E G I K M O      Q S U W Y


If the input is 4 the output should be:

   D     J     Python     V
C E   I K   O      Q   U W
B   F H   L N        R T   X Z
A     G     M          S     Y


Notes

• A always starts at the bottom left.
• Input can be via stdin or function call or similar. Output to stdout.
• Input above 26 doesn't need to work.
• No trailing spaces.
• Are programming languages with one letter names allowed? (C, J, K, etc.) Jul 28 '14 at 6:15
• @isaacg Sure. I'd imagine it might be easier in them. Jul 28 '14 at 6:16
• Can the input simply be expected to be stored in a variable? Jul 28 '14 at 10:17
• @MartinBüttner Yes, that's fine. Jul 28 '14 at 15:54
• Btw, this isn't a sawtooth wave, this is a triangle wave :P
– qwr
Jul 29 '14 at 1:04

## C, 134

n,m,c,p;
main(r){
for(scanf("%d",&n),m=--n?n*2:1;n+r--;puts(""))
for(c=-1,p=1;c++<25;)
p+=(c-n-r)%m*((c-n+r)%m)?1:1-printf("%*c",p,c+65);
}


Compiles on gcc with a few warnings. Newlines aren't included in the character count.

122 characters if the input is already stored in n.

Thanks to user2992539, tolos and edc65 for improvements.

• You can use puts("") instead of printf("\n"). Jul 28 '14 at 17:54
• Save 4 characters with p-=(c-n+r)%m*((c-n-r)%m)?0:printf("%*c",p,c+65); instead of if((c-...
– user21677
Jul 28 '14 at 22:29
• Sorry for previous (deleted) comment.I was wrong. Playing with signs and abusing the fact that the first argument of main is 1 if there are no parameters: 134 n,m,c,p; main(r){ for(scanf("%d",&n),m=--n?n*2:1;n+r--;puts("")) for(c=-1,p=1;c++<25;) p+=(c-n-r)%m*((c-n+r)%m)?1:1-printf("%*c",p,c+65); } Jul 29 '14 at 8:58

if n holds the height:

# C + escape codes: 81

x;main(y){for(y=n--;x<26;x++)printf("\033[%d;%dH%c",n?x/n&1?y++:y--:y,x+1,x+65);}


# C: 110

x;char a[702]={[0 ...701]=32};main(y){for(y=--n;x<26;a[x*27-1]=10)a[27*(n?x/n&1?y++:y--:y)+x]=x+++65;puts(a);}

• I admit defeat. What on earth. :D Jul 29 '14 at 13:30
• May I ask for compilation instructions? cc gives error "<bebe.c:1:17: error: ‘n’ undeclared (first use in this function)”. Jul 29 '14 at 13:43
• well it is way worse than it looks. firstly the second one contains trailing spaces, secondly they both relies on that n is a global variable set to a number of your choice (as Martin has previously asked).
– bebe
Jul 29 '14 at 13:46
• Oh, so I have to provide n in any way I can. Lol. Still impressed. Jul 29 '14 at 14:10

# TI-BASIC - 148 bytes (raw text), 186 bytes (graphic)

In response to the OP, the wonderful TI-83 (and newer) comes with a size of 16 x 8 (just using the standard large text) or with a size of 94 x 62 pixels (which with small text is worth about 10 lines).

Now, this has a little problem (to which I would like clarification). The size impositions can't be "ignored" by the interpreter; in other words, if we were to try to set the sawtooth height at 20, it would give an error preventing the full execution of the code. I could write code that would, in an infinite environment, produce the correct output, except it wouldn't run on the machine.

With this being said, I present you the (running) versions of the programs. They all depend on the variable N being set to the desired height in lines before running:

• Raw text approach

:ClrHome
:"ABCDEFGHIJKLMNOPQRSTI-BASICUVWXYZ"→Str1
:8→R
:For(C,1,16
:If N=1
:Then
:0→F
:Else
:If R<2 or 10-R>N
:1→F
:If R>7
:-1→F
:End
:If C≠20
:Then
:Output(R,C,sub(Str1,C,1
:Else
:Output(R,C,sub(Str1,C,8
:C+7→C
:End
:R+F→R
:End


In order to make this work regardless of the terminal, change For(C,1,16 to For(C,1,33 and remove the upper bound checking (R<2 or). Here is the output with 5→N:

• Graphic approach (this may also need AxisOff for clarity)

:ClrDraw
:N*6→N
:"ABCDEFGHIJKLMNOPQRSTI-BASICUVWXYZ"→Str1
:57→R
:For(C,1,56
:If N=6
:Then
:0→F
:Else
:If R<7 or 64-R>N
:6→F
:If R>51
:-6→F
:End
:If C≠20
:Then
:If C>50
:Then
:Text(R,C,sub(Str1,C-23,1
:Else
:Text(R,C,sub(Str1,C,1
:End
:Else
:Text(R,C,sub(Str1,C,8
:C+30→C
:End
:R+F→R
:End


This one works OK, with two minor quirks. The height is still a problem, although the width isn't. However, I didn't space the letters, so in some cases (when the letter starts to rise or decline from the sawtooth), the letters may be chopped off by their successors. To make it work regardless of the terminal, remove the upper bound check (R<7 or). Then follows the graph:

• Now I have to port this to my graphing calculator Jul 29 '14 at 14:22
• Quick comment: Instead of 0→F you can do Delvar F which saves 1 byte once tokenized. Also, I'm sure you can factor the Output/Text towards the end thanks to an inline boolean test condition for the coordinate, and for the C+7→C, write it in a short if (no then/else/end) Mar 17 '15 at 2:19

# Pure Bash (no coreutils), 181 bytes

m=$1 for l in A Bash {C..Z};{ ((m))||s=++ ((m>$1-2))&&s=--
for((m=$1==1?1:m,m$s,i=0;i<$1;i++));{ ((i-m))&&a[i]+=${l//?/ }||a[i]+=$l } } shopt -s extglob printf %s\\n "${a[@]%%+( )}"


### Output:

Piped to cat -E just to prove there are no trailing newlines.

$./sawtooth.sh 1 | cat -E ABashCDEFGHIJKLMNOPQRSTUVWXYZ$
$./sawtooth.sh 5 | cat -E E M U$
D F     L N     T V$C G K O S W$
Bash     H J     P R     X Z$A I Q Y$

# J : 75 bytes

NB. without IO |:26([:u:65+i.@[)(($(,|.@}.@}:)@i.)<"1@,.i.@[)(' '$~,~)}5
2(1!:2)~|.26([:u:65+i.@[)(($(,|.@}.@}:)@i.)<"1@,.i.@[)(' '$~,~)}".1!:1[1


Using the wonderful Amend conjunction. As usual the IO is ugly and clunky, not going into details there. The core solution takes 3 gerunds (a sort of noun-ified verb (aka. function)):

• a) generating the alphabet
• b) generating the indices
• c) generating the matrix to make amends to

x (abc}) y

a) is a pretty trivial lookup in the ascii table

c) is even more trivial

b) is the interesting one. The morale is that the horizontal indices are supposed to be starting from 0 going to y-1 and back down, repeating this 26 times. Eg. for y == 4:

0 1 2 3 2 1 0 1 2 3 2 1 ...


Implementing this gives for b):

($(,|.@}.@}:)@i.) <"1@,. i.@[) NB. is equivalent too (tine0 tine1 tine2) NB. a fork with tines defined as tine0 =: hook0 =: hook0_0 hook0_1 NB. a dyadic hook: x (g h) y -: x g h y hook0_0 =:$                    NB. reshape
hook0_1 =: (hook1_0 hook1_1)@i. NB. do hook1 after making 0-y
hook1_0=: ,                   NB. append to self
hook1_1=: |.@}.@}:            NB. rotated version of y after beheading and curtailing
tine2 =: i.@[                  NB. generate 0-x
tine1 =: <"1@,.                NB. glue together coordinates.


And oh yea, handy fact: J's name is ... "J".

• Is it worth to use amend? It seems easier to me to say something like 3 :'|:(26$1+(i.1=y),}:|i:<:y)|.@{."+u:65+i.26' The ugly part in that solution is the 8 characters just to special case height 1, but this can probably be shortened a bit. Jul 30 '14 at 9:40 • Thanks for the suggestion! Yours is indeed far shorter, and amend is probably overkill. Since it's so different, maybe you'd want to post it as a solution yourself? Jul 30 '14 at 15:34 • The spec says "no trailing spaces" and my solution does print trailing spaces. Jul 30 '14 at 20:20 ## R (204) f=function(x) { m=matrix(" ",x,26) i=x d=ifelse(x==1,0,-1) for (j in 1:26) { m[i,j]=LETTERS[j] if (!((i+d) %in% 1:x)) d=-d i=i+d } for (i in 1:x) cat(m[i,],"\n",sep="") }  Result > f(1) ABCDEFGHIJKLMNOPQRSTUVWXYZ > f(2) B D F H J L N P R T V X Z A C E G I K M O Q S U W Y > f(3) C G K O S W B D F H J L N P R T V X Z A E I M Q U Y > f(7) G S F H R T E I Q U D J P V C K O W B L N X Z A M Y  • I see what you did there! Very smart... Jul 28 '14 at 23:57 • +1 Neat! You can get rid of the spaces around your for statements though (for(i in 1:x)cat(... for instance) or the one around %in%. Jul 29 '14 at 11:11 ## J, 67 57 61 characters echo@dtb"1@|.@|:@(26&,$(u:65+i.26)#~1 j.26$(0#~1=]),<:#-&0 2)  Use as a function:  echo@dtb"1@|.@|:@(26&,$(u:65+i.26)#~1 j.26$(0#~1=]),<:#-&0 2) D J P V C E I K O Q U W B F H L N R T X Z A G M S Y  Explanation: this solution uses a different approach than the other J solution. Instead of generating a sawtooth wave 0 1 2 3 2 1 0 1 ..., I looked at the spacing between consecutive letters. For instance, for n=4 if you go from the A upwards, wrap over to the second column and reach B, then you find four spaces between A and B. This pattern of spacing between letters is very regular: for n=4 the pattern is 4 4 4 2 2 2 4 4 4 .... So the idea is to first build the flattened (and transposed) array, and then re-shape it and flip it so it look right. The output routine is straightforward (for being J, at least): dtb is "delete trailing blanks" and "1 says "operate on each line". dtb and echo are both provided by the standard library. Thanks to Zsbán Ambrus for some golfing help. • 48 byte solution. This works in J 901 but not TIO (can't figure out why it's failing there). And I'm pretty sure it could be golfed further too. Dec 5 '20 at 3:24 ## Javascript - 248224 235 z=~~prompt(),y="ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");y[9]="Javascript";for(w=[],v=0;v<z;v++)w[v]="\n";v--;for(i=0;i<26;i++){for(j=0;j<z;j++)w[j]+=j-v?i-9?" ":" ":y[i];~~(i/(z-1))%2?v++:v--;}if(z==1)w=y;console.log(w.join(""))  Here is a link to the jsfiddle, where you can test it. edit: Made a console log for a monospaced font and removed the commas if input==1. • Suggestions: 1: parseInt and Math.floor can be both changed with an integer coercing operation like |0 or ~~. 2: it's shorter to build the w array directly, without split. for(w=[],v=0;v<z;v++)w[v]="\n"; Jul 28 '14 at 8:40 • ... and there is not an output statement (console.log or whatever you use in your fiddle, it's part of the char count) Jul 28 '14 at 9:02 • @edc65 Thank you for the tips. You were right I forgot the output here so i added an alert, but there is no mono spaced font so it looks pretty chaotic. Jul 28 '14 at 9:25 • @izlin Instead of (i==9?" ":" ") you could use (i^9?" ":" "), which saves a character. – rev Jul 28 '14 at 12:11 • HELP! can anyone explain? (Why is there twice <code>v=0</code>?) Jul 28 '14 at 14:32 # Perl 119 $s.=/26/?++$r&&$/:$m-1&&$r-abs$_%(2*$m-2)+1-$m?$"x(1+3*/15/):/15/?Perl:(A..Z)[$_]for(0..26)x($m=<>);print$s=~s/\s+$//rg


This program takes input from STDIN and prints the result to STDOUT.

And bonus - a version that is against the rules as it prints trailing spaces, but adds some interaction:

#!/usr/bin/perl -p
$r=0;$_=join'',map{/26/?++$r&&$/:$m-1&&$r-abs$_%(2*$m-2)+1-$m?$"x(1+3*/15/):/15/?Perl:(A..Z)[$_]}(0..26)x($m=$_)  ...and some tests below: 1 ABCDEFGHIJKLMNOPerlQRSTUVWXYZ 2 B D F H J L N Perl R T V X Z A C E G I K M O Q S U W Y 4 D J Perl V C E I K O Q U W B F H L N R T X Z A G M S Y 6 F Perl Z E G O Q Y D H N R X C I M S W B J L T V A K U  # MetaPost (207) numeric h,d,y;h=5;d=-1;y=1;u=5mm;pair p;string s;for x=1upto26:p:=(x,y)*u;s:=char(x+64);if x=13:s:="MetaPost";elseif x>13:p:=(x+2,y)*u;fi;label.rt(s,p);if(y=h)or(y=1):d:=d*-1;fi;if h=1:d:=0;fi;y:=y+d;endfor;  You can try it here. # Bash (213) (223) read i p=0 d=1 printf '\n%.0s' seq$i
for l in {A..Z}
do (($p==$i-1))&&((p=$p*-1)) (($i==1))&&p=0
(($p!=0))&&echo -en "\033[s\033[${p#-}A"
[[ "$l" == "B" ]]&&l="Bash" echo -en$l"\033[s\033[${p#-}B" ((p++)) done  Minor tweaks and we're down to 213. The original one had a minor bug. Tested and confirmed to work on bash version 4.2.37. Thanks to @manatwork for pointing out the bug and some tips. • I edited your post by adding syntax highlighting to it, but now I see that it wrongly highlighted a part of your code as a comment, so I rolled it back. I just said this in case you were wondering why I rolled it back :) Jul 28 '14 at 12:30 • @ProgramFOX That's alright. Thanks anyhow! – Okw Jul 28 '14 at 14:20 • I think there is minor bug somewhere, as the output is slowly descending. (At least in Bash 4.3.) Some minor improvements to reduce the size to 194 characters: omit the sigil in arithmetic evaluation, do not try to double-quote inside double-quoted string: pastebin.com/zKa3zdwR Jul 28 '14 at 15:28 • Can you use newlines instead of some of the ; just to make it a tiny bit more readable? It won't affect your golf score Jul 28 '14 at 19:43 # Haskell – 432 Bytes (unfortunately...) This turned out to be much harder than I expected to accomplish purely, hence the hefty byte count. I am sure I (or someone) could do better, but I've spent too much time on this as it is. The golfed version is as follows: import Data.Matrix import Data.Vector(toList) r=repeat s h=y h$l(take 26(case h of 1->r 1;_->concat$r$[h,h-1..1]++[2..h-1]))['A'..'Z']$matrix h 32(const ' ')<|>matrix h 1(const '\n') l _[]m=m l(x:i)(r:e)m=l i e$u m(let z=26-length i in if z<9 then z else z+6)x r
l _ _ m=m
u m c r h=case h of 'H'->t c r"Haskell"m;_->setElem h(r,c)m
t _ _[]m=m
t c r(x:i)m=t(c+1)r i$setElem x(r,c)m y h m=concat[toList$getRow x m|x<-[1..h]]


To run, load the code into ghci and execute putStr $s Int where Int is your desired height. You could also add import System.Environment main :: IO () main = fmap (s . read . head) getArgs >>= putStr  under the imports in a text file, compile it with ghc, and pass the height as a command line argument. Ungolfed version: import System.Environment import Data.Matrix import Data.Vector (toList) main :: IO () main = fmap (sawtooth . read . head) getArgs >>= putStr type M = Matrix Char sawtooth :: Int -> String sawtooth height = let mat = matrix height 32 (const ' ') <|> matrix height 1 (const '\n') numbers = take 26 (case height of 1 -> repeat 1 _ -> concat$ repeat $[height,height-1..1]++[2..height-1]) chars = ['A'..'Z'] in toString height$ makeMatrix numbers chars mat

makeMatrix :: [Int] -> String -> M -> M
makeMatrix []     []     mat = mat
makeMatrix (x:xs) (s:ss) mat = makeMatrix xs ss $updateMatrix mat (let z = 26 - length xs in if z < 9 then z else z + 6) x s makeMatrix _ _ mat = mat updateMatrix :: M -> Int -> Int -> Char -> M updateMatrix mat col row char = case char of 'H' -> insertHaskell col row "Haskell" mat _ -> setElem char (row, col) mat insertHaskell :: Int -> Int -> String -> M -> M insertHaskell _ _ [] mat = mat insertHaskell col row (x:xs) mat = insertHaskell (col+1) row xs$ setElem x (row, col) mat

toString ::Int -> M -> String
toString height mat = concat [ toList $getRow x mat | x <- [1..height] ]  • I believe you can replace const with pure (using the Applicative instance for functions) to save a few bytes. Apr 20 '18 at 7:00 # C#/LINQ: using System; using System.Linq; namespace SawtoothAlphabet { class Program { static void Main(string[] args) { int N = Int32.Parse(args[0]); // eg 4 Console.WriteLine( String.Join(Environment.NewLine, Enumerable.Range(0, N).Select(line => String.Concat(Enumerable.Range(0, 26).Select(i => line == Math.Abs(i % (2 * (N - 1)) - (N - 1)) ? (i == 2) ? "C#" : Char.ConvertFromUtf32(i + 'A') : (i == 2) ? " " : " ") ).TrimEnd()))); } } }  Brief explanation: Enumerable.Range(0, N).Select(...) causes a string to be generated for each line which is eventually concatenated into a single string with String.Join(Environment.NewLine, ...). For each line we cycle through all 26 characters with Enumerable.Range(0, 26).Select(...), the test at the start of the lambda expression determines whether to generate a character or space while the i==2 checks for "C" and converts it to either "C#" or two spaces depending on the line. The String.Concat(...) converts the resulting IEnumerable<char> for each line into a string before passing it to TrimEnd(...) to cleanly strip away any trailing whitespace. # K, 60 bytes 0:'{+{x!y}.'+(26#{(!x),|1_!x-1}x;(((x-1)#" "),)'c$65+!26)}


Pretty straightforward, and it looks like I just edged out the J solution. :)

First, generate an alphabet:

  c$65+!26 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"  And a sawtooth wave of an appropriate length:  26#{(!x),|1_!x-1}5 0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 0 1 2 3 4 3 2 1 0 1  Pad each letter of the alphabet with leading spaces:  (((5-1)#" "),)'"ABC" (" A" " B" " C")  Zip the alphabet and the square wave together, and rotate each row:  +(0 1 2;(" A";" B";" C")) ((0 " A") (1 " B") (2 " C")) {x!y}.'+(0 1 2;(" A";" B";" C")) (" A" " B " "C ")  And the transposition of that is our answer:  +{x!y}.'+(0 1 2;(" A";" B";" C")) (" C" " B " "A ")  Try it here in oK. # PHP (216) (205) New version: $b=array_fill(65,26,' ');$b[80]=' ';$b=array_fill(0,$i,$b);for($j=--$i,$x=64;++$x<91;$i||$j=0){$b[$j][$x]=chr($x);$x==80&&$b[$j][$x]='PHP';$j+=($d=$j<($d?$i:1))*2-1;}echo join("\n",array_map('join',$b));


Old version:

$b=array_fill(0,$i,array_fill(0,28,' '));for($j=--$i,$x=-1;++$x<28;$i||$j=0){$q=&$b[$j];$q[$x]=chr($x-($x&16)/8+65);$x==15&&($q[++$x]='H')*$q[++$x]='P';$j+=($d=$j<($d?$i:1))*2-1;}echo join("\n",array_map('join',$b));


expects the variable $i to be the height. ## C, 214 169 bytes, no trailing spaces Thank to @edc65 and @tolos for their helpful suggestions. #define C ((c-i+n-65)%z&&(c+i+n-67)%z) n,i,m,c,z;main(){scanf("%d",&n);z=n<2?1:2*n-2;for(;i++<n;){for(m=c=64;c++<90;)m=C?m:c;for(c=64;c++<m;)putchar(C?32:c);puts("");}}  • It's a lost battle, but I persist: #include <stdio.h> is not needed in many cases, be it gcc or any other compiler. It's standard and valid C anyway. Jul 28 '14 at 9:07 • @edc65: Depends on what you consider "valid C". It is AFAIK valid K&R C, but ANSI/ISO C demands that variadic functions (which include scanf and printf) are given prototypes, otherwise you'll get undefined behaviour. #include <stdio.h> is, of course, the shortest way to give a prototype to both scanf and printf. Jul 28 '14 at 9:34 • @celtschk valid K&R is enough for me in code golf. And 'in many cases' (when just using puts for instance) is valid C89. What I want stress out is that is not a strange behaviour of gcc. (Thks for the note about variadic functions, anyway) Jul 28 '14 at 10:15 • Globals are type int and initialized to zero. Might as well drop int declaration for main if you aren't returning anything. Can drop extra parens, replace ' ' with 32 and if(!C)m=c with a ternarny statement, and as I just learned (above) replace printf("\n") with puts("") for 18 characters: n,i,m,c,z;main(){;scanf("%d",&n);z=n<2?1:2*n-2;for(;i<n;i++){for(m=c=65;c<91;c++)m=C?m:c;for(c=65;c<=m;c++)printf("%c",C?32:c);puts("");}} – user21677 Jul 28 '14 at 22:51 Javascript (204 185 150 145) h=m=4;d=h>1?-1:0;o=[];for(a=0;a<35;a++){for(r=h;r;r--)o[r]=(o[r]||"")+(r==m?"ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a]:" ");if(a<9||a>17){m+=d;if(m<2||m==h)d=-d}}console.log(o.join("\n"))  ## EDIT Saved 13 bytes by not building an array and .join("\n"). Required flipping the for loops. Then, with help from C coding son, made code entirely too clever to save another 12 bytes. Here is the readable version showing the logic change. for (row = height; row; row--) { rowOfNextActiveLetter = 1; direction = height > 1 ? -1 : 0; output = ""; for (a = 0; a < 35; a++) { output += (row == rowOfNextActiveLetter ? "ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a] : ""); if (a < 9 || a > 17) { rowOfNextActiveLetter -= direction; if (rowOfNextActiveLetter < 2 || rowOfNextActiveLetter == height)direction = -direction } } console.log(output) }  Golfed (161): for(r=h;r;r--){m=1;d=h>1?-1:0;o="";for(a=0;a<35;a++){o+=(r==m?"ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a]:" ");if(a<9||a>17){m-=d;if(m<2||m==h)d=-d}}console.log(o)}  Golfed and obfuscated (149): for(r=h;r;r--,console.log(o))for(m=1,d=h>1?1:0,o="",a=0;a<35;)if(o+=r==m?"ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a]:" ",a<9|a++>17)d=(m+=d)<2|m==h?-d:d  Reversed Alphabet and loop (145): for(r=h;r;r--,console.log(o))for(m=d=1,o="",a=35;a;)if(o+=" ZYXWVUTSRQPONMLKtpircsavaJIHGFEDCBA"[r==m?a:0],a<18|a-->26)d=h<2?0:(m+=d)<2|m==h?-d:d  • I like it even if I don't understand it full. But anyway you can cut 9 chars removing substr and using direct index .substr(a,1) => [a] Jul 30 '14 at 8:30 • You can narrow it further by using bitwise operators and coalescing iterators for 182: h=m=4;d=1<h?-1:0;o=[];for(a=0;35>a;a++){for(r=h;r;r--)o[r]=(o[r]||"")+(r==m?"ABCDEFGHIJavascriptKLMNOPQRSTUVWXYZ"[a]:" ");if(9>a|17<a)if(m+=d,2>m||m==h)d=-d}console.log(o.join("\n")) Oct 31 '14 at 0:59 • whoops, cleaned up one too many spaces Mar 16 '15 at 16:43 # C: 142 139 characters Dreadfully long, I expect to be able to shorten it a bit: char a[26][27],i,j,p,d;main(n){for(scanf("%d",&n);i<26;d^=!p^p+2>n,p+=d-(d^n>1),i++)for(j=n;j--;a[j][i]=p^j?32:i+65);while(n)puts(a[--n]);}  Slightly more readable: char a[26][27], i, j, p, d; main(n) { for ( scanf("%d", &n); i < 26; d ^= !p ^ p + 2 > n, p += d - (d ^ n > 1), i++ ) for ( j = n; j--; a[j][i] = p ^ j ? 32 : i + 65 ); while (n) puts(a[--n]); }  Edit: I missed the "no trailing spaces"-rule, but I will be back. # Scala, 246 bytes def f(h:Int)={val a=Seq.fill(h)(Array.fill(32)(' '));var(r,x,d)=(h-1,0,if(h==1)0 else-1);def p(c:Char){a(r)(x)=c;x+=1};for(c<-'A'to'Z'){p(c);if(c==83)"cala"foreach p;r+=d;if(r==0|r==h-1)d*= -1};for(z<-a)println(new String(z)replaceAll(" +$",""))}


reformatted and commented:

def f(h: Int) = {
val a = Seq.fill(h)(Array.fill(32)(' '));
// r - row; x - x coordinate, column; d - direction
var (r, x, d) = (h - 1, 0, if(h==1) 0 else -1);
def p(c: Char) { // p for "put the character"
a(r)(x) = c;
x += 1
};
for(c <- 'A' to 'Z') {
p(c);
if(c == 83)      // 83 == 'S'
"cala" foreach p;
r += d;
if(r == 0 | r == h - 1)     // | is shorter than ||
d *= -1
};
for(z <- a)
println(new String(z) replaceAll (" +\$", ""))  // trimming trailing whitespace
}


Results:

scala> f(4)
D     J     P         V
C E   I K   O Q       U W
B   F H   L N   R     T   X Z
A     G     M     Scala     Y

scala> f(5)
E       M           U
D F     L N         T V
C   G   K   O   Scala   W
B     H J     P R         X Z
A       I       Q           Y

scala> f(1)
ABCDEFGHIJKLMNOPQRScalaTUVWXYZ


## Python - 137

Input to be stored in i. e.g. i=8

l=[""]*h;k=j=0;y=h-1;exec'l[y]+=" "*(j-len(l[y]))+chr(k+65)+"ython"*(k==15);j=len(l[y]);y-=1^k/(h-(h>2))%2*-2;k+=1;'*26;print"\n".join(l)


# Racket

Here's a clean functional version: suggestions to shorten it welcome.

(define (sawtooth n)
(define (ST i d m lns)
(if (null? m)
lns
(let* ([v (first m)]
[spc (make-string (string-length v) #\space)]
[I (+ i d)])
(ST I
(if (or (zero? I) (= (sub1 n) I)) (* d -1) d)
(rest m)
(for/list ([ln lns] [j n])
(~a ln (if (= i j) v spc)))))))
(displayln
(string-join
(ST (sub1 n)
(if (= n 1) 0 -1)
(string-split "A B C D E F G H I J K L M N O P Q Racket S T U V W X Y Z")
(make-list n "\n")))))


## Output

> (sawtooth 1)
ABCDEFGHIJKLMNOPQRacketSTUVWXYZ

> (sawtooth 2)
B D F H J L N P Racket T V X Z
A C E G I K M O Q      S U W Y

> (sawtooth 8)
H                  V
G I                U W
F   J              T   X
E     K            S     Y
D       L     Racket       Z
C         M   Q
B           N P
A             O
`