Programming Challenge!

Twenty years ago, during my first year in academia, my Pascal tutor set us some top-notch assignments.

Your mission:

Write a program which draws a diamond of the form illustrated below. The letter which is to appear at the widest point of the figure (E in the example) is to be specified as input data.

Here’s a scan of the original hand-out:

My original Pascal solution, which I prototyped using BBC Basic V, took less than a page of fan-fold listing paper and was implemented as a console application. 50% of the listing dealt with input validation and “do you want to run the program again?” code! I will convert the example line-by-line into C# for later publication here! Of course, were I to write it today, it should look very different!

I’d be keen to see your solutions, written in your choice of programming language. Novelty value for uniqueness in your choice of programming language may well be rewarded! Procedural, object-oriented, functional, dynamic, verbose, terse…the choice is yours!

“What’s in it for me?” you might ask?
Well, nothing really, a bit of kudos and the feeling of a job well done! However, I will offer the two best/novel UK-based solutions a much-coveted DDD polo shirt (modelled here!). My decision is final, colour may vary, size might not be the same size as you, yada yada, other legalese applies, etc.

Submission by comments here on this post, by e-mail (top right About Me), or via Twitter @camurphy please!

Over to you!

UPDATE: Comments seem to mangle the code formatting, it has been suggested that code is submitted either via e-mail or via http://pastebin.com/

