#!/usr/bin/perl
use 5.016;
use warnings;
no warnings qw(once);
use List::Util qw(reduce);

package _Stream;

sub new {
	my $class = shift;
	return bless [ @_ ], $class;
}

sub value { $_[0]->[0] }
sub next { ref $_[0]->[1] eq 'CODE' ? $_[0]->[1] = $_[0]->[1]->() : $_[0]->[1] }


package main;

sub top { _Stream->new(shift, undef) }

sub f {
	my ($n, $l, $p) = @_;

	return _Stream->new(
		$p->value * 10 + $l->[$n],
		sub {
			(($n + 1) > $#{$l}) ?
				(defined $p->next ? f(0, $l, $p->next) : undef) :
				f($n + 1, $l, $p)
		}
	);
}

sub _f {
	my ($b, $n) = @_;

	return ($n < 1 ?
		top($b) :
		f(
			0,
			($b == 9 ? [2 .. 9, 1] : [1 .. 9]),
			reduce{ f(0, [0 .. 9], $a) } (top($b), 2 .. $n)
		)
	);
}

sub g {
	my ($b, $n, $f) = @_;

	return _Stream->new(
		$f->value,
		sub {
			(not defined $f->next) ?
				g($b, $n + 1, _f($b, $n + 1)) :
				g($b, $n, $f->next)
		}
	);
}

sub h {
	my ($n, @g) = @_;

	return _Stream->new(
		$g[$n]->value,
		sub{
			h(
				$g[$n]->value % 10,
				@g[0 .. $n - 1],
				$g[$n]->next,
				@g[$n + 1 .. $#g]
			)
		}
	);
}

my $h = h(1, map{ g($_, 0, _f($_, 0)) } (0 .. 9));
my $i = $h->value;
while($i < 1001){
	$i = $h->value;
	$h = $h->next;
	print $i, ' ';
}
