Programming Challenge – Original Pascal Submission

Earlier this week I set a Programming Challenge using an example from my first year in academia. So far it has attracted 60 or so comments and solutions!

I’m particularly impressed with the range of languages that have been used.

Regular day-to-day offerings in C# are there, C# with LINQ, PowerShell and VBScript. “Vanilla” C, C++, Perl, Ruby and Python aren’t left out; neither are Smalltalk, Haskall, Lisp, clojure, Scala, F#, T-SQL, Informix SQL, SyBase SQL, APL, APL2 and A+. 6502 machine code and Excel are in the submission pot to – extreme diamond plotting!

There are even submissions in Octave and J (references here and here)!

I’ve had offers of solutions in JavaScript and jQuery, hopefully they’ll arrive soon!

I haven’t verified it yet, but here’s one of the J solutions, stunningly terse:

It is written in 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

by Tracy Harms

That won me “most cryptic” tweet from Stuart!

Naturally I’m pleased, I wasn’t expecting it to be so popular! Huge thanks to all involved so far!

For the sake of completion, I’ve scanned in the original Pascal submission. Here it is:

Oh dear: notice the scandalous indentation after the FOR loop. Cringe.

If I was to write a C# version of the Pascal code, I might end up with something similar to this:


using System;

namespace diamond
{
class Program
{
static void Main(string[] args)
{
char widest_char;
int next_char, finish_char, wide, range, direction, position, spacelength, loop;

widest_char = Console.ReadKey().KeyChar;
Console.WriteLine();

wide = (int)widest_char;
direction = 1;
spacelength = 1;
position = 1;

next_char = 66;
finish_char = 65;

range = 2 * (wide - finish_char);

// Calculate initial left indent
int mid = wide - 65 + 1;

String firstLetter = Char.ToString((char)finish_char);
firstLetter=firstLetter.PadLeft(mid+1);
Console.WriteLine(firstLetter);

for (loop = 1; loop < range; loop++) { Console.Write(" ".PadLeft(mid - position)); Console.Write((char)next_char); Console.Write(" ".PadLeft(spacelength)); Console.WriteLine((char)next_char); next_char = next_char + (1 * direction); position = position + (1 * direction); spacelength = spacelength + (2 * direction); // Flip direction when the middle of the diamond is reached if (next_char == wide) direction = -1; } Console.WriteLine(firstLetter); Console.ReadLine(); } } }

Back in 1988, I was reasonably pleased with the Pascal solution. Looking at it now, there are a few things I'd probably change, however hindsight with experience is a wonderful thing.

I can't remember how long it took me to write the Pascal version, probably not very long as I had prototyped the solution using BBC Basic V - a programming language that I had been using since I was 13...some five years before I set eyes on the diamond plotter task! I can't recall exactly, but I'm reasonably sure that the BBC Basic version took me about an hour to get working...

Of course, throwing readability, etc. out of the window, were I thinking about writing a similar solution today in 2009, I might find myself writing something similar to this:


using System;

namespace ConsoleApplication5
{
class Program
{
static void Main()
{
int range = Console.ReadKey().KeyChar - 65;
Console.Clear();

Console.WriteLine(String.Format("{0}A", "".PadLeft(range)));
int r = 1, dir = 1;
while ((r > 0) && (range>0))
{
char c = Convert.ToChar(r + 65);
Console.WriteLine(String.Format("{0}{1}{2}{3}", "".PadLeft(range - r),
c, "".PadLeft(r + (r - 1)), c));
if (r == range) dir = -1;
r = r + dir;
}
Console.WriteLine(String.Format("{0}A", "".PadLeft(range)));

Console.ReadKey();
}
}
}

How long did it take me to write a solution today? 30 minutes. 10 minutes of which were spent strangely refactoring for fewer lines of code and terseness. It was interesting writing this version, readability and ability to follow the work-flow came through in the initial version. Then the desire to strip it back to the very basics caught up with me. It's still not perfect, but it does the job. That said, I'm not sure my original Pascal tutor would be hugely happy with it! C'est la vie!

I'll write another post that brings together all the submissions that I've received so far - keep them coming!

4 thoughts on “Programming Challenge – Original Pascal Submission”

  1. Glad you liked my entry, Craig, but I do think it worth mentioning that it seems to me the weakest of the J entries. It was definitely nice to see such a variety of J and APL solutions. As is often the case when working with these languages, the different phrasings make for inspiring and instructive reading.

    Were I going to be using this program on a longer-term basis, I’d probably structure it across several lines with comments, like this:


    diamond=: 3 : 0 "0
    AB=.a.{~65+i.26 NB. alphabet
    Y=.>:y(=i.1:)AB NB. letter count
    dg=.(AB{~i.Y)(_2<\2#i.Y)}' '$~2#Y NB. letters on diagonal
    (],|.@}:) (|.@}."_1,.]) dg NB. trimmed reflection on both axes
    )

    The most obvious weakness in my solution is the use of forks instead of hooks for joining after reflection. Also. the reliance on Amend (}) is rather ham-handed.

    Ric Sherlock posted a nicely refined version of a solution here: http://jsoftware.com/pipermail/programming/2009-April/014417.html

Comments are closed.