120 thoughts on “Programming Challenge!”

  1. Wow, thanks Simon & David for joining the APL-Club here 🙂
    Compliments, Simon, for the well documented solution. (While shaving this morning I thought I could spare a few chars, but didn’t get it as compact as yours, nice 🙂
    Especially the unneccessary “mix” is embarrassing, whish I could edit my post 😉

    Well, here’s the updated version (54 chars):
    {{{⍵⍪1 0↓⊖⍵}⍵,0 ¯1↓1⌽⌽⍵}{(⍳⍵)⌽(⍵,⍵)↑(⍵,1)⍴⎕a}⎕a⍳⍵}’E’

    Looking at Simon’s version, I realize my use of dynamic fns made the whole thing more verbose than required – I’ll keep that mind next time! 😉

  2. Just wanted to whole-heartedly endorse what David Liebtag said: The whole thing can be done in a single line of APL code, but a commented function is much better. In my original post I was trying to draw attention to how well APL handles the problem compared to many other languages.

    Here’s my solution:

    ∇R←LetterDiamond A;letters
    [1] letters←(⎕A⍳A)↑⎕A ⍝ Get letters, e.g. A-E
    [2] R←⊃(-⍳⍴letters)↑¨letters ⍝ Form upper-right side
    [3] R←R⍪1 0↓⊖R←(⌽R),0 1↓R ⍝ Reflect to get whole diamond

    Again, you may need a Unicode APL font installed in order to view it.

    For anyone interested, I documented how the code works on the APL Wiki:

    http://aplwiki.com/Studio/LetterDiamonds

    I’d encourage people to find out more about APL. It’s not as widely known as it deserves. For some types of problem it’s a superb language to use.

  3. Well, as there are a few APLers here, I have an A+ solution here: http://twitpic.com/3g4mi – it is written as a single function (yes, it could be a single ugly line as well). The results are shown here: http://twitpic.com/3g4n0

    Unfortunately I have not yet figured out how to translate to Unicode (the results were pretty far off when I tried) so no code here 🙁

  4. It seems the APL community is alive and kicking. Here is my version in Dyalog with quad IO = 1 and quad ML = 3

    z,0 1↓⌽z←z⌽⊃n↑¨⎕A[z←(⍳n),1↓⌽⍳n←⎕A⍳’E’]

    and just for fun its cousin

    (⌽z),0 1↓z←z⌽⊃n↑¨⎕a[z←(⍳n),1↓⌽⍳n←⎕a⍳’F’]

    Graham.

  5. Here’s my SQL version for Informix 7.20!

    CREATE TEMP TABLE t_diamond(
    t_aRow CHAR (40))
    WITH NO LOG;

    CREATE PROCEDURE diamond (userInput CHAR (1))

    DEFINE p_alphabet CHAR (26);
    DEFINE p_aLetter CHAR (1);
    DEFINE i, p_noOfLetters, p_rowNumber, p_direction INT;

    DEFINE p_line CHAR (40);

    LET p_alphabet = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
    LET p_aLetter = “A”;
    LET i = 1;

    — Work out which letter has been entered
    WHILE userInput != p_aLetter
    LET p_aLetter = substr(p_alphabet,i, i + 1);
    LET i = i + 1;
    END WHILE

    LET p_noOfLetters = i – 1;
    LET p_rowNumber = 0;
    LET p_direction = 1;
    LET p_line = “”;

    — First and last line
    WHILE p_rowNumber >= 0
    LET p_line = substr(p_line,0 , p_noOfLetters – p_rowNumber) || substr(p_alphabet, p_rowNumber, 1);

    — Top half of diamond
    IF p_rowNumber > 0 THEN
    LET p_line = substr(p_line,0 , p_noOfLetters – p_rowNumber) || substr(p_alphabet, p_rowNumber + 1, 1);
    LET p_line = substr(p_line,0, p_noOfLetters + p_rowNumber) || substr(p_alphabet, p_rowNumber + 1, 1);
    END IF

    — Bottom half of diamond
    IF p_rowNumber = p_noOfLetters – 1 THEN
    LET p_line = substr(p_line,0 , p_noOfLetters – p_rowNumber) || substr(p_alphabet, p_rowNumber + 1, 1);
    LET p_line = substr(p_line,0, p_noOfLetters + p_rowNumber) || substr(p_alphabet, p_rowNumber + 1, 1);
    LET p_direction = -1;
    END IF

    INSERT INTO t_diamond VALUES (p_line);

    LET p_line = “”;
    LET p_rowNumber = p_rowNumber + p_direction;

    END WHILE

    END PROCEDURE;

    EXECUTE PROCEDURE diamond(“E”);

    UNLOAD TO ‘diamond.txt’ DELIMITER ‘ ‘
    SELECT * FROM t_diamond;

    DROP TABLE t_diamond;

  6. Here’s another J entry implementation.

    seq=: i.&.(-&65)@>:&.(a.&i.)
    diam=: [: (,~ |.@}.)”1 [: ]/. (, ,.@}.)&.|.@seq

    example use (but remember to convert quotes back to single quotes).
    diam’B’

    note also, seq’E’ would produce the result
    ABCDE

    note that much the complexity of seq has to do with the structure of ascii — this would be somewhat simpler if the domain were numbers, with 0 being used for padding, instead of spaces.

  7. Alternatively the problem would be simpler (and the result more generic) if the entire sequence of letters were specified as input.

    I did not post any documentation, because this problem seems fairly simple and for the most part a person just needs to understand J’s primitives (http://www.jsoftware.com/help/dictionary/vocabul.htm) and grammar.

    However for people struggling with the language: (, ,.@}.)&.|.@seq ‘E’ produces an L shaped arrangement of letters, and ]/. rotates it 45 degrees, and (,~ |.@}.)”1 mirrors this half diamond to make a full diamond. The [: are, in essence, punctuation.

  8. Actually… ]/. mirrors and rotates in 45 degrees. Using . for some spaces to defeat html’s suppression of extraneous white space,

    (, ,.@}.)&.|.@seq ‘E’
    A
    B
    C
    D
    EDCBA

    ]/.(, ,.@}.)&.|.@seq ‘E’
    A
    .B
    ..C
    …D
    ….E
    …D
    ..C
    .B
    A

    To get an idea of the mirroring involved, here’s some incremental representations of the intermediate result:

    (, ,.@}.)seq ‘E’
    ABCDE
    B
    C
    D
    E
    (, ,.@}.)|.seq ‘E’
    EDCBA
    D
    C
    B
    A
    |.(, ,.@}.)|.seq ‘E’
    A
    B
    C
    D
    EDCBA

    But I use F&.|. instead |.F|. because the former is a single verb phrase while the latter is merely a run-on sequence of verbs.

    (Sorry, I should probably stop explaining, but I keep noticing areas where my initial treatment was inadequate.)

  9. @RDM – I am very grateful for your explanations as are other readers too I would imagine!

    Tracy Harms sent in the other J version that arrived via e-mail: (Iverson’s J programming language):

    3 :'(],|.@}:)(|.@}.”_1,.])(AB{~i.Y)(_2<\2#i.Y)}'' ''$~2#Y=.>:y(=i.1:)AB=.a.{~65+i.26′”0

    Stunning stuff!

  10. Another J solution:

    (,}.@|.)|:(|.,}.)(={“1′ ‘,.])’A'([+i.@-.@-)&.(a.&i.) ‘E’

    As RDM says, the majority of the complexity (i.e. code) results from the specification requiring textual (rather than numeric) i/o.

    If numeric i/o were permissible, this could be reduced to:

    (,}.@|.)|:(|.,}.)(*=)1+i. 5

    Whether this improvement is due to the spec’s bias towards text or J’s bias towards numbers is subjective, but I expect the textual and numeric solutions will be substantially equivalent in most languages, with the textual version carrying a slight overhead (in terms of code length).

    BTW, J is an array-oriented language, so it’s particularly suited for “these kind” of challenges. There are many ways to solve this puzzle in J, from the structural/descriptive, like above, to the imperative/instructive, which would explore the mathematical relationships hidden in the pattern.

    My preference is for the code to be descriptive: i.e. for the code to describe the pattern (as a human would), rather than imperative, instructing the computer to build the pattern using relationships among the indices.

  11. How strange, 🙁 as well as losing indents, submitting here cut out the middle of the line around the OR in the middle of is_letter() so do not try to run the above!!! Can I delete it if I find a safer formatter?

  12. A very slightly shorter solution is possible in APL dialects which support the “power” operator and “direct definition”: An anonymous function (the thing in curly braces on the left) which combines the “two halves” and transposes&reverses the result can be applied twice to the array containing letters along the diagonal to produce the final result:

    {⌽⍉⍵,0 1↓⌽⍵}⍣2⊃(-⍳⍴l)↑¨⌽l←(⎕A⍳’F’)↑⎕A

    This solution has the “cute” feature that if you replace the 2 by a 4 you get:

    _____A_________A_____
    ____B_B_______B_B____
    ___C___C_____C___C___
    __D_____D___D_____D__
    _E_______E_E_______E_
    F_________F_________F
    _E_______E_E_______E_
    __D_____D___D_____D__
    ___C___C_____C___C___
    ____B_B_______B_B____
    _____A_________A_____
    ____B_B_______B_B____
    ___C___C_____C___C___
    __D_____D___D_____D__
    _E_______E_E_______E_
    F_________F_________F
    _E_______E_E_______E_
    __D_____D___D_____D__
    ___C___C_____C___C___
    ____B_B_______B_B____
    _____A_________A_____

    (spaces replaced by underbars) I’ll spare y’all the results of using higher numbers than 4 🙂

  13. foo=: 3 : 0
    NB. Software courtesy of http://www.jsoftware.com
    NB. assignment to global facilitates analysis
    ALF =: ‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’
    a =: ALF i. y NB. position in ALF (‘E’ returns 4)
    b =: |i:a NB. 4 3 2 1 0 1 2 3 4
    c =: a-b NB. 0 1 2 3 4 3 2 1 0
    d =: c=/b NB. truth table
    e =: 1+2*a NB. arithmetic (value is 9)
    f =: ‘ ‘,:(e,e)$e#c{ALF NB. dyadic ,: is an interesting structural primitive
    d}f NB. This form of } is a marvelous KEI jewel.
    )

    foo’E’

  14. Ha ha ha … So many people have posted revolting code, I may as well do the same. At http://twitpic.com/3iuke you can see my A+ function rewritten into a single line. Horrible – variable assignment inside an indexing of the variable that’s just been assigned. I promise my production code would never do that! However, I have changed it to take case into account, so:

    dia¡’bCd’
    < a
    b b
    a
    < A
    B B
    C C
    B B
    A
    < a
    b b
    c c
    d d
    c c
    b b
    a

    🙂

  15. In Haskell. There is probably a more elegant way to implement the diamond’ function.

    import List (transpose)

    diamond :: Char -> String
    diamond = (unlines . mirror . transpose . mirror . diamond’)

    diamond’ :: Char -> [String]
    diamond’ c = zipWith pad [0..] chars
    where chars = reverse [‘A’..c]
    pad n m = pre n ++ [m] ++ post n
    pre n = replicate (length chars – 1 – n) ‘ ‘
    post n = replicate n ‘ ‘

    mirror :: [[a]] -> [[a]]
    mirror (n:ns) = (n ++ (tail . reverse) n) : zipWith (++) ns (map (tail . reverse) ns)

  16. I cannot but mention that some of the proposed implementations differ from the rest in what they do. For example, some produce a rectangular table rather than a ‘diamond’, or do not print their output, or do not read any input. However, a complete program, including all this properly done, might happen to increase 40-50% in volume precisely due to taking care of these details.
    Also, certain programs, although extremely small at first look, are only that small if sheer volume is measured, but are of ‘normal’ size – comparable to programs in other languages – if tokens are counted.

  17. I would not spend much time worrying about the handling of details which were not a part of the original problem specification:

    In my experience, when minor changes in the specification result in a vastly simplified application, changing the specification is usually a good idea.

    (Of course, programs which interface with other programs may have unbending requirements — but in those cases re-implementation is often a bad idea.)

    This gets into issues of ownership and responsibility and so on, but if you want your programs to be useful you should never neglect these issues.

    (Or, in the context of little contests like this one, I would usually just ignore issues which depend on the operating system and programming environment.)

  18. Boyko Bantchev,

    Apparently you understand the requirements to involve not printing spaces to the right of any of the output letters. This seems inaccurate and pointless, unless the point were to impose a handicap on languages in which a rectangular table is significantly easier.

    I do, however, agree that complete programs should both take any letter as input and print output, and that there are disadvantages to having programs that don’t weighed amidst those that do.

    I also agree that the best way to evaluate program size is by counting tokens, not characters.

  19. My previous note was meant to draw attention to the many differences in what the proposed solutions implement, because those differences make comparisons w.r.t., say, terseness, more or less meaningless.

    I myself perceive this challenge as an exercise in making apparent different possibilities – languages, algorithmic approaches – rather than a ‘contest’. So, using an interactive programming environment to save the need for explicit reading and printing is o.k., so long as the result is as expected. Similarly, outputting trailing spaces is o.k., so long as the result is seen as a ‘diamond’. (However, this is not always the case: e.g., one of the Haskell programs would print ” A\n B B\n A\n” rather than an A-B diamond; this is easy to get rid of, but would have required the author to submit a longer program.)

    Both adhering to a specification and changing it may be used as a means to show the good/bad points of a language and its environment. It’s just that the two kinds of solutions should not, as a rule, be compared to each other.

  20. @Boyko.

    prDiamond = do
    cs <- getLine
    putStrLn $ diamond (head cs)

    Happy? 🙂 On a more serious note, I like these programming challenges as they illustrate the differences in approach that one can take to solve a problem. This is particularly evident between the functional and imperative styles. I find the whole “I-can-write-it-in-fewer-characters-than-you” competition somewhat tiresome. I am much more interested in appreciating the underlying algorithm.

  21. Here’s q and k (closely related to APL, J, and A+):

    k){-1@’f@(f:{x,1_|x})’n$10h${((|x)#’32),’65+x}(!)n:-64+6h$x;}

    q){-1@’f(f:{x,1_reverse x})each n$10h${((reverse x)#’32),’65+x}til n:-64+6h$x;}

    sample runs:

    q){-1@’f(f:{x,1_reverse x})each n$10h${((reverse x)#’32),’65+x}til n:-64+6h$x;}”E”
    A
    B B
    C C
    D D
    E E
    D D
    C C
    B B
    A
    q)\
    {-1@’f@(f:{x,1_|x})’n$10h${((|x)#’32),’65+x}(!)n:-64+6h$x;}”E”
    A
    B B
    C C
    D D
    E E
    D D
    C C
    B B
    A

    (i’m not responsible for wordpress’s probably ruining of this post)

  22. A solution in Haskell, different from the one I posted before, along with other languages (http://pastebin.com/fbca102d).

    The d function produces one (the bottom-left) quarter q of the diamond, which is then reflected horizontally to produce h, and h is reflected vertically to produce the whole figure. d is recursive, building a square by gradually enlarging it from the left and the top.

    This solution is attractive by not needing anything explicitly related to the size of the figure or the encoding of characters as numbers (counting, subscripting, replicate, ord etc).

    import System(getArgs)
    main = do args <- getArgs
    let {h = zipWith (++) q (map (tail.reverse) q);
    q = d $ head $ head args;
    d c = if c==’A’ then [“A”] else (c:’ ‘:t) : map (‘ ‘:) r
    where r@((_:t):_) = d $ pred c
    } in putStr $ unlines (reverse h ++ tail h)

  23. Sorry for the previous post: it made use of the HTML tags CODE and PRE which the blog software does not treat properly, to say the least (although WordPress docs say otherwise).
    Please see a copy of that post here:
    http://pastebin.com/f4635515b

  24. A solution in JavaScript (within an HTML page):
    http://pastebin.com/d63f6cce4

    On loading the page, an A-Z half-diamond is built-up as an array
    of which, upon clicking a letter, a portion is being cut off,
    corresponding to that letter. The diamond() function – a click
    event listener – does the cutting and outputs the result to the page.

    Works in a normal browser, such as Firefox, but also in IE 🙂

  25. A solution in Object Pascal (Delphi). Things have changed, I’m now a C# guy now.

    program challenge;
    {$APPTYPE CONSOLE}
    uses
    SysUtils;
    var
    inputChar, current : char;
    begin
    Readln(inputChar);
    current := ‘A’;
    while current ‘A’ do
    begin
    current := chr(ord(current) – 1);
    if current = ‘A’ then
    Writeln(StringOfChar(‘ ‘, abs(ord(current) – ord(inputChar))) + ‘A’)
    else
    begin
    Write(StringOfChar(‘ ‘, abs(ord(current) – ord(inputChar))) + current);
    Writeln(StringOfChar(‘ ‘, abs(ord(‘A’) – ord(current)) * 2), current);
    end;
    end;
    Readln;
    end.

  26. i have added a QBasic solution. I did adjustments to make it look identical to the expected output. I used Qbasic from http://www.qbcafe.net/qbc/english/download/compiler/qbasic_compiler.shtml
    We wrote some games using QBasic. I miss those days.

    CLS
    PRINT “Enter Letter:”
    INPUT l$
    l$ = UCASE$(l$)

    col = ASC(l$) – ASC(“A”) + 1
    row = 0
    col2 = col – 1

    DO
    LOCATE row + 5, col: PRINT CHR$(ASC(“A”) + row)
    col2 = col2 + 1

    LOCATE row + 5, col2: PRINT CHR$(ASC(“A”) + row)
    col = col – 1
    row = row + 1

    LOOP WHILE col >= 1

    col = 1
    col2 = (ASC(l$) – ASC(“A”)) * 2 + 1
    DO
    LOCATE row + 5, col + 1: PRINT CHR$(ASC(l$) – col)
    col2 = col2 – 1

    LOCATE row + 5, col2: PRINT CHR$(ASC(l$) – col)
    col = col + 1
    row = row + 1

    LOOP WHILE col < ASC(l$) – ASC(“A”) + 1

  27. Maybe some cobol will do.

    identification division.
    program-id. diamond.

    environment division.
    data division.
    working-storage section.
    01 options.
    02 letter pic X occurs 26 times.
    02 inputletter pic X.
    77 a pic 99.
    77 colval pic 99.
    77 rowval pic 99.
    77 numitems pic 99.
    77 col2 pic 99.

    screen section.
    01 cls.
    02 blank screen.

    procedure division.

    main-prog section.
    para-a.
    perform populate;
    display cls.

    display “Enter Letter:”.
    accept inputletter, no beep.

    perform varying a from 1 by 1 until letter(a) = inputletter
    if not letter(a) = inputletter then
    add 1 to colval
    end-if
    end-perform.
    move colval to numitems.

    perform varying a from 1 by 1 until letter(a) = inputletter
    if not letter(a) = inputletter then
    display letter(a), line rowval, col colval
    move colval to col2
    add a to col2
    add a to col2
    subtract 2 from col2
    display letter(a), line rowval, col col2
    subtract 1 from colval
    add 1 to rowval
    end-if
    end-perform.

    perform varying a from numitems by -1 until a = 0
    display letter(a), line rowval, col colval
    move numitems to col2
    add a to col2
    subtract 1 from col2
    display letter(a), line rowval, col col2
    add 1 to colval
    add 1 to rowval
    end-perform.

    stop run.

    populate.
    move “A” to letter(1).
    move “B” to letter(2).
    move “C” to letter(3).
    move “D” to letter(4).
    move “E” to letter(5).
    move “F” to letter(6).
    move “G” to letter(7).
    move “H” to letter(8).
    move “I” to letter(9).
    move “J” to letter(10).
    move “K” to letter(11).
    move “L” to letter(12).
    move “M” to letter(13).
    move “N” to letter(14).
    move “O” to letter(15).
    move “P” to letter(16).
    move “Q” to letter(17).
    move “R” to letter(18).
    move “S” to letter(19).
    move “T” to letter(20).
    move “U” to letter(21).
    move “V” to letter(22).
    move “W” to letter(23).
    move “X” to letter(24).
    move “Y” to letter(25).
    move “Z” to letter(26).
    move 5 to rowval.
    move 1 to colval.

  28. Some plain old C++ that read the ending character from standard input:

    #include
    void p(char c){std::cout<‘A’){s(2*(c-‘A’)-1);p(c);}p(‘\n’);}
    int main()
    {
    char e,n(‘A’);std::cin.get(e);
    while(n=’A’)r(n–,e);
    }

    Nice challenge!

  29. Some plain old C++ that read the ending character from standard input:

    #include <iostream>
    void p(char c){std::cout<<c;}
    void s(int w){while(w–)p(‘ ‘);}
    void r(char c,char e){s(e-c);p(c);if(c>’A’){s(2*(c-‘A’)-1);p(c);}p(‘\n’);}
    int main()
    {
    char e,n(‘A’);std::cin.get(e);
    while(n<e)r(n++,e);while(n>=’A’)r(n–,e);
    }

    Nice challenge!

  30. Here is my C# offering. Nothing new. I see that the two key subtleties (the Abs and Substring) are found in previous entries. I wish I knew how to read them all. Maybe then I could find a job? Hmmmm? Naaah!

    char c = Console.ReadKey().KeyChar;
    int m = c – ‘A’;
    for(int n = m + m; n >= 0; n–) {
    int i = Math.Abs(n – m); // …, 2, 1, 0, 1, 2, …
    string s = new string((char)(‘A’ + m – i), 1); // A, B, …, B, A
    Console.WriteLine(s.PadLeft(i + 1) + s.PadLeft(2 * (m – i) + 1).Substring(1));
    }

  31. To Dan Bron:
    Your “numeric” version still can be easily translated to the required “letter”:

    a. {~ 32+(,}.@|.)|:(|.,}.)(*=)33+i.(64-~a.&i.) ‘E’

    Here is also my Haskell solution:

    sol e =
    let bl = inits $ repeat ‘ ‘
    qu = zipWith (++) bl $ reverse $ zipWith (:) [‘A’..e] bl
    ln = zipWith (++) qu $ map (tail.reverse) qu
    all = reverse ln ++ (tail ln)
    in unlines all

    main = do
    e <- getChar
    putStr $ sol e

  32. Hello,

    This is my Java version… Hope you like it guys=)

    Please email me at jayson_rq2d3@yahoo.com if you have problem with the code and please acknowledge me when using this code, and most importantly email me if you can optimize this code in java, I would really like to see your code. Thanks.

    System.exit(0); =)

    /*JAYSON P. ZANARIAS
    IV-BSCS, 19Yrs.Old
    */

    class Diamond{
    public static void main(String[]args){
    String alphabet = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;
    int index = alphabet.indexOf(args[0].toUpperCase());

    for(int j, k=-index; k<=index; k++){
    j = Math.abs(Math.abs(k)-index);
    for(int i=-index; i<=index; i++){
    if(i==j || i==-j)
    System.out.print(alphabet.charAt(j));
    else
    System.out.print(" ");
    if(i==index && k!=index)
    System.out.println();
    }
    }
    }
    }

  33. this is done in C in Linux. not a very efficient code for after printing the rightmost characters it still prints spaces to occupy the remaining length until it reaches the maximum length of the diamond:

    #include

    main(){
    int num, i, x, y;
    char input;
    char alpha[26] = “ABCDEFGHIJKLMNOPQRSTUVWXYZ”;

    printf(“Enter a character from a-z: “);
    input = toupper(getchar());

    for (i = 0; i < 26; i++){
    if (alpha[i] == input)
    num = i;
    }

    for (y = -num; y <= num; y++){
    for (x = -num; x <= num; x++){
    if (abs(x) + abs(y) == num)
    printf("%c", alpha[num-abs(y)]);
    else
    printf(" ");
    }
    printf("\n");
    }
    }

  34. #!/bin/bash

    j=0
    char=”${1:-E}”
    alphabet=( 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 )

    if [ “${char}” = “” -o “${char}” = “A” -o “${char}” = “${char/[A-Z]/}” ] ; then
    echo “USAGE: Specify an uppercase letter greater than A as in ${0} E” && exit
    fi

    for ((i=39;i>=1;i–,j++)) ; do
    output=”$( jot -b ‘ ‘ -s ” ${i} )”
    echo -n “${output}${alphabet[${j}]}”
    [ ${j} -gt 0 ] && echo “$( jot -b ‘ ‘ -s ” $((${j}*2-1)) )${alphabet[${j}]}” || echo
    [ “${alphabet[${j}]}” = “${char}” ] && break
    [ ${j} -ge 25 ] && j=$((j%25))
    done

    let j-=1

    for ((k=$(($i+1));k<=39;k++,j–)) ; do
    output="$( jot -b ' ' -s '' ${k} )"
    echo -n "${output}${alphabet[${j}]}"
    [ ${j} -gt 0 ] && echo "$( jot -b ' ' -s '' $((${j}*2-1)) )${alphabet[${j}]}" || echo
    [ ${j} -le 0 ] && j=25
    done

  35. Posting in the comments changes single and double quotes (somewhat randomly) and double dashes (‘”–“‘). Another marvel of modern computing, swell.

  36. This is a VB.NET console application:

    Module Module1

    Sub Main()
    Dim keyInfo As ConsoleKeyInfo = Nothing
    Dim wideChar As Char = ” “c
    Dim iA As Integer = 0, iB As Integer = 0
    Dim iX As Integer = 0

    Do
    Console.Write(“Input Widest Character: “)
    keyInfo = Console.ReadKey(True)
    With keyInfo
    If System.Char.IsLetter(.KeyChar) Then
    wideChar = .KeyChar.ToString.ToUpper
    Console.WriteLine(wideChar)
    End If
    End With
    Loop Until wideChar ” “c
    iA = Asc(“A”c)
    iB = Asc(wideChar)
    Console.WriteLine()
    For iX = iA To iB
    Console.WriteLine(Space(iB – iX + 1) & Chr(iX) & Space((iX – iA) * 2) & Chr(iX))
    Next
    For iX = iB – 1 To iA Step -1
    Console.WriteLine(Space(iB – iX + 1) & Chr(iX) & Space((iX – iA) * 2) & Chr(iX))
    Next
    Console.WriteLine()
    Console.Write(“Press Any Key”)
    Console.ReadKey()
    End
    End Sub

    End Module

Comments are closed.