Challenge

Discuss Programming
Post Reply
Tux
guru
guru
Posts: 689
Joined: Wed Jan 08, 2003 10:40 am

Challenge

Post by Tux » Mon Aug 22, 2005 5:48 pm

This is a little programming challenge posed by TheQuirkat 'the other place'.
Next challenge:

Fill an n by n array in the following manner:

Image

For example, suppose that n = 3. Your program should create the following array:

[[1 2 3]
[8 9 4]
[7 6 5]]

I'd love to see a solution from you clever folk.

Tux
guru
guru
Posts: 689
Joined: Wed Jan 08, 2003 10:40 am

Post by Tux » Mon Aug 22, 2005 5:48 pm

I wanted to try this out myself but realised I had forgotten all of what I had ever known of C. :(
Instead I wrote a kludgy bash shell script to do the job!

Code: Select all

#!/bin/bash

echo -n "Enter n: "
read -e N;
MATRIX[0]='Results: \n'

Y=0
while [ $Y -le $[$N-1] ];do
	let "Y += 1"
	: $[POS_N = $[$N+1] * $Y]
	MATRIX[$POS_N]='\n'
done

TOP=2
BOT=$N
LEFT=1
RIGHT=$N
COL=1
ROW=1
VAL=1

ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
MATRIX[$ARR]=$VAL

: $((X = $N * $N))
until [ "$VAL" == "$X" ]
	do

until [ "$COL" == "$RIGHT" ]
	do
	let "COL += 1"
	let "VAL += 1"
	ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
	MATRIX[$ARR]=$VAL
	done

if [ "$COL" == "$RIGHT" ]; then
	if [ "$VAL" != "$X" ]; then
	let "RIGHT -= 1"
	let "ROW += 1"
	let "VAL += 1"
	ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
	MATRIX[$ARR]=$VAL
	fi
fi

until [ "$ROW" == "$BOT" ]
	do
	let "ROW += 1"
	let "VAL += 1"
	ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
	MATRIX[$ARR]=$VAL
	done

if [ "$ROW" == "$BOT" ]; then
	if [ "$VAL" != "$X" ]; then
	let "BOT -= 1"
	let "COL -= 1"
	let "VAL += 1"
	ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
	MATRIX[$ARR]=$VAL
	fi
fi

until [ "$COL" == "$LEFT" ]
	do
	let "COL -= 1"
	let "VAL += 1"
	ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
	MATRIX[$ARR]=$VAL
	done

if [ "$COL" == "$LEFT" ]; then
	if [ "$VAL" != "$X" ]; then
	let "LEFT += 1"
	let "ROW -= 1"
	let "VAL += 1"
	ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
	MATRIX[$ARR]=$VAL
	fi
fi

until [ "$ROW" == "$TOP" ]
	do
	let "ROW -= 1"
	let "VAL += 1"
	ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
	MATRIX[$ARR]=$VAL
	done

if [ "$ROW" == "$TOP" ]; then
	if [ "$VAL" != "$X" ]; then
	let "TOP += 1"
	let "COL += 1"
	let "VAL += 1"
	ARR=$[$COL + $[$[$N+1] * $[$ROW-1]]]
	MATRIX[$ARR]=$VAL
	fi
fi
done

for ((i=0;i<$[$X + $N + 1];i++)); do
  echo -en "\t${MATRIX[${i}]}"
done

Tux
guru
guru
Posts: 689
Joined: Wed Jan 08, 2003 10:40 am

Post by Tux » Fri Aug 26, 2005 6:19 pm

Nobody?

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Fri Aug 26, 2005 6:44 pm

I don't quite understand the question so there is no way I can come up with a solution. Remember, I'm a dirt biker. :)

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Fri Aug 26, 2005 8:04 pm

What you're supposed to do is write a program (probably in Perl for Void) that populates some arrays with values, but does it in a strange order. Getting a handle on the order is the hard part. Basically, your arrays, when printed, should follow the order of the drawing. Like, if n was 4, it would look like:
[01 02 03 04] = array element one
[12 13 14 05] = array element two
[11 16 15 06] = array element three
[10 09 08 07] = array element four

So you have one array, with n number of elements, and each element is an array with n number of elements. And the elements follow a pattern.


Actually, to be totally correct, the program should place them into the arrays in ordinal order - 5 should be the 5th element, etc. Tux's doesn't do this - but perhaps one day it will.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Fri Aug 26, 2005 8:15 pm

