JavaScript - Hard copying primitive - javascript
I'm trying to copy a variable to a new one, NOT by reference, but by hard copy. In my understanding, JavaScript does a hard copy of primitive types by default. However, I get a reference copy if I do it like this:
var u = [0, 12, 34, 56];
var v = u[1];
u[1] = 85;
console.log(v); // returns 85, I want it to return 12
So I guess u[1] isn't a primitive type, after all (even though it's just a 12, which is a number, which should be primitive in my understanding). Is there a way I can make a hard copy? I've tried severeal methods I've found here. v = u[1].slice() seems to be the obvious choice, it doesn't work however, and there has to be an easier method for this than the 20 line custom functions some advise.
Thank you for your help!
EDIT: Apparently it works this way, so here's more of the code(without some unimportant parts):
var G = [[1, 2, 34, 56],[2, 345, 67, 8],[3, 4],[4, 65, 87]...]; // G contains 99 entries originally
var v;
var u;
var m = 99;
var alt;
var n = edges.length;
G[0].l = 0;
u = G[0].slice(); // now u = [1, 2, 34, 56]
u.l = G[0].l;
//... ...(some code not doing anything with v and u)
for (i = 1; i < ( u.length - 1 ) ; i++) {
alt = u.l + 1;
console.log(u[i]);
v = u[i];
u[i] = 9999999; //this is for testing if v is the ith of u or not
for( j = 0; j < m; j++) {
if(G[j][0] == v) {
if ( alt < G[j].l ){
Res[j].l = alt;
Res[j].previous = u;
}
}
}
for( j = 0; j < m; j++) {
if(G[j][0] == v) {
if ( alt < G[j].l ){
G[j].l = alt;
G[j].previous = u;
}
}
}
}
return v; //returns 9999999 instead of anythign from the original u, or G for that matter
Well these two lines are inside of a loop:
from your fiddle https://jsfiddle.net/7vjf82oa/1
//reduced to the core problem
while(/*whatever*/){
for(var i=1; i<u.length-1; ++i){
v = u[i];
u[i] = 9999999; //this is for testing if v is the ith of u or not
}
}
return v;
you overwrite the values in the first itertion and access them in any further one.
What are you trying to achieve with your code? It seems messed up in so many ways. Maybe we can help to solve the underlying problem.
Like this part:
for ( k = 0; k < m ; k++ ) {
if ( G[k].l < min ) {
mini = G[k][0];
u = G[mini].slice();
u.l = G[mini].l;
}
}
G.splice(mini, 1);
m--;
mini = 0;
mini seems to reference the index-position of something min.
The way you build G, G[k][0] would reference the index-Position inside of G, and mini = G[k][0] could be replaced as mini = k, except that since you remove Elements from G the indices are completely messed up, so that referencing u = G[mini].slice() would result in some sort of fancy shuffle.
Except for the fact that the surrounding condition can never be true. why?
G[/*any*/].l is initialized as Infinite.
u.l is initialized as 0 and counting up.
G[0].l = 0;
u = G[0].slice();
u.l = G[0].l;
//...
alt = u.l + 1;
//...
G[j].l = alt;
min is initialized as 0 and is never changed.
neither 0..99 nor Infinite can ever be lower than 0
so that G.splice(mini, 1); is just a substitute for G.shift();
so again, what are you trying to build? maybe we can help
if you want to clone an object or deep copy ,
there is a few ways to do it.
function clone(a) {
return JSON.parse(JSON.stringify(a));
}
Related
How to load a multidimensional array using for loop in JS?
[just joined. first post \o/] I'm working on a 'battleblocks' project idea of mine to help learn JS, where I have a 10x10 css grid of dynamically created divs. They are identifiable from numbers 1 to 100, reading left to right (row 1 has 1,2,3..10, row 2 has 11,12..20 etc). I need to be able to have a nested array of columns that house 10x arrays (columnArray[0] contains 1,11,21..91 - columnArray[1] contains 2,12,22..92 etc). And the same for rows - a row array that has 10x row arrays (rowArray[0] contains 1,2,3..10 - rowArray[1] contains 11,12,13..20 etc). Ive declared column array globally, but as it stands whatever ive done so far causes a 'aw, snap! something went wrong while displaying this webpage.' error. loadColsArray(); // load column arrays function loadColsArray() { let rowsAr = []; let count = 0; for (let c = 1; c <= 10; c++) { for (let r = 0; r <= 100; r + 10) { rowsAr[count] = c + r; count++; } columnArray[c - 1] = rowsAr; count = 0; rowsAr = []; } console.log(columnArray); } Any help appreciated. ps: added code as a snippet, because 'code sample' option broke up my pasted code.
There are a few problems in your code: The "Aw Snap" is caused by an infinite loop in your code which occurs because you never increment r. You must use r += 10 to increment it by 10. Since you initialise r to 0, your exit condition must be r < 100, otherwise 11 iterations will occur. You also need to define columnArray before you use it (it's not defined in the snippet). Try this: let columnArray = []; // ← loadColsArray(); // load column arrays function loadColsArray() { let rowsAr = []; let count = 0; for (let c = 1; c <= 10; c++) { for (let r = 0; r < 100; r += 10) { // ← rowsAr[count] = c + r; count++; } columnArray[c - 1] = rowsAr; count = 0; rowsAr = []; } console.log(columnArray); }
JS check if the value of object exists
So, I have following js setup: var NAMES = []; function INFO(id,first,middle,last){ var newMap = {}; newMap[id] = [first, middle, last]; return newMap ; } Then, for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values var my_name = all_names[j]; // has "185, 185, 185" if (NAMES[my_name] !== 185){ //Needs to check here NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd")); }else{ } } alert(JSON.stringify(NAMES , null, 4)); Here is a screenshot of the alert: I hardcoded the number "185" for this example. I need to check if the id of 185 exists, then skip to else. I am not sure how to check it. I tried typeof, undefinedetc. but no luck. (In other words, I should only have one "185"). Any help? Thanks!
If I understood correctly what you are trying to achieve, you have to iterate over NAMES and check every element. For example, you could do it using [].some javascript function: if (!NAMES.some(function(v){return v[my_name]})) { ... } else { }
If you want to remove duplication you can just use NAMES as an object instead of array like this var all_names = [185, 185, 181], NAMES = {}; for (var j = 0; j < all_names.length; j++) { //let say it there are three values var my_name = all_names[j]; // has "185, 185, 185" NAMES[my_name] = ["sean","sdfsd","sdfsfd"]; } alert(JSON.stringify(NAMES, null, 4));
First of all I would recommend making a JS Fiddle or CodePen out of this so people can see the code running. I believe that the issue is that NAMES[my_name] is not doing what you think it is. NAMES is an Array so when you say NAMES[my_name] you are really asking for the ITEM in the array so you are getting the entire object that you create in the INFO function. What you really want is to see if the object has an attribute that matches the value (e.g. "185" from the my_names array). This is not the prettiest code but it will show you how to do what you really want to do: var NAMES = []; function INFO(id,first,middle,last){ var newMap = {}; newMap[id] = [first, middle, last]; return newMap ; } all_names = ["185", "186", "185"] for (var j = 0; j < all_names.length; j++) { var my_name = all_names[j]; if (NAMES.length == 0) { NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd")); } else { var match = false; for (var x = 0; x < NAMES.length; x++) { console.log(NAMES[x][my_name] + ' : ' + my_name); if(NAMES[x][my_name]) { match = true; } } if (!match) { NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd")); } } } alert(JSON.stringify(NAMES , null, 4)); Note the if that looks at NAMES[x][my_name] - this is asking if the item at array index 'x' has an attribute of 'my_name' (e.g. "185"). I believe this is really what you are trying to do. As its after midnight I assure you that there is more concise and pretty JS to do this but this should show you the basic issue you have to address.
Try this code using hasOwnProperty method : for (var j = 0; j < NUMBER.length; j++) { //let say it there are three values var my_name = all_names[j]; // has "185, 185, 185" if (!NAMES[my_name].hasOwnProperty("185")){ //Needs to check here NAMES.push(INFO(my_name,"sean","sdfsd","sdfsfd")); }else{ } }
Efficiently find every combination of assigning smaller bins to larger bins
Let's say I have 7 small bins, each bin has the following number of marbles in it: var smallBins = [1, 5, 10, 20, 30, 4, 10]; I assign these small bins to 2 large bins, each with the following maximum capacity: var largeBins = [40, 50]; I want to find EVERY combination of how the small bins can be distributed across the big bins without exceeding capacity (eg put small bins #4,#5 in large bin #2, the rest in #1). Constraints: Each small bin must be assigned to a large bin. A large bin can be left empty This problem is easy to solve in O(n^m) O(2^n) time (see below): just try every combination and if capacity is not exceeded, save the solution. I'd like something faster, that can handle a variable number of bins. What obscure graph theory algorithm can I use to reduce the search space? //Brute force var smallBins = [1, 5, 10, 20, 30, 4, 10]; var largeBins = [40, 50]; function getLegitCombos(smallBins, largeBins) { var legitCombos = []; var assignmentArr = new Uint32Array(smallBins.length); var i = smallBins.length-1; while (true) { var isValid = validate(assignmentArr, smallBins, largeBins); if (isValid) legitCombos.push(new Uint32Array(assignmentArr)); var allDone = increment(assignmentArr, largeBins.length,i); if (allDone === true) break; } return legitCombos; } function increment(assignmentArr, max, i) { while (i >= 0) { if (++assignmentArr[i] >= max) { assignmentArr[i] = 0; i--; } else { return i; } } return true; } function validate(assignmentArr, smallBins, largeBins) { var totals = new Uint32Array(largeBins.length); for (var i = 0; i < smallBins.length; i++) { var assignedBin = assignmentArr[i]; totals[assignedBin] += smallBins[i]; if (totals[assignedBin] > largeBins[assignedBin]) { return false; } } return true; } getLegitCombos(smallBins, largeBins);
Here's my cumbersome recursive attempt to avoid duplicates and exit early from too large sums. The function assumes duplicate elements as well as bin sizes are presented grouped and counted in the input. Rather than place each element in each bin, each element is placed in only one of duplicate bins; and each element with duplicates is partitioned distinctly. For example, in my results, the combination, [[[1,10,20]],[[4,5,10,30]]] appears once; while in the SAS example in Leo's answer, twice: once as IN[1]={1,3,4} IN[2]={2,5,6,7} and again as IN[1]={1,4,7} IN[2]={2,3,5,6}. Can't vouch for efficiency or smooth-running, however, as it is hardly tested. Perhaps stacking the calls rather than recursing could weigh lighter on the browser. JavaScript code: function f (as,bs){ // i is the current element index, c its count; // l is the lower-bound index of partitioned element function _f(i,c,l,sums,res){ for (var j=l; j<sums.length; j++){ // find next available duplicate bin to place the element in var k=0; while (sums[j][k] + as[i][0] > bs[j][0]){ k++; } // a place for the element was found if (sums[j][k] !== undefined){ var temp = JSON.stringify(sums), _sums = JSON.parse(temp); _sums[j][k] += as[i][0]; temp = JSON.stringify(res); var _res = JSON.parse(temp); _res[j][k].push(as[i][0]); // all elements were placed if (i == as.length - 1 && c == 1){ result.push(_res); return; // duplicate elements were partitioned, continue to next element } else if (c == 1){ _f(i + 1,as[i + 1][1],0,_sums,_res); // otherwise, continue partitioning the same element with duplicates } else { _f(i,c - 1,j,_sums,_res); } } } } // initiate variables for the recursion var sums = [], res = [] result = []; for (var i=0; i<bs.length; i++){ sums[i] = []; res[i] = []; for (var j=0; j<bs[i][1]; j++){ sums[i][j] = 0; res[i][j] = []; } } _f(0,as[0][1],0,sums,res); return result; } Output: console.log(JSON.stringify(f([[1,1],[4,1],[5,1],[10,2],[20,1],[30,1]], [[40,1],[50,1]]))); /* [[[[1,4,5,10,10]],[[20,30]]],[[[1,4,5,10,20]],[[10,30]]],[[[1,4,5,20]],[[10,10,30]]] ,[[[1,4,5,30]],[[10,10,20]]],[[[1,4,10,20]],[[5,10,30]]],[[[1,4,30]],[[5,10,10,20]]] ,[[[1,5,10,20]],[[4,10,30]]],[[[1,5,30]],[[4,10,10,20]]],[[[1,10,20]],[[4,5,10,30]]] ,[[[1,30]],[[4,5,10,10,20]]],[[[4,5,10,20]],[[1,10,30]]],[[[4,5,30]],[[1,10,10,20]]] ,[[[4,10,20]],[[1,5,10,30]]],[[[4,30]],[[1,5,10,10,20]]],[[[5,10,20]],[[1,4,10,30]]] ,[[[5,30]],[[1,4,10,10,20]]],[[[10,10,20]],[[1,4,5,30]]],[[[10,20]],[[1,4,5,10,30]]] ,[[[10,30]],[[1,4,5,10,20]]],[[[30]],[[1,4,5,10,10,20]]]] */ console.log(JSON.stringify(f([[1,1],[4,1],[5,1],[10,2],[20,1],[30,1]], [[20,2],[50,1]]))); /* [[[[1,4,5,10],[10]],[[20,30]]],[[[1,4,5,10],[20]],[[10,30]]],[[[1,4,5],[20]],[[10,10,30]]] ,[[[1,4,10],[20]],[[5,10,30]]],[[[1,5,10],[20]],[[4,10,30]]],[[[1,10],[20]],[[4,5,10,30]]] ,[[[4,5,10],[20]],[[1,10,30]]],[[[4,10],[20]],[[1,5,10,30]]],[[[5,10],[20]],[[1,4,10,30]]] ,[[[10,10],[20]],[[1,4,5,30]]],[[[10],[20]],[[1,4,5,10,30]]]] */ Here's a second, simpler version that only attempts to terminate the thread when an element cannot be placed: function f (as,bs){ var stack = [], sums = [], res = [] result = []; for (var i=0; i<bs.length; i++){ res[i] = []; sums[i] = 0; } stack.push([0,sums,res]); while (stack[0] !== undefined){ var params = stack.pop(), i = params[0], sums = params[1], res = params[2]; for (var j=0; j<sums.length; j++){ if (sums[j] + as[i] <= bs[j]){ var _sums = sums.slice(); _sums[j] += as[i]; var temp = JSON.stringify(res); var _res = JSON.parse(temp); _res[j].push(i); if (i == as.length - 1){ result.push(_res); } else { stack.push([i + 1,_sums,_res]); } } } } return result; } Output: var r = f([1,5,10,20,30,4,10,3,4,5,1,1,2],[40,50,30]); console.log(r.length) console.log(JSON.stringify(f([1,4,5,10,10,20,30], [40,50]))); 162137 [[[30],[1,4,5,10,10,20]],[[10,30],[1,4,5,10,20]],[[10,20],[1,4,5,10,30]] ,[[10,30],[1,4,5,10,20]],[[10,20],[1,4,5,10,30]],[[10,10,20],[1,4,5,30]] ,[[5,30],[1,4,10,10,20]],[[5,10,20],[1,4,10,30]],[[5,10,20],[1,4,10,30]] ,[[4,30],[1,5,10,10,20]],[[4,10,20],[1,5,10,30]],[[4,10,20],[1,5,10,30]] ,[[4,5,30],[1,10,10,20]],[[4,5,10,20],[1,10,30]],[[4,5,10,20],[1,10,30]] ,[[1,30],[4,5,10,10,20]],[[1,10,20],[4,5,10,30]],[[1,10,20],[4,5,10,30]] ,[[1,5,30],[4,10,10,20]],[[1,5,10,20],[4,10,30]],[[1,5,10,20],[4,10,30]] ,[[1,4,30],[5,10,10,20]],[[1,4,10,20],[5,10,30]],[[1,4,10,20],[5,10,30]] ,[[1,4,5,30],[10,10,20]],[[1,4,5,20],[10,10,30]],[[1,4,5,10,20],[10,30]] ,[[1,4,5,10,20],[10,30]],[[1,4,5,10,10],[20,30]]]
This problem is seen often enough that most Constraint Logic Programming systems include a predicate to model it explicitly. In OPTMODEL and CLP, we call it pack: proc optmodel; set SMALL init 1 .. 7, LARGE init 1 .. 2; num size {SMALL} init [1 5 10 20 30 4 10]; num capacity{LARGE} init [40 50]; var WhichBin {i in SMALL} integer >= 1 <= card(LARGE); var SpaceUsed{i in LARGE} integer >= 0 <= capacity[i]; con pack( WhichBin, size, SpaceUsed ); solve with clp / findall; num soli; set IN{li in LARGE} = {si in SMALL: WhichBin[si].sol[soli] = li}; do soli = 1 .. _nsol_; put IN[*]=; end; quit; This code produces all the solutions in 0.06 seconds on my laptop: IN[1]={1,2,3,4,6} IN[2]={5,7} IN[1]={1,2,3,4} IN[2]={5,6,7} IN[1]={1,2,3,6,7} IN[2]={4,5} IN[1]={1,2,5,6} IN[2]={3,4,7} IN[1]={1,2,5} IN[2]={3,4,6,7} IN[1]={1,2,4,6,7} IN[2]={3,5} IN[1]={1,2,4,7} IN[2]={3,5,6} IN[1]={1,2,4,6} IN[2]={3,5,7} IN[1]={1,3,4,6} IN[2]={2,5,7} IN[1]={1,3,4} IN[2]={2,5,6,7} IN[1]={1,5,6} IN[2]={2,3,4,7} IN[1]={1,5} IN[2]={2,3,4,6,7} IN[1]={1,4,6,7} IN[2]={2,3,5} IN[1]={1,4,7} IN[2]={2,3,5,6} IN[1]={2,3,4,6} IN[2]={1,5,7} IN[1]={2,3,4} IN[2]={1,5,6,7} IN[1]={2,5,6} IN[2]={1,3,4,7} IN[1]={2,5} IN[2]={1,3,4,6,7} IN[1]={2,4,6,7} IN[2]={1,3,5} IN[1]={2,4,7} IN[2]={1,3,5,6} IN[1]={3,5} IN[2]={1,2,4,6,7} IN[1]={3,4,7} IN[2]={1,2,5,6} IN[1]={3,4,6} IN[2]={1,2,5,7} IN[1]={3,4} IN[2]={1,2,5,6,7} IN[1]={5,7} IN[2]={1,2,3,4,6} IN[1]={5,6} IN[2]={1,2,3,4,7} IN[1]={5} IN[2]={1,2,3,4,6,7} IN[1]={4,6,7} IN[2]={1,2,3,5} IN[1]={4,7} IN[2]={1,2,3,5,6} Just change the first 3 lines to solve for other instances. However, as others have pointed out, this problem is NP-Hard. So it can switch from very fast to very slow suddenly. You could also solve the version where not every small item needs to be assigned to a large bin by creating a dummy large bin with enough capacity to fit the entire collection of small items. As you can see from the "Details" section in the manual, the algorithms that solve practical problems quickly are not simple, and their implementation details make a big difference. I am unaware of any CLP libraries written in Javascript. Your best bet may be to wrap CLP in a web service and invoke that service from your Javascript code.
Javascript Typed array vs simple array: performance
What I'm basically trying to do is to map an array of data points into a WebGL vertex buffer (Float32Array) in realtime (working on animated parametric surfaces). I've assumed that representing data points with Float32Arrays (either one Float32Array per component: [xx...x, yy...y] or interleave them: xyxy...xy) should be faster than storing them in an array of points: [[x, y], [x, y],.. [x, y]] since that'd actually be a nested hash and all. However, to my surprise, that leads to a slowdown of about 15% in all the major browsers (not counting array creation time). Here's a little test I've set up: var points = 250000, iters = 100; function map_2a(x, y) {return Math.sin(x) + y;} var output = new Float32Array(3 * points); // generate data var data = []; for (var i = 0; i < points; i++) data[i] = [Math.random(), Math.random()]; // run console.time('native'); (function() { for (var iter = 0; iter < iters; iter++) for (var i = 0, to = 0; i < points; i++, to += 3) { output[to] = data[i][0]; output[to + 1] = data[i][1]; output[to + 2] = map_2a(data[i][0], data[i][1]); } }()); console.timeEnd('native'); // generate data var data = [new Float32Array(points), new Float32Array(points)]; for (var i = 0; i < points; i++) { data[0][i] = Math.random(); data[1][i] = Math.random(); } // run console.time('typed'); (function() { for (var iter = 0; iter < iters; iter++) for (var i = 0, to = 0; i < points; i++, to += 3) { output[to] = data[0][i]; output[to + 1] = data[1][i]; output[to + 2] = map_2a(data[0][i], data[1][i]); } }()); console.timeEnd('typed'); Is there anything I'm doing wrong?
I think your problem is that you are not comparing the same code. In the first example, you have one large array filled with very small arrays. In the second example, you have two very large arrays, and both of them need to be indexed. The profile is different. If I structure the first example to be more like the second (two large generic arrays), then the Float32Array implementation far outperforms the generic array implementation. Here is a jsPerf profile to show it.
In V8 variables can have SMI (int31/int32), double and pointer type. So I guess when you operate with floats it should be converted to double type. If you use usual arrays it is converted to doubles already.
List Permutations
I'm trying to list all three letter permutations and this is the code I have - window.permute = function(){ var alphabet = "abcdefghijklmnopqrstuvwxyz"; var searchTerm ="aaa"; var position = 2; changeString(searchTerm, position); } window.changeString = function(searchTerm, position){ if (position <0){ alert(newString); return; } var alphabet = "abcdefghijklmnopqrstuvwxyz" for (j=0; j < 26;j++){ var newString = searchTerm.substr(0, position) + alphabet[j] + searchTerm.substr(position+1); var newPosition = position -1; changeString(newString,newPosition); } return; } It's not working and I'm not sure why- can anyone help?
var permutate = (function() { var results = []; function doPermute(input, output, used, size, level) { if (size == level) { var word = output.join(''); results.push(word); return; } level++; for (var i = 0; i < input.length; i++) { if (used[i]) { continue; } used[i] = true; output.push(input[i]); doPermute(input, output, used, size, level); used[i] = false; output.pop(); } } return { getPermutations: function(input, size) { var chars = input.split(''); var output = []; var used = new Array(chars.length); doPermute(chars, output, used, size, 0); return results; } } })(); for more information, visit http://jinwolf.tumblr.com/post/26476479113/draw-something-cheat for an working example, check this jsfiddle http://jsfiddle.net/jinwolf/Ek4N5/31/
alert(newString); newString is not defined right there. Instead, you should use the argument passed: alert(searchTerm); Edit: I'm not entirely sure of your approach. It seems overly complicated. This seems to work. I understand that you rather have your own code working, but perhaps this helps you in solving. I don't quite get your substr part. http://jsfiddle.net/NUG2A/2/ var alphabet = "abc"; // shortened to save time function permute(text) { if(text.length === 3) { // if length is 3, combination is valid; alert console.log(text); // or alert } else { var newalphabet = alphabet.split("").filter(function(v) { return text.indexOf(v) === -1; }); // construct a new alphabet of characters that are not used yet // because each letter may only occur once in each combination for(var i = 0; i < newalphabet.length; i++) { permute(text + newalphabet[i]); // call permute with current text + new // letter from filtered alphabet } } } permute(""); This will result in the following being called: permute(""); permute("a"); permute("ab"); permute("abc"); // alert permute("ac"); permute("acb"); // alert permute("b"); // ...
I'm not sure from your question that you mean "permutations" because usually permutations do not include repeated elements where it looks like you want to include "aaa". Here are several algorithms for listing permutations you can go check out. If it turns out you mean to have repetitions, it looks like pimvdb has you covered. Edit: So you know what you are getting into run-time wise: With repetition (aaa,aab,...): n^k = 26^3 = 17,576 Without repetition (abc,bac,...): n!/(n-k)! = 26!/(26-3)! = 15,600
for (j=0; j < 26;j++){ should be for (var j=0; j<26; j++) { Without the declaration, j is a global variable, so it only takes one iteration to get to 26 and then all the loops terminate.
For permutations a recursive algorith as pimvd showed is always nice but don't forget you can just brute force it with for-loops when N is small: for(int x1=0; x1 < 26; x1++) for(int x2=0; x2 < 26; x2++) for(int x3=0; x3 < 26; x3++){ //do something with x1, x2, x3 }
In C#: void DoPermuation(string s) { var pool = new HashSet<string>(); //Permute("", , pool); pool = Permute(new List<char>(s)); int i = 0; foreach (var item in pool) Console.WriteLine("{0:D2}: {1}", ++i, item); } HashSet<string> Permute(List<char> range) { if (range.Count == 1) return new HashSet<string>(new string[] { range[0].ToString() }); var pool = new HashSet<string>(); foreach (var c in range) { var list = new List<char>(range); list.Remove(c); foreach (var item in Permute(list)) pool.Add(c + item); } return pool; }