Project Euler 106

by uwi
@see http://projecteuler.net/index.php?section=problems&id=106
♥0 | Line 63 | Modified 2009-07-11 22:22:22 | MIT License
play

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/jtL5
 */

package {
    import flash.display.Sprite;
    import flash.text.TextField;
    import flash.utils.getTimer;
    // @see http://projecteuler.net/index.php?section=problems&id=106
    public class Euler106 extends Sprite {
        private var _tf : TextField;
  
        public function Euler106() {
            _tf = new TextField();
            _tf.width = 465;
            _tf.height = 465;
            addChild(_tf);
            
            var s : int = getTimer();
            _tf.appendText("" + solve(12) + "\n");
//            _tf.appendText("" + nTest(4, 2) + "\n");
            var g : int = getTimer();
            _tf.appendText("" + (g - s) + " ms\n");
        }
        
        // kを2からn/2まで動かす。
        // 元集合からとった、要素数k個の互いにdisjointな2個のsubsetの組について、
        // subsetそれぞれを昇順にソートして、
        // 小さい方から順に互いのsubsetの要素を比較したときに
        // すべてが同じ比較結果にはならないものをカウントしていく。
        private function solve(n : int) : int
        {
            var s : int = 0;
            var i : int;
            for(i = 2;i <= n / 2;i++){
                s += nTest(n, i);
            }
            return s;
        }
        
        private var _used : Array;
        private var _pos0 : int;
        
        private function nTest(n : int, k : int) : int
        {
            _used = new Array(n);
            for(var i : int = 0;i < n;i++)_used[i] = 0; 
            return enum(n, k, 0, 0);
        }
        
        private function enum(n : int, k : int, phase : int, pos : int) : int
        {
            var i : int;
            if(phase == 2 * k){
                var a : Array = [];
                var b : Array = [];
                for(i = 0;i < _used.length;i++){
                    if(_used[i] == 1)a.push(i);
                    if(_used[i] == 2)b.push(i);
                }
                // if a < b or a > b for all element, return 0, if else return 1.
                var s : int = 0;
                for(i = 0;i < a.length;i++){
                    s += a[i] < b[i] ? -1 : 1;
                }
//                _tf.appendText("" + a + "\t" + b + "\t" + s + "\n");
                return (s == a.length || s == -a.length) ? 0 : 1;
            }
            if(phase == k)pos = _pos0 + 1;
            
            var sum : int = 0;
            var v : int = 1 + phase / k;
            for(i = pos;i < n;i++){
                if(_used[i] == 1)continue;
                _used[i] = v;
                if(phase == 0)_pos0 = i;
                sum += enum(n, k, phase + 1, i + 1);
                _used[i] = 0;
            }
            return sum;
        }
    }
}