The parentheses in the "hard" expression represent order of evaluation. Rather than trying to generate the displayed form directly, just come up with a list of operators in random order, and derive the display form of the expression from that.
Numbers: 1 3 3 9 7 2
Operators: + * / + *
Result: ((1 + 3) * 3 / 9 + 7) * 2
Deriving the display form is a relatively simple recursive algorithm.
Update: here is an algorithm in Perl to generate the display form. It displays the components ofBecause + and * are distributive, it randomizes the expression in a random order (without changingof the value), so thatterms for those operators. That helps keep the parentheses don't always endfrom all building up on the leftone side.
use warnings;
use strict;
sub build_expression
{
my ($num,$op) = @_;
#Start with the final term.
my $last_num = pop @$num;
my $last_op = pop @$op;
#Base case: return the number if there is just a number
return $last_num unless defined $last_op;
#Recursively call for the expression minus the final term.
my $rest = build_expression($num,$op);
#Add parentheses if there is a bare + or - and this term is * or /
$rest = "($rest)" if ($rest =~ /[+-][^)]+$|^[^)]+[+-]/ and $last_op !~ /[+-]/);
#Return the two components in a random order for + or *.
return $last_op =~ m|[-/]| || rand(2) >= 1 ?
"$rest $last_op $last_num" : "$last_num $last_op $rest";
}
my @numbers = qw/1 3 4 3 9 7 2 1 10/;
my @operators = qw|+ + * / + * * +|;
print build_expression([@numbers],[@operators]) , "\n";