#!/usr/bin/perl -w

use v5.16;

package IntComp;

sub new {
	my ($class, $mem, $inputs) = @_;
	my $self = {
		mem => [ @$mem ],
		pc  => 0,
		want_input => undef,
	};
	$self->{inputs} = [ @$inputs ]
		if defined $inputs;
	bless $self, $class;
}

sub m2val {
	my ($self, $off, $mode) = @_;
	if ($mode == 0) {
		return $self->{mem}->[ $self->{mem}->[$self->{pc} + $off] ];
	} elsif ($mode == 1) {
		return $self->{mem}->[$self->{pc} + $off];
	}
}

sub input {
	my ($self, @input) = @_;
	push @{ $self->{inputs} }, @input;
}

sub run {
	my ($self, @input) = @_;
	my $mem = $self->{mem};

	push @{ $self->{inputs} }, @input;
	if (defined $self->{want_input}) {
		$mem->[$self->{want_input}] = shift @{ $self->{inputs} };
		$self->{want_input} = undef;
	}

	while (1) {
		my $opcode = $mem->[$self->{pc}];
		say "pc=", $self->{pc}, " opcode=$opcode";
		say "mem=", join(',', @{ $self->{mem} });
		my $op = int($opcode % 100);
		my $m1 = int($opcode / 100) % 10;
		my $m2 = int($opcode / 1000) % 10;
		if ($op == 1) {
			$mem->[ $mem->[$self->{pc}+3] ]
				= m2val($self, 1, $m1)
				+ m2val($self, 2, $m2);
			$self->{pc} += 4;
		} elsif ($op == 2) {
			$mem->[ $mem->[$self->{pc}+3] ]
				= m2val($self, 1, $m1)
				* m2val($self, 2, $m2);
			$self->{pc} += 4;
		} elsif ($op == 3) {
			if (@{ $self->{inputs} }) {
				$mem->[ $mem->[$self->{pc} + 1] ]
					= shift @{ $self->{inputs} };
				$self->{pc} += 2;
			} else {
				$self->{want_input} = $self->{pc} + 1;
				$self->{pc} += 2;
				return undef;
			}
		} elsif ($op == 4) {
			my $val = m2val($self, 1, $m1);
			$self->{pc} += 2;
			return $val;
		} elsif ($op == 5) {
			if (m2val($self, 1, $m1)) {
				$self->{pc} = m2val($self, 2, $m2);
			} else {
				$self->{pc} += 3;
			}
		} elsif ($op == 6) {
			if (!m2val($self, 1, $m1)) {
				$self->{pc} = m2val($self, 2, $m2);
			} else {
				$self->{pc} += 3;
			}
		} elsif ($op == 7) {
			$mem->[ $mem->[$self->{pc}+3] ] =
				m2val($self, 1, $m1)
				< m2val($self, 2, $m2) ? 1 : 0;
			$self->{pc} += 4;
		} elsif ($op == 8) {
			$mem->[ $mem->[$self->{pc}+3] ] =
				m2val($self, 1, $m1)
				== m2val($self, 2, $m2) ? 1 : 0;
			$self->{pc} += 4;
		} elsif ($op == 99) {
			return undef;
		}
	}
}

package main;

chomp (my @mem = split /,/, <>);

my $max;
sub run_all {
	my @perm = @_;
	my @interps;

	for my $p (@perm) {
		push @interps, IntComp->new(\@mem, [ $p ]);
	}

	my $last_rv;
	my $rv = 0;
	ROUND:
	while (1) {
		say "Starting from 0";
		for my $int (@interps) {
			if (defined $rv) {
				$int->input($rv);
			}
			$rv = $int->run;
			say "Interp returned ", $rv // '_';
			next ROUND if !defined $rv && $int->{want_input};
		}
		if (defined $rv) {
			say "Loop returned $rv";
			$last_rv = $rv;
			next ROUND;
		}
		last if !defined $rv;
	}
	return $last_rv;
}

my $max = 0;
sub permute {
	my ($rem, $used) = @_;
	for my $i (0 .. $#$rem) {
		my @nr = @$rem;
		my @in = ($nr[$i], @$used);
		splice(@nr, $i, 1);
		
		if (@nr) {
			permute(\@nr, \@in);
		} else {
			say "Running with perm ", join(',', @in);
			my $rv = run_all(@in);
			say $rv;
			$max = $rv if $max < $rv;
		}
	}
}

permute([ 5 .. 9 ], []);

say $max;

