Project Euler 170
@see http://projecteuler.net/index.php?section=problems&id=170
♥0 |
Line 156 |
Modified 2010-06-25 10:26:07 |
MIT License
archived:2017-03-20 06:43:33
ActionScript3 source code
/**
* Copyright uwi ( http://wonderfl.net/user/uwi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/9jV7
*/
package {
import flash.display.Sprite;
import flash.text.TextField;
import flash.utils.getTimer;
// @see http://projecteuler.net/index.php?section=problems&id=170
public class Euler170 extends Sprite {
private var _tf : TextField;
public function Euler170() {
_tf = new TextField();
_tf.width = 465;
_tf.height = 465;
addChild(_tf);
var s : int = getTimer();
tr(solve());
var g : int = getTimer();
tr((g - s) + " ms");
}
// concatenated productの最上位の数字cを決めて、そこから、
// ab = cとなるa,bを探す。そのあとa,b以外のinputと、
// c以外のoutputを埋める組み合わせをみつける。
// productの最大値を見つければよいため、
// cの最上位の数字は9となるようにする。(98としてもよい)
private function solve() : Number
{
var i : uint, j : uint, k : uint;
for(i = 1023;i >= 1;i--){
var a : Vector.<uint> = new Vector.<uint>();
for(j = 0, k = i;j < 10;j++, k>>=1){
if(k & 1)a.push(j);
}
if(a.length >= 8)continue;
for(;a != null; a = nextPermutation(a)){
if(a[0] != 9)continue;
// if(a.length > 1 && a[1] != 8)continue;
calcOrg(a);
}
}
tr(_ct);
return Number(_gopt);
}
private var _ct : uint = 0;
private var _gopt : String = "";
private function calcOrg(a : Vector.<uint>) : void
{
var ai : Number = 0;
var code : uint = 0;
for each(var e : uint in a){
ai = ai * 10 + e;
code |= 1 << e;
}
if(_gopt.substr(0, ai.toString().length) > ai.toString())return;
for(var i : uint = 2;i * i < ai;i++){
if(ai % i == 0){
var du : uint = isDup(i, ai / i);
if(du == 0)continue;
var li : String;
li = ai + lookup(i, du, code);
if(li.length == 10){
tr(ai, i, li);
if(li > _gopt)_gopt = li;
_ct++;
}
li = ai + lookup(ai / i, du, code);
if(li.length == 10){
tr(ai, ai / i, li);
if(li > _gopt)_gopt = li;
_ct++;
}
}
}
}
private function isDup(...args : Array) : uint
{
var c : uint = 0;
for each(var a : uint in args){
while(a > 0){
if(c & (1 << (a % 10)))return 0;
c |= 1 << (a % 10);
a /= 10;
}
}
return c;
}
private function lookup(base : uint, src : uint, dst : uint) : String
{
var ob : Object = {};
var gct : uint = 0;
var i : int, j : int, k : int;
var ord : Array = [];
for(k = 1;k < 1024;k++){
if(src & k)continue;
var a : Vector.<uint> = new Vector.<uint>();
for(i = 0, j = k;i < 10;i++, j>>=1){
if((j & 1) == 1){
a.push(i);
}
}
outera:
for(;a != null; a = nextPermutation(a)){
if(a[0] == 0)continue;
var aa : uint = dec(a);
var count : uint = dst;
for(var r : Number = base * aa;r > 0;r = Math.floor(r / 10)){
var c : uint = 1 << (r % 10);
if(count & c)continue outera;
count |= c;
}
ord.push({mul : base * aa, src : k, dst : count ^ dst});
gct++;
}
}
// tr(base, gct);
ord.push({mul : 0, src : 1, dst : 1});
ord.sortOn("mul", Array.DESCENDING);
opt = "";
rec(ord, src, dst, "", 0);
return opt;
}
private var opt : String = "";
// src, dstどちらも1023にする
private function rec(ord : Array, src : uint, dst : uint, prev : String, depth : uint) : void
{
for(var i : uint = 0;i < ord.length;i++){
if(src & ord[i].src)continue;
if(dst & ord[i].dst)continue;
var nsrc : uint = src | ord[i].src;
var ndst : uint = dst | ord[i].dst;
var cur : String = prev + ord[i].mul;
if(nsrc != 1023 && ndst != 1023 && cur >= opt.substr(0, cur.length)){
rec(ord, nsrc, ndst, cur, depth + 1);
}
if(nsrc == 1023 && ndst == 1023){
if(cur > opt){
opt = cur;
}
}
}
}
private function dec(v : Vector.<uint>) : uint
{
var ret : uint = 0;
for each(var u : int in v){
ret = ret * 10 + u;
}
return ret;
}
private function nextPermutation(src : Vector.<uint>) : Vector.<uint>
{
for(var i : int = src.length - 2;i >= 0 && src[i] > src[i + 1];i--);
if(i == -1)return null;
for(var j : uint = i + 1;j < src.length && src[i] < src[j];j++);
var d : uint;
d = src[i]; src[i] = src[j - 1]; src[j - 1] = d;
for(var p : uint = i + 1, q : uint = src.length - 1;p < q;p++, q--){
d = src[p]; src[p] = src[q]; src[q] = d;
}
return src;
}
private function tr(...o : Array) : void
{
_tf.appendText(o + "\n");
_tf.scrollV = _tf.maxScrollV;
}
}
}