#!/usr/bin/perl -w

use v5.30;
use strict;

local $/ = "\n\n";

my @is_op = (65535) x 16;

my $total = 0;
while(<>) {
	chomp;
	last if !length;

	my @nums = /(\d+)/g;
	my @before = @nums[0..3];
	my ($op, $a, $b, $c) = @nums[4..7];
	my @after  = @nums[8..11];
	my $match = 0;

	print join(' ', @nums), "\n";
	# addr
	$is_op[$op] &= ~(1 << 0) unless ($before[$a] + $before[$b] == $after[$c]);
	# addi
	$is_op[$op] &= ~(1 << 1) unless ($before[$a] + $b == $after[$c]);
	# mulr
	$is_op[$op] &= ~(1 << 2) unless ($before[$a] * $before[$b] == $after[$c]);
	# muli
	$is_op[$op] &= ~(1 << 3) unless ($before[$a] * $b == $after[$c]);
	# bandr
	$is_op[$op] &= ~(1 << 4) unless (($before[$a] & $before[$b]) == $after[$c]);
	# bandi
	$is_op[$op] &= ~(1 << 5) unless (($before[$a] & $b) == $after[$c]);
	# borr
	$is_op[$op] &= ~(1 << 6) unless (($before[$a] | $before[$b]) == $after[$c]);
	# bori
	$is_op[$op] &= ~(1 << 7) unless (($before[$a] | $b) == $after[$c]);
	# setr
	$is_op[$op] &= ~(1 << 8) unless ($before[$a] == $after[$c]);
	# seti
	$is_op[$op] &= ~(1 << 9) unless ($a == $after[$c]);
	# gtir
	$is_op[$op] &= ~(1 << 10) unless (($a > $before[$b] ? 1 : 0) == $after[$c]);
	# gtri
	$is_op[$op] &= ~(1 << 11) unless (($before[$a] > $b ? 1 : 0) == $after[$c]);
	# gtrr
	$is_op[$op] &= ~(1 << 12) unless (($before[$a] > $before[$b] ? 1 : 0) == $after[$c]);
	# eqir
	$is_op[$op] &= ~(1 << 13) unless (($a == $before[$b] ? 1 : 0) == $after[$c]);
	# eqri
	$is_op[$op] &= ~(1 << 14) unless (($before[$a] == $b ? 1 : 0) == $after[$c]);
	# eqrr
	$is_op[$op] &= ~(1 << 15) unless (($before[$a] == $before[$b] ? 1 : 0) == $after[$c]);
	print join(' ', map { sprintf("%04x", $_) } @is_op), "\n";
}

my %is_2n = map { (1 << $_) => 1 } 0 .. 15;

my %done_2n;
my $modified = 1;
while ($modified) {
	say join(" ", map { sprintf("%04x", $_) } @is_op);
	$modified = 0;
	for my $try (0 .. 15) {
		next if $done_2n{$try};
		next if !$is_2n{$is_op[$try]};
		print "Unique: $try: $is_op[$try]\n";
		$done_2n{$try} = 1;
		$modified = 1;
		for my $other (0 .. 15) {
			next if $done_2n{$other};
			$is_op[$other] &= ~$is_op[$try];
		}
	}
}

my @op_trans;
for my $op (0 .. 15) {
	for my $l (0 .. 15) {
		next if (1 << $l) != $is_op[$op];
		print "$op => $l\n";
		$op_trans[$op] = $l;
	}
}

local $/ = "\n";
my @regs = (0) x 4;
while (<>) {
	my ($op, $a, $b, $c) = /(\d+)/g;
	say "$op $a $b $c ", join(' ', @regs);

	# addr
	$regs[$c] = $regs[$a] + $regs[$b] if $op_trans[$op] == 0;
	# addi
	$regs[$c] = $regs[$a] + $b if $op_trans[$op] == 1;
	# mulr
	$regs[$c] = $regs[$a] * $regs[$b] if $op_trans[$op] == 2;
	# muli
	$regs[$c] = $regs[$a] * $b if $op_trans[$op] == 3;
	# bandr
	$regs[$c] = ($regs[$a] & $regs[$b]) if $op_trans[$op] == 4;
	# bandi
	$regs[$c] = ($regs[$a] & $b) if $op_trans[$op] == 5;
	# borr
	$regs[$c] = ($regs[$a] | $regs[$b]) if $op_trans[$op] == 6;
	# bori
	$regs[$c] = ($regs[$a] | $b) if $op_trans[$op] == 7;
	# setr
	$regs[$c] = $regs[$a] if $op_trans[$op] == 8;
	# seti
	$regs[$c] = $a if $op_trans[$op] == 9;
	# gtir
	$regs[$c] = ($a > $regs[$b] ? 1 : 0) if $op_trans[$op] == 10;
	# gtri
	$regs[$c] = ($regs[$a] > $b ? 1 : 0) if $op_trans[$op] == 11;
	# gtrr
	$regs[$c] = ($regs[$a] > $regs[$b] ? 1 : 0) if $op_trans[$op] == 12;
	# eqir
	$regs[$c] = ($a == $regs[$b] ? 1 : 0) if $op_trans[$op] == 13;
	# eqri
	$regs[$c] = ($regs[$a] == $b ? 1 : 0) if $op_trans[$op] == 14;
	# eqrr
	$regs[$c] = ($regs[$a] == $regs[$b] ? 1 : 0) if $op_trans[$op] == 15;
}

say $regs[0];

