0

我制作了一个程序,它将接收 5 个数字,并将使用前四个来获取第五个数字作为解决方案。解只能包含正整数,并且唯一可接受的运算符是“+ - * /”。有 11 种不同的方式可以用括号排列数字和运算符。例如 "(n @ n) @ n @ n" 其中 n 代表数字,@ 代表运算符。

我找到所有解决方案都没有问题,我的问题是删除“重复项”。我已经能够使用删除大多数重复项

%Seen = ();
@solutions = grep { ! $Seen{ $_ }++ } @solutions;

但是我无法找到删除“重复”公式的方法。

在删除第一个重复项后,使用 21 14 2 7 获得 34 为我们提供了 4 个解决方案。他们来了

21/7=3; 14+3=17; 2*17=34
21/7=3; 3+14=17; 2*17=34
21/7=3; 3+14=17; 17*2=34
21/7=3; 14+3=17; 17*2=34

我的老师认为这些在数学上是相同的,因此所有四个都只是一种解决方案。我不知道该怎么做是找到这些“重复”并删除它们。任何帮助表示赞赏,谢谢。

4

2 回答 2

3

例如,对于交换运算,只考虑x @ ywhere x <= y。这种方式,2 * 17是可能的,但17 * 2不是。

于 2013-02-08T20:07:12.077 回答
3

您使用的重复数据删除代码的更通用形式是

grep !$seen{key($_)}++, ...

在这种情况下,key将是

sub key {
   ( my $key = $_[0] ) =~ s/(\d+)([*+])(\d+)/ $1 < $3 ? "$1$2$3" : "$3$2$1" /eg;
   return $key;
}

在您的情况下,您可能想先简单地标准化您的输入

sub normalise(_) {
   ( my $s = $_[0] ) =~ s/(\d+)([*+])(\d+)/ $1 < $3 ? "$1$2$3" : "$3$2$1" /eg;
   return $s;
}

@solutions = grep !$seen{$_}++, map normalise, @solutions;
于 2013-02-08T20:29:43.970 回答