配列の順列並べ替えを全て計算する

by 9re forked from わざと偏りをつけたランダムな配列の並び替え (diff: 124)
基本的なuiお借りします
♥0 | Line 85 | Modified 2009-10-08 12:51:45 | MIT License
play

ActionScript3 source code

/**
 * Copyright 9re ( http://wonderfl.net/user/9re )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/c3Vf
 */

// forked from nemu90kWw's 1行でArrayをシャッフルする

// 基本的なuiお借りします

package
{
	import flash.display.*;
	import flash.text.*;
	import flash.events.*;
	import com.adobe.serialization.json.JSON;

	[SWF(width="465", height="465", backgroundColor="#ffffff")]
	public class Permutation extends Sprite
	{
		private var textfield:TextField = new TextField();
		private var input:TextField = new TextField();
		private var button:Sprite = new Sprite();
		private var buttontext:TextField = new TextField();
		
		function Permutation()
		{
			var tf:TextField = new TextField();
			tf.defaultTextFormat = new TextFormat("_等幅");
			tf.text = "arr = ";
			tf.x = 10;
			tf.y = 13;
			addChild(tf);
			
			input = new TextField();
			input.type = TextFieldType.INPUT;
			input.border = true;
			input.borderColor = 0x999999;
			input.text = '["A", "B", "C", "D"]';
			input.x = 50;
			input.y = 10;
			input.width = 120;
			input.height = 20;
			addChild(input);
			
			textfield.x = 10;
			textfield.y = 60;
			textfield.width = 465 - 20;
			textfield.height = 465 - 50;
			textfield.wordWrap = true;
			textfield.defaultTextFormat = tf.getTextFormat();
			
			addChild(textfield);
			
			button.x = 300;
			button.y = 10;
			button.mouseChildren = false;
			button.buttonMode = true;
			button.graphics.lineStyle(1, 0xBBBBBB);
			button.graphics.beginFill(0xEEEEEE);
			button.graphics.drawRoundRect(0, 0, 100, 20, 5, 5);
			button.graphics.endFill();
			addChild(button);
			
			buttontext = new TextField();
			buttontext.width = 100;
			buttontext.height = 20;
			buttontext.htmlText = "<p align='center'><font face='_sans'>再計算</span></p>";
			button.addChild(buttontext);
			
			button.addEventListener(MouseEvent.CLICK, function(e:Event):void{test();});
			test();
		}
		
		private function test():void
		{
			var result:Array = permutation(JSON.decode(input.text));
			textfield.text = "arrの順列並べ替え:" + result.length + "通り\n\n" + JSON.encode(result);
			return;
		}
		
		/**
		 * @param	arr [1, 2, 3]などの配列を渡す
		 * @return arrの順列を要素に持つ配列。arr=[1,2]なら[[1,2],[2,1]]
		 */
		private function permutation(arr:Array):Array {
			var res:Array = [];
			switch (arr.length) {
			case 0:
				res.push([]);
				break;
			default:
				arr.forEach(function (i:int, j:int, a:Array):void {
					res = res.concat(unshiftElementToEachArray(i, permutation(removeIndexAt(j, a))));
				});
			}
			return res;
		}
		
		/**
		 * @param	index
		 * @param	array
		 * @return arrayのindex番目だけの要素を取り除いた配列を返す
		 */
		private function removeIndexAt(index:*, array:Array):Array {
			return  array.slice(0, index).concat(array.slice(index + 1));
		}
		
		/**
		 * @param	element 追加する要素
		 * @param	array 配列の配列
		 * @return arrayに入っている配列全てに最初にelementを追加した配列を返す
		 */
		private function unshiftElementToEachArray(element:*, array:Array):Array {
			return array.map(function(eachArray:Array, i:int, a:Array):Array {
				eachArray.unshift(element);
				
				return eachArray;
			});
		}

	}
}