第二回変なプログラマの作り方勉強会

いやはや、1週間放ってしまいました。

総評はだいたい皆さんが書いてらっしゃるので、今回は自分が発表した途中までのプレの続きを書きたいと思います。

「ありきたりな人が贈る、アリキタリなソート」

なるタイトルで本当にアリキタリな実装のソートを作りました。

#!/usr/bin/perl

use strict;
use Getopt::Long;

my $null = '';

my @fields;
my ($in, $out, $fs) = ('-', '-', "\t");

GetOptions(
		'--input=s' => \$in,
		'--output=s' => \$out,
		'--field-separator|s=s' => \$fs,
		'--fields|f=i' => \@fields,
	);
	
open IN, "<$in" or die "Error in opening input stream : $in ".$!;

our $comp;

if ($fields[0] =~ m/\d/) {
	$comp = sub (@@) {
		my $a = $_[0];
		my $b = $_[1];
		foreach (@fields) {
			my $ret = ($$a[$_-1] cmp $$b[$_-1]);
			return $ret if $ret != 0;
		}
		return join($fs, @$a) cmp join($fs, @$b);
	};
} else {
	$comp = sub (@@) {
		my $a = shift;
		my $b = shift;
		return join($fs, @$a) cmp join($fs, @$b);
	};
}

my $head = {};

foreach (<IN>) {
	my @indata = split($fs, $_);
	my $leaf = $head;
	for ( ;$leaf->{data}; ) {
		my $ret = &$comp(\@indata, $leaf->{data});
		if ($ret < 0) {
			$leaf->{lessNode}={} if !$leaf->{lessNode};
			$leaf = $leaf->{lessNode};
		} else {
			$leaf->{greatNode}={} if !$leaf->{greatNode};
			$leaf = $leaf->{greatNode};
		}
	}
	$leaf->{data} = \@indata;
}

close IN;

open OUT, ">$out" or die "Error in opening output stream : ".$!;

print &printNodes($head);

close OUT;

sub printNodes {
	my $leaf = $_[0];
	my $left = '';
	my $right = '';

	if ($leaf->{lessNode}) {
		$left = &printNodes($leaf->{lessNode});
	}
	
	if ($leaf->{greatNode}) {
		$right = &printNodes($leaf->{greatNode});
	}
	
	return $left.join($fs, @{$leaf->{data}}).$right;
}

とりあえず。 続きは夜を待たれい。