Still not quite sure I get it. Wouldn't you want to use a 2 dimensional array? I would actually probably use C. In fact if I figure out the question maybe I'll just use Pascal to throw you all off.

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Fri Aug 26, 2005 8:24 pm

The trick is to use an n-dimensional array, since you want to solve this for any given N.

Granted, the exercise has no real-world value, except as a thinking exercise. Tux's version is the only one I've seen that works.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Fri Aug 26, 2005 9:09 pm

Ok, I see the pattern now. I've been working on something else and couldn't put full attention on it. I still can't put full attention on it but at least I understand the question now (duh). I'll try and look at it sometime this weekend.

Tux
guru
guru
Posts: 689
Joined: Wed Jan 08, 2003 10:40 am

Post by Tux » Sat Aug 27, 2005 4:24 am

Void Main wrote:Ok, I see the pattern now. I've been working on something else and couldn't put full attention on it. I still can't put full attention on it but at least I understand the question now (duh). I'll try and look at it sometime this weekend.
Great!

I'd love to see how this is done. Properly.
Void Main wrote: Wouldn't you want to use a 2 dimensional array? I would actually probably use C.
Yeah, I think that's the way it's supposed to be done but bash doesn't seem to have them.

ZiaTioN
administrator
administrator
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm
Contact:

Post by ZiaTioN » Sat Aug 27, 2005 4:36 am

This was actually a little more difficult to hash out the logic then I thought it would be but here is my attempt in perl:

Code: Select all

#!/usr/bin/perl -w

use strict;

print "Enter n: ";
chomp(my $n = <>);

my @shiza;
my $firstD = my $secondD = 0;
my $cnt    = my $inc     = 1;


while ($cnt <= ($n*$n)) {
   while (!$shiza[$firstD][$secondD] && $secondD < $n && $inc == 1) {
      $shiza[$firstD][$secondD] = $cnt;
      $secondD++ unless($shiza[$firstD][$secondD+1] || ($secondD+1) >= $n);
      $cnt++;
   }
   $firstD++;

   while (!$shiza[$firstD][$secondD] && $firstD < $n && $inc == 1) {
      $shiza[$firstD][$secondD] = $cnt;
      $firstD++ unless($shiza[$firstD+1][$secondD] || ($firstD+1) >= $n);
      $cnt++;
   }
   $secondD--;
   $inc = 0;

   while (!$shiza[$firstD][$secondD] && $secondD >= 0 && $inc == 0) {
      $shiza[$firstD][$secondD] = $cnt;
      $secondD-- unless($shiza[$firstD][$secondD-1] || ($secondD-1) < 0);
      $cnt++;
   }
   $firstD--;

   while (!$shiza[$firstD][$secondD] && $firstD >= 0 && $inc == 0) {
      $shiza[$firstD][$secondD] = $cnt;
      $firstD-- unless($shiza[$firstD-1][$secondD] || ($firstD-1) < 0);
      $cnt++;
   }
   $secondD++;
   $inc = 1;
}

for (@shiza) {
   for (@{$_}) {
      print "$_\t" if($_);
   }
   print "\n";
}
Yes a two dimensional array is probably the best idea in the situation. At least that is what I used so I have to say it was the best method! LOL...

I am not quiet sure what worker is talking about when he stated something about "ordinal order" but I think my code above satisfies the challenge.

User avatar
Void Main
Site Admin
Site Admin
Posts: 5716
Joined: Wed Jan 08, 2003 5:24 am
Location: Tuxville, USA
Contact:

Post by Void Main » Sat Aug 27, 2005 4:51 pm

Heh heh, "for shiza". I like it fo zhiza! :) I hadn't seen that one before.

ZiaTioN
administrator
administrator
Posts: 460
Joined: Tue Apr 08, 2003 3:28 pm
Contact:

Post by ZiaTioN » Sat Aug 27, 2005 5:34 pm

If you can't work a little humor in the code then what is the point? :-)

I used to develop for a message board system and a couple of users actually came to the support forum one time to complain about the off color humor in the comments of the source code.

I did not write the comments but I thoguht they were humorous and could not see why someone would have an issue with it. I told them to not look at the source code if it offended them that much. LOL..

I mean come one, it is not like these comments were in the actual displayable text for the message board. Some people just need something to complain about to make themselves feel happy.

worker201
guru
guru
Posts: 668
Joined: Sun Jun 13, 2004 6:38 pm
Location: Hawaii

Post by worker201 » Sun Aug 28, 2005 4:12 pm

Mad props to ZiaTioN for solving this one in Perl!

Verified as correct with n=7.

Post Reply