IWETHEY v. 0.3.0 | TODO
1,095 registered users | 1 active user | 0 LpH | Statistics
Login | Create New User
IWETHEY Banner

Welcome to IWETHEY!

New No luck on #2
I gave up and found a solution on the Net. After looking at it for a while, I still can't say I grok it. I don't quite see how the author can be sure that he exausted every possible combination (although I see why he thinks so). Also, the solution does not allow for unary "-". Would you let me look at yours?

As to more optimization - I could not do it w/o sacrificing that readability and compactness. I could use more C instead of STL, but that would be reinventing the wheel. I think it's good enough as is.
Expand Edited by Arkadiy Jan. 29, 2002, 09:36:02 AM EST
New You can skip the - very easily
There is a complete and utter symmetry of positive and negative at the numbers you can reach in all of the calculations. Noticing and using this means that if you only consider calculations with non-negative pairs of numbers that will result in non-negative numbers, you get a factor of 4 reduction in combinations of pairs of numbers, and have shorter sets of expressions to include.

This ties directly into the fact that there is no need to consider every possible expression. You merely need to be sure that you visit every possible value. (Or actually every non-negative value.)

For the Perl solution you also have to assume that floating point round-off is not going to rear its ugly head. This is true, but proving it is non-trivial.

The following solution is not my fastest in Perl, but it is not too far off and has the benefit that with a -v argument you get told the expressions leading to smaller numbers. Note that Perl is an extremely poor solution for this problem because it spends a lot of time doing number-string conversions. (As is seen by the fact that building up the actual string expressions is relatively little extra work.)

(BTW Scott, I loathe my workaround for the extra returns...)


#! /usr/bin/perl
use strict;
use Getopt::Std;
getopts('v');
use vars qw($opt_v @find_in);

# Set up my array of hashes of how to find various numbers with
# n 9's.
@find_in =(
{}, # None of size 0!
{ 9 => '9' }, # 2 with 1 9
map {}, 2..9
);

foreach my $i (1..9) {
print "Searching depth $i\\n" if $opt_v;
my $find_in_a = $find_in[$i];

foreach my $j (1..$i) {
next if 9 < $i + $j;
print " Searching combinations of $i, $j\\n" if $opt_v;

my $find_in_b = $find_in[$j];
my $find_in_sum = $find_in[ $i+$j ];

foreach my $val_a (keys %$find_in_a) {
my $expr_a = $find_in_a->{$val_a};

foreach my $val_b (keys %$find_in_b) {
my $expr_b = $find_in_b->{$val_b};

$find_in_sum->{$val_a + $val_b} ||= "($expr_a + $expr_b)";
$find_in_sum->{$val_a * $val_b} ||= "($expr_a * $expr_b)";
\tif ($val_a < $val_b) {
$find_in_sum->{$val_b - $val_a} ||= "($expr_b - $expr_a)";
\t}
\telse {
$find_in_sum->{$val_a - $val_b} ||= "($expr_a - $expr_b)";
\t}
if (0 != $val_b) {
$find_in_sum->{$val_a / $val_b} ||= "($expr_a / $expr_b)";
}
if (0 != $val_a) {
$find_in_sum->{$val_b / $val_a} ||= "($expr_b / $expr_a)";
}
}
}
}
}

my $ans = 1;
while (exists $find_in[9]{$ans}) {
print "$ans\\t$find_in[9]{$ans}\\n" if $opt_v;
$ans++;
}
print "ANSWER: $ans\\n";


Cheers,
Ben
New That's the part I can't see
Yes, I get that inverting signs gives you symmetric values. But how about mixing signs? If you mix positive and negative nines, you may reach some numbers unreacheable any other way. E.g., suppose we limit ourselves to +, - and () only. Then 0 will be unreacheable w/o using unary minus.

Also, for a value that you cannot produce, you need to be sure that you exhausted all possible approches, no?

I guess I just suck at number theory...
New May be I can see, after all :)
The way you handle binary '-' must be the key. This way, any use of unary minus can be expressed through binary one.
New Right
Here are two ways to see it.

The first is to note that if you apply unary - to an expression it can always be distributed into the expression. Either into the first term (case of * and /) or across both terms (+ and binary -). Therefore in any expression with unary -'s comes out to the same answer (after mechanical operations) as one where the only unary -'s are applied to individual terms. In other words you are building up expressions out of 9 and -9. But that just establishes the symmetry that I used to avoid having to consider negative numbers, so I ignore the -9.

The second is even slicker. You agree with the symmetry note? Then I only need to consider operations with non-negative numbers that come out to non-negative answers. Every expression involving 2 non-negative numbers comes out to something that is either on my list, or that is negative, or that gives the same value as something on my list.

In short, the unary - is useful because it establishes the symmetry. And once established, it turns out you never need to look at the unary -. (Actually it turns out to be a red herring. While the symmetry is relatively easily spotted, all you really need to know is that the set of negative values you can reach with n 9's is a subset of the set of negatives of positive values you can reach with n 9's.)

Cheers,
Ben
     Fun-looking stuff in Boston - (ben_tilly) - (18)
         Re: Fun-looking stuff in Boston - (Arkadiy) - (16)
             Nope, the correct answer has length 15 - (ben_tilly) - (15)
                 Oh shit! - (Arkadiy) - (14)
                     Heh - (ben_tilly) - (13)
                         OK, I know what you did. - (Arkadiy)
                         Fixed. - (Arkadiy) - (11)
                             I wouldn't count on that - (ben_tilly) - (10)
                                 Re: I wouldn't count on that - (Arkadiy)
                                 Big improvement! - (Arkadiy)
                                 Used STLport - (Arkadiy)
                                 STL + hash_map - (Arkadiy) - (6)
                                     See? I said that Perl was slow and bloated! - (ben_tilly) - (5)
                                         No luck on #2 - (Arkadiy) - (4)
                                             You can skip the - very easily - (ben_tilly) - (3)
                                                 That's the part I can't see - (Arkadiy) - (2)
                                                     May be I can see, after all :) - (Arkadiy) - (1)
                                                         Right - (ben_tilly)
         Certainly an interesting approach - (wharris2)

Yes, no, maybe so.
55 ms