[Rt-devel] RT DEVELOPER CHALLENGE: TOWER OF HANOI

Jesse Vincent jesse at bestpractical.com
Tue Oct 26 14:50:06 EDT 2004


I'm impressed :) You win.   May I add this to the Wiki?


	Best,
	Jesse
On Oct 25, 2004, at 9:47 PM, Bron Gondwana wrote:

>
> On Sat, 23 Oct 2004 03:33:20 -0400, "Jesse Vincent"
> <jesse at bestpractical.com> said:
>> Perhaps it's the fault of the delicious bottle of Port that a 
>> houseguest
>> brought me, but I've got a challenge for the RT community.
>>
>> The first person to develop and document a solution to the famed Tower
>> of Hanoi puzzle[1] using RT's Scrips system with queues modeling the
>> rods, tickets modeling the disks and ticket relationships modeling the
>> relative disk sizes will win a fabulous prize.[2]
>
> I've made a couple of them, but they suck for various reasons.
> Basically
> it's hard to make them sort correctly, because it takes forever if you
> put
> a 'sleep 1' in, but otherwise (at least with Mysql's dates) they don't
> sort
> properly.
>
> Anyway, here's one that's pretty chatty, but gets the moves in the
> correct
> order txn-wise.
>
> The Scrip:
> ===============================================================
>
> Condition: On Comment
>
> Action: User Defined
>
> Prepration Code: (<< __EOF__)
> my $comment = $self->TransactionObj->Content();
>
> if ($comment =~ m/move to ([A-Za-z0-9_ ]+)/) {
>   my $new_queue_match = lc($1);
>   $new_queue_match =~ s/^\s+//;
>   $new_queue_match =~ s/\s+$//;
>
>   my $user = $self->TransactionObj->CurrentUser();
>   my $old_queue_id = $self->TicketObj->Queue();
>
>   # Find a third queue to use as temporary space for this move.
>   my $queues = RT::Queues->new($user);
>   $queues->UnLimit();
>   my $queue_items = $queues->ItemsArrayRef;
>
>   my %queue_names;
>   my $temp_queue_id;
>   my $new_queue_id;
>   foreach my $item (@$queue_items) {
>     my $id = $item->id;
>     my $name = $item->Name;
>     my $matchname = lc($name);
>     $matchname =~ s/^\s+//;
>     $matchname =~ s/\s+$//;
>     $queue_names{$id} = $name;
>     if ($id == $old_queue_id) {
>       # nothing to do
>     } elsif ($new_queue_match eq $matchname) {
>       $new_queue_id = $id;
>     } elsif (!$temp_queue_id) {
>       $temp_queue_id = $id;
>     }
>   }
>
>   # make sure a move is actually required (the case of trying to move 
> to
>   where
>   # we already are will leave this blank as well)
>   return 0 unless $new_queue_id;
>
>   # the next smaller disk is our member.
>   my $members = $self->TicketObj->Members->ItemsArrayRef;
>   if (@$members) {
>     # make sure there's spare space to move this thing!
>     return 0 unless $temp_queue_id;
>     my $child_obj = RT::Ticket->new($user);
>     $child_obj->Load($members->[0]->LocalBase);
>     if ($child_obj->Queue != $temp_queue_id) {
>       $child_obj->Comment(Content => "move to
>       $queue_names{$temp_queue_id}");
>     }
>     $self->TicketObj->SetQueue($new_queue_id);
>     $child_obj->Comment(Content => "move to
>     $queue_names{$new_queue_id}");
>   } else {
>     # no children, just move ourselves!
>     $self->TicketObj->SetQueue($new_queue_id);
>   }
>   return 1;
> }
>
> return 0;
> __EOF__
>
> Cleanup Code: return 1;
>
> Stage: TransactionCreate
>
> ===============================================================
>
> How to use:
>
> a) Have at least 3 queues available.
> b) Create tickets with a Parent/Child relationship (Parent is the 
> larger
> disk)
> c) Create a comment on the largest disk "move to <name of another
> queue>".
>
> All the other disks will be moved as appropriate.
>
> NOTE: There is no concept of 'stacking' in RT queues, so the disks are
> assumed to
> be stacked correctly at the start since there's no way of detecting
> otherwise.
>
> The script won't move a disc until the immediately smaller disk is on
> the a third
> stack (not the source or destination of the first move) - and that
> propagates up
> to the top disk which has no children and hence can always move.
>
> I still think this solution is rather ugly, but it works.
>
> Bron.
> -- 
>   Bron Gondwana
>   brong at fastmail.fm
>



More information about the Rt-devel mailing list