Project Euler 32

7254は面白い性質を持っている. 39 × 186 = 7254と書け, 掛けられる数/掛ける数/積に1から9の数が1回ずつ出現する.
掛けられる数/掛ける数/積に1から9の数が1回ずつ出現するような積の総和を求めよ.
HINT: いくつかの積は, 1通り以上の掛けられる数/掛ける数/積の組み合わせを持つが1回だけ数え上げよ.

Mathematica

ans = {};
For[i = 1, i <= 10000, i++,
 For[j = i, j <= 10000, j++,
  tmp = i*j;
  If[tmp>10000, Break[]];
  A = Sort[
    Flatten[{IntegerDigits[i], IntegerDigits[j], IntegerDigits[tmp]}]];
  
  If[A == Table[i, {i, 9}] && MemberQ[ans, i*j] == False,
   Print[{i, j, i*j}];
   ans = Append[ans, i*j];
   ,
   {}]
  ]
 ]

まあ10000までループさせる必要なんかないですけどね。
10000の2重ループはとても危険な感じがしますが、

If[tmp>10000, Break[]];

の1行がうまく効いてくれてます。

C/C++

#include <iostream>
#include <deque>
#include <set>
using namespace std;

// xを各桁ごとにばらしてdequeに挿入する。
deque<int> integerDigit(int x){
	deque<int> arr;
	while(x!=0){
		arr.push_front(x%10);
		x/=10;
	}
	return arr;
}

// m, n, mn がpandigital(1から9が1回ずつ出現する)かどうかを判定する。
bool isPandigital(int m, int n, int mn){
	deque<int> num1, num2, num3;
	set<int> nums;

	num1 = integerDigit(m);
	num2 = integerDigit(n);
	num3 = integerDigit(mn);

	for(int i=0 ; i < (signed)num1.size() ; i++){
		nums.insert(num1[i]);
	}
	for(int i=0 ; i < (signed)num2.size() ; i++){
		nums.insert(num2[i]);
	}
	for(int i=0 ; i < (signed)num3.size() ; i++){
		nums.insert(num3[i]);
	}

	int s = nums.size();
	if(s != num1.size() + num2.size() + num3.size()) return false;

	set<int>::iterator it = nums.begin();
	if(s==9 && *it!=0) return true;
	else return false;
}

int main(){
	set<int> nums;

	for(int i=1; i<100 ; i++){
		for(int j=i ; j<10000 ; j++){
			if(i*j>10000) continue;
			if(isPandigital(i,j,i*j)){
				cout << i << "*" << j << "=" << i*j << endl; 
				nums.insert(i*j);
			}
		}
	}

	int sum=0;
	set<int>::iterator it = nums.begin();
	for(int i=0 ; i<(signed)nums.size() ; i++){
		sum += *it;
		it++;
	}
	
	cout << "sum -> " << sum << endl;
}

問題読んだ時点ではうわー、めんどくさーい・・・と思いましたが、やってみたら別段苦労する部分もなく。
冗長ですがそこまで遅いわけでもありません。