Given an array of positive integers representing terrain heights (in 2-d, ala Super Mario)) and an integer representing a flat sea level, return a container of integers representing the volume of each unique body of water.
Please do not solve the whole problem for me!
I have a few questions:
Lets take an example first.
int [] arr = {4, 3, 5, 6, 4, 2};
int sea_level = 4;
The way it is set up is like this:
6
5 6
4 5 6 4 2
4 3 5 6 4 2
4 3 5 6 4 2
4 3 5 6 4 2
Q So we can't cross over 4 right?
So we have the ranges, [4, 3] and [4, 2] (after the [5, 6] range).
But how do I calculate the volume?
Arraylist<Integer> list = new Arraylist<>();
int volume = 0;
for(int i = 0; i < arr.length; i++){
if(arr[i] <= sea_level){
volume += arr[i];
} else{
list.add(volume); //volume for one block, then reset down.
volume = 0; //loop starts with the next one.
}
}
Is this the way to go about it? I don't understand the problem.
Given your example:
6
5 6 5
4 5 6 5
4 3 5 6 5
4 3 5 6 2 5
4 3 5 6 2 1 5
The water line is at 4, so:
6
5 6 5
~~~~~~~~~~~~5
4 5 6 5
4 3 5 6 5
4 3 5 6 2 5
4 3 5 6 2 1 5
Which makes the water volume the holes beneath the water line, or:
6
5 6 5
~~~~~~~~~~~~5
4 W 5 6 W W 5
4 3 5 6 W W 5
4 3 5 6 2 W 5
4 3 5 6 2 1 5
or, 1 cube of water, and then 5 cubes of water.
Now, how do you calculate that... you need the volume.
The volume is measured between the waterline (4) and the terrain height...
So to measure the volume: sea_level - a[i]
Related
i want devide matrix into four sub-blocks equally by vertically and horizontallty in java (Here, we suppose that m and nare even numbers) .
for example we have matrix:
1 2 3 4 5 6
7 8 9 1 2 8
1 2 3 4 5 6
4 5 6 7 8 9
1 4 7 2 5 8
3 6 9 7 2 5
I want to display the last block that is:
7 8 9
2 5 8
7 2 5
how i can resolve this problem in java.
Iterate over the lower-right part of the matrix. Here is an example for a square matrix. I am sure you will be able to make it more generic for non-square quadrants or to get other quadrants than the lower-right one.
public int[][] getQuadrantOfSquareMatrix(int[][] matrix) {
int newDimension = matrix.length / 2;
int[][] toReturn = new int[newDimension][newDimension];
for (int i = 0; i < newDimension; i++) {
for (int j = 0; j < newDimension; j++) {
toReturn[i][j] = matrix[i + newDimension][j + newDimension];
}
}
return toReturn;
}
So I made this method of rolling a dice 100 times with a 50% chance of rolling 6.
Basic idea is that there are 50% odd numbers and 50% even numbers between 1 and 6, so if an even number is rolled, system prints 6 else it prints a random number between 1 and 5. Do you think this is correct?
public static void printDiceRolls(Random randGenerator) {
for (int i=0; i < 30; i++) {
int temp;
temp = randGenerator.nextInt(6) + 1;
if (temp%2 == 0) {
temp = 6;
}
else
temp = randGenerator.nextInt(5) + 1;
System.out.print(" " + temp + " ");
}
}
Generate a random number between 1 and 10, inclusive on both ends. If the number be 1 to 5, you rolled that number, otherwise, you rolled 6. Note that there are 5 chances in this scheme to roll a 6 (i.e. 50%), and 5 total chances to roll 1 through 5 (i.e. the other 50%).
Random random = new Random();
int roll = random.nextInt(10) + 1;
if (roll > 5) {
System.out.println("You rolled a 6");
}
else {
System.out.println("You rolled a " + roll);
}
You could generate number from 1 to 10 and print 6 if its bigger than 6
for (int i = 0 ; i < 30 ; i++) {
int temp = randGenerator.nextInt(10) + 1;
if (temp > 6) {
temp = 6;
}
System.out.print(" "+temp+" ");
}
Dice roll with a 50% chance of rolling 6
The following method ensures 50% of the dice being 6 but they won't
come in alternative manner... I think this is the best way to ensure
that 6 being diced exactly 50% times but not in alternating sequence
which makes the result more believable, in my opinion.
In my view you only need to do it:
public static void naturalDicingWithVariablePercentageOfSix(int totalDice,int probability)
{
Random rand=new Random();
List<Integer> diceList=new ArrayList<Integer>();
System.out.println(""+( (int)(100/probability))+"% times that six being diced \n\n");
for(int i=0;i<totalDice;i++)
{
if(i%probability==0)
diceList.add(6);
else
diceList.add(rand.nextInt(5)+1);
}
Collections.shuffle(diceList);
int notSixCount=0;
int sixCount=0;
for(Integer diceVal:diceList)
{
if(diceVal!=6)
notSixCount++;
else
sixCount++;
System.out.print(diceVal+" ");
}
System.out.println("\n\n Not 6 being diced : "+notSixCount+" times "+" and Six being diced :"+sixCount+"\n\n");
}
Input:
naturalDicingWithVariablePercent6(100,2); // 50% times 6
naturalDicingWithVariablePercent6(100,3); // 33% times 6
naturalDicingWithVariablePercent6(100,4); // 25% times 6
naturalDicingWithVariablePercent6(100,5); // 20% times 6
naturalDicingWithVariablePercent6(100,6); // 16.67% times 6
Output:
50% times that six being diced
4 3 6 6 3 5 4 6 2 1 6 6 6 6 1 6 6 4 3 5 6 6 5 4 2 5 6 2 1 6 5 5 1 6 6 6 2 6 4 6 6 4 6 6 6 6 2 1 6 3 6 4 3 5 6 6 5 6 6 6 6 6 4 2 6 3 3 6 3 6 6 6 3 5 2 5 6 6 3 2 6 6 6 5 4 6 4 4 3 6 5 4 6 1 6 6 6 6 5 6
Not 6 being diced : 50 times and Six being diced :50
33% times that six being diced
2 6 1 6 5 2 1 5 6 5 6 3 3 2 1 3 5 3 6 6 4 4 2 6 6 1 1 4 2 6 6 3 6 2 6 5 6 4 1 3 6 4 1 1 2 6 5 6 6 6 2 4 2 2 3 6 4 3 4 1 6 4 4 2 4 6 6 4 5 4 6 6 2 4 4 5 3 6 6 6 3 6 6 1 2 4 1 4 6 6 6 5 4 4 5 5 6 2 3 6
Not 6 being diced : 66 times and Six being diced :34
25% times that six being diced
6 1 3 4 6 4 4 2 4 1 6 3 6 1 1 3 3 5 3 4 1 2 3 3 6 3 3 4 5 5 2 6 5 2 3 1 1 4 4 6 5 4 2 3 5 6 3 4 6 4 6 6 5 6 6 5 1 6 6 6 2 3 6 3 6 4 6 5 3 4 5 2 4 2 1 6 3 5 6 3 2 1 4 1 3 6 4 6 6 5 5 5 5 4 2 1 2 3 3 6
Not 6 being diced : 75 times and Six being diced :25
20% times that six being diced
6 4 6 1 3 5 4 4 1 4 4 1 4 5 6 3 4 3 2 3 3 5 2 1 3 3 2 6 1 3 5 6 5 2 2 6 3 1 2 2 1 6 2 1 3 1 1 1 1 1 5 4 4 6 2 2 2 2 1 6 3 5 6 5 3 6 6 5 2 4 3 2 6 4 6 6 6 6 3 5 2 3 2 4 4 5 4 2 1 6 1 6 6 3 3 5 2 5 2 5
Not 6 being diced : 80 times and Six being diced :20
16% times that six being diced
5 4 2 2 4 4 6 2 2 1 3 5 4 2 5 5 6 5 3 3 4 3 3 5 3 1 6 5 3 6 2 4 6 6 5 4 4 6 6 5 6 5 1 3 4 3 2 1 1 6 1 1 4 4 3 3 1 3 5 3 2 6 5 4 4 2 6 4 6 3 1 4 2 3 1 1 1 1 1 3 3 5 2 3 3 6 6 2 3 3 5 5 1 1 6 4 6 3 2 2
Not 6 being diced : 83 times and Six being diced :17
Don't roll a six sided die, roll a ten sided die. The die has sides marked [1, 2, 3, 4, 5, 6, 6, 6, 6, 6]. Pick a random side for each die roll.
I am trying to implement in Eclipse Java Levenshtein distance on the following two strings:
I took the idea from Wikipedia, but I don't know why my output is wrong, I need help to find my mistake/s.
"kruskal"
"causal"
package il.ac.oranim.alg2016;
public class OPT {
public static void main(String[] args)
{
char[] t={'k','r','u','s','k','a','l'};
char[] s={'c','a','u','s','a','l'};
for (int i=0;i<=s.length;i++)
{
for (int j=0;j<=t.length;j++)
System.out.print(LevenshteinDistance(s,t)[i][j]+" ");
System.out.println();
}
}
private static int[][] LevenshteinDistance(char s[], char t[])
{
// d is a table with m+1 rows and n+1 columns
int[][] d=new int[s.length+1][t.length+1];
for (int i=0;i<=s.length;i++)
d[i][0] = i; // deletion
for (int j=0;j<=t.length;j++)
d[0][j] = j; // insertion
for (int j=1;j<t.length;j++)
{
for (int i=1;i<s.length;i++)
{
if (s[i] ==t[j])
d[i][j]=d[i-1][j-1];
else
d[i][j] = Math.min(Math.min((d[i-1][ j] + 1),
(d[i][j-1] + 1)),
(d[i-1][j-1] + 1)) ;
}
}
return d;
}
}
My output:
0 1 2 3 4 5 6 7
1 1 2 3 4 4 5 0
2 2 1 2 3 4 5 0
3 3 2 1 2 3 4 0
4 4 3 2 2 2 3 0
5 5 4 3 3 3 2 0
6 0 0 0 0 0 0 0
The output should be:
0 1 2 3 4 5 6 7
1 1 2 3 4 5 6 7
2 2 2 3 4 5 5 6
3 3 3 2 3 4 5 6
4 4 4 3 2 3 4 5
5 5 5 4 3 3 3 4
6 6 6 5 4 4 4 3
If you reread the specifications, you will find there are two errors:
on the wikipedia, they use indices ranging from 1 to (and including n), a string starts at index i=1 according to Wikipedia where it is i=0 in Java; and
the weights are not updated correctly:
if (s[i] ==t[j])
d[i][j]=d[i-1][j-1];
In the specifications, this should be the minimum of d[i-1][j]+1, d[i][j-1]+1 and d[i-1][j-1]. It is not guaranteed that d[i-1][j-1] is the lowest value, so you should effectively calculate it.
If one takes these mistakes into account, one can modify the table update algorithm (changes on comment //):
for (int j=1;j<=t.length;j++) { //use <= instead of <
for (int i=1;i<=s.length;i++) { //use <= instead of <
if (s[i-1] ==t[j-1]) //use i-1 and j-1
d[i][j] = Math.min(Math.min(d[i-1][j]+1,d[i][j-1]+1),d[i-1][j-1]); //use the correct update
else
d[i][j] = Math.min(Math.min(d[i-1][j]+1,d[i][j-1]+1),d[i-1][j-1]+1);
}
}
I'm working on an assignment that asks a user to input an integer between 1-15 and then displays an integer pyramid for the number of rows they selected.
I have everything working, but if the number enters an integer greater than 10, I'm getting tripped up by the extra space needed for a double digit number. I've attached my code below. If anyone could provide a little help it would be greatly appreciated.
int lines = input.nextInt();
for (int row = 1; row <= lines; row++)
{
for (int column = 1; column <= lines - row; column++)
{
System.out.print(" ");
}
for (int num = row; num >= 1; num--)
{
System.out.print((num>=10)?+num:" "+num);
}
for (int num = 2; num <= row; num++)
{
System.out.print((num>=10)?+num:" "+num);
}
System.out.println();
}
With my current code, if the user entered 13, it would produce the following output:
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 910
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
I just need to figure out how to get the extra space for the double digit integers. The desired output would be:
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
It looks like you have chosen to do this the (slightly) harder way.
The easy way would be to reserve three spaces for each number (so that single digit numbers would have two spaces between them).
What you have chosen to do is variable spacing depending on the actual length of the numbers in each column. The first step is to change your output statements to the following:
System.out.print(" "+num);
So you will always print one space between numbers on each row. If you run that, you'll notice that it almost works except the top part of the triangle is misaligned. To fix that, you'll have to adjust your
System.out.print(" ");
statement so that the number of spaces it prints in each column depends on the value of the number that will appear in each column later on. To do this, you'll have to work out some arithmetic involving column and lines, to choose between " " (two spaces) and " " (three spaces). It's straightforward but I'll let you work out the details.
It is possible to further extend this idea to support 100 lines or more, but it's not clear that you need that capability.
I was interested in solving this, so wrote a simple solution for your task. Seems to work for any lines value.
public static void main(String[] args) {
int lines = 100;
for (int row = 1; row <= lines; row++) {
for (int i = 0; i < calculateOffset(row, lines); i++) {
System.out.print(" ");
}
System.out.print(row);
for (int num = row-1; num >= 1; num--) {
System.out.print(" " + num);
}
for (int num = 2; num <= row; num++) {
System.out.print(" " + num);
}
System.out.println();
}
}
private static int calculateOffset(int row, int totalRows) {
return calculateSpace(totalRows) - calculateSpace(row);
}
private static int calculateSpace(int columnsCount) {
int categoryLowest = 1;
int categoryHighest = 9;
int categoryDigits = 1;
int charactersUsed = 0;
while (categoryLowest <= columnsCount) {
int categoryItems = Math.min(categoryHighest, columnsCount) - categoryLowest + 1;
int numbersCharacters = categoryDigits * categoryItems;
int spacesCharacters = (categoryItems - 1);
boolean previousCategoryIncluded = categoryLowest > 1;
int spaceBetweenCategoriesPresent = previousCategoryIncluded ? 1 : 0;
charactersUsed += numbersCharacters + spacesCharacters + spaceBetweenCategoriesPresent;
categoryHighest = categoryHighest * 10 + 9;
categoryLowest *= 10;
categoryDigits++;
}
return charactersUsed;
}
No idea why you chose the logic like that. However, intuitively, this is what I am going to do:
1 find mid point location (you can simply contruct the last line and find the mid-point)
2 a function to construct a line, by simply do (psuedo-code):
String getLine(int num) {
String result = "";
for (int i = num; i > 0; i--) {
result = result + i + " ";
}
for (int i = 2; i <= num; i++) {
result = result + i + (i == num? "" : " ");
}
return result;
}
3 do a loop to print each line:
int midPoint = .....; //
for (i=0; i < num; i++) {
String line = getLine(i+1);
print (midPoint - mid point of line) spaces;
print line
}
Update:
Have briefly tested, looks good to me:
public static String getLine(int num) {
String result = "";
for (int i = num; i > 0; --i) {
result = result + i + " ";
}
for (int i = 2; i <= num; ++i) {
result = result + i + (i == num ? "" : " ");
}
return result;
}
public static void main(String[] args) {
int num = 15;
int midPoint = getLine(num).length()/2 + 1;
for (int i = 0; i < num; ++i) {
String line = getLine(i+1);
int noPrefix = midPoint - (line.length()+1)/2 ;
for (int j = 0; j < noPrefix; ++j) {
System.out.print(" ");
}
System.out.println(line);
}
}
result :
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Late to the party, but here's a solution using StringBuilder and printing it out only at the end.
The idea is to calculate the amount of padding required based on the String equivalent of the current value.
Note: The solution is not efficient (with all the conversion to String), but it can be used for any input value.
Working Example:
import java.util.Scanner;
public class IntegerPyramid {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter # of lines: ");
int numLines = sc.nextInt();
StringBuilder sb = new StringBuilder();
System.out.println();
for(int row = 1; row <= numLines; row++) {
for(int num = -numLines; num <= numLines; num++) {
if(num == -1 || num == 0)
continue;
int value = Math.abs(num);
int padding = String.valueOf(value).length() + 1;
if(value <= row) {
// Print numbers
sb.append(String.format(("%" + padding + "d"), value));
}
else {
// Print spaces
sb.append(String.format(("%" + padding + "s"), ""));
}
}
sb.append("\n");
}
System.out.println(sb.toString());
sc.close();
}
}
Output:
Enter # of lines: 6
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
Enter # of lines: 15
1
2 1 2
3 2 1 2 3
4 3 2 1 2 3 4
5 4 3 2 1 2 3 4 5
6 5 4 3 2 1 2 3 4 5 6
7 6 5 4 3 2 1 2 3 4 5 6 7
8 7 6 5 4 3 2 1 2 3 4 5 6 7 8
9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9
10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10
11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11
12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12
13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13
14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
You've got the conditional backwards, believe it should be
System.out.print((num >= 10) ? " " + num : num)
Easier to understand
System.out.print((num < 10) ? num : num : " " + num)
Let's say I have a list [x1, x2, x3] where x1, x2, and x3 can take on any value between 1 and 5.
I want to iterate over every possible list that can be created (From [1, 1, 1], [1, 1, 2], . To [5, 5, 5]). This is an easy problem with only 3 elements in the list.
You can do something like this:
for x = 1; x <= 5; x++;
for y = 1; y <= 5; y++;
...
for q = 1; q <= 5; q++;
create list [x, y, ..., q];
do something with the list;
However, how do you iterate over every possible list where the number of elements is over like 10?
Edi: I've added Java as a constraint. I just want to see how this would be done without too many fancy library calls.
Edit2: What I am really looking for is some algorithm to do this, not what sort of libraries can be used to do it. But what I'm looking for is really a language-independent algorithm.
Using Guava you can do it easily:
public static void main(String[] args) {
int lowerBound = 1;
int upperBound = 5;
int setSize=3;
ContiguousSet<Integer> integers = ContiguousSet.create(Range.closed(lowerBound, upperBound), DiscreteDomain.integers());
List<Set<Integer>> sets = Lists.newArrayList();
for (int i = 0; i < setSize; i++) {
sets.add(integers);
}
Set<List<Integer>> cartesianProduct = Sets.cartesianProduct(sets);
for (List<Integer> list : cartesianProduct) {
System.out.println(list);
}
}
Which prints:
[1, 1, 1]
[1, 1, 2]
[1, 1, 3]
[1, 1, 4]
[1, 1, 5]
...
[5, 5, 4]
[5, 5, 5]
Logic :
In arr[x1 x2 x3]; all x1, x2, x3 can have values from 1 to 5. Which means every position in array can have value from 1 to 5. For a value at current position all the values are possible at next position.
suppose at 0 position of array value stored is 1.
[1 _ _] _ represent there is no value.
values for the next position : [1 1 _] , [1 2 _] ,[1 3 _] ,[1 3 _] ,[1 4 _],[1 5 _].
So iterate over current position to store the different possible values from 1 to 5 at current position and for each value call the permutate function again with current position value incremented by 1 for iterating all possible values from 1 to 5 at next position .
Code :
public class permutation {
static int limit;
public static void permutate(int arr[],int curPos)
{
int i;
if(curPos==arr.length)
{
for(i=0;i<arr.length;i++)
{
System.out.print(arr[i] + "\t");
}
System.out.println("");
return;
}
for(i=1;i<=limit;i++)
{
arr[curPos]=i;
permutate(arr,curPos+1);
}
}
public static void main(String[] args) {
int arr[] = new int[3];
limit = 5;
permutate(arr,0);
}
}
Output :
1 1 1
1 1 2
1 1 3
1 1 4
1 1 5
1 2 1
1 2 2
1 2 3
1 2 4
1 2 5
1 3 1
1 3 2
1 3 3
1 3 4
1 3 5
1 4 1
1 4 2
1 4 3
1 4 4
1 4 5
1 5 1
1 5 2
1 5 3
1 5 4
1 5 5
2 1 1
2 1 2
2 1 3
2 1 4
2 1 5
2 2 1
2 2 2
2 2 3
2 2 4
2 2 5
2 3 1
2 3 2
2 3 3
2 3 4
2 3 5
2 4 1
2 4 2
2 4 3
2 4 4
2 4 5
2 5 1
2 5 2
2 5 3
2 5 4
2 5 5
3 1 1
3 1 2
3 1 3
3 1 4
3 1 5
3 2 1
3 2 2
3 2 3
3 2 4
3 2 5
3 3 1
3 3 2
3 3 3
3 3 4
3 3 5
3 4 1
3 4 2
3 4 3
3 4 4
3 4 5
3 5 1
3 5 2
3 5 3
3 5 4
3 5 5
4 1 1
4 1 2
4 1 3
4 1 4
4 1 5
4 2 1
4 2 2
4 2 3
4 2 4
4 2 5
4 3 1
4 3 2
4 3 3
4 3 4
4 3 5
4 4 1
4 4 2
4 4 3
4 4 4
4 4 5
4 5 1
4 5 2
4 5 3
4 5 4
4 5 5
5 1 1
5 1 2
5 1 3
5 1 4
5 1 5
5 2 1
5 2 2
5 2 3
5 2 4
5 2 5
5 3 1
5 3 2
5 3 3
5 3 4
5 3 5
5 4 1
5 4 2
5 4 3
5 4 4
5 4 5
5 5 1
5 5 2
5 5 3
5 5 4
5 5 5
At least in python (You should specify language if it's a constraint):
>>> from itertools import permutations as permu
>>> for i in permu(range(5), 3):
... print i
...
(0, 1, 2)
(0, 1, 3)
(0, 1, 4)
(0, 2, 1)
(0, 2, 3)
(0, 2, 4)
(0, 3, 1)
....
In recursive solution you don't have to sort the list every time. Giving sorted list to recursive function must be sifficient.
To do so, I've written this piece of C# code. Length of output result will be determined by len. Just remember that input length must be equal or bigger than len:
// Input must be sorted, Result must be initialized to empty list
void Iterate(List<int> input, int len, List<int> result)
{
if(result.Count == n)
print result
else
foreach (var i in input)
Iterate(input, len, result.Append(num).ToList())
}
Use this algorithm.
Input: X is the minimum number, Y is the maximum number, and Z is the number of independent choices.
Create an array of size Z, with each element equal to X. Call it Permutation.
Loop:
Add a copy of Permutation to the list of permutations.
Set J to Z minus 1.
Loop:
Add 1 to Permutation[J]. If Permutation[J] is now Y or less, break.
Set Permutation[J] to X.
Subtract 1 from J. If J is now less than 0, return the list of permutations.
Must be classic algorithm. But it always fun to write it from scratch. Here is Java class accepting data set and result list size parameters. Core method is generate(). Also lists might be copied on demand (to be more functional style).
import com.google.common.collect.Maps;
import org.apache.commons.lang.ArrayUtils;
import java.util.Map;
public class PermutationGenerator {
private int listValuesSize;
private int resultListSize;
private String[] currentList;
private Map<String, String> nextValue = Maps.newHashMap();
private int permutations = 0;
public PermutationGenerator(String[] dataSet, int resultListSize) {
this.listValuesSize = dataSet.length;
this.resultListSize = resultListSize;
init(dataSet);
}
private void init(String[] dataSet) {
// rolling values
String previous = dataSet[0];
for (int valuesIndex = 1; valuesIndex < dataSet.length; valuesIndex++) {
nextValue.put(previous, dataSet[valuesIndex]);
previous = dataSet[valuesIndex];
}
nextValue.put(dataSet[dataSet.length - 1], dataSet[0]);
// init
currentList = new String[resultListSize];
for (int i = 0; i < resultListSize; i++) {
currentList[i] = dataSet[0];
}
}
public void generate() {
generate(0, resultListSize - 1);
}
private void generate(int from, int to) {
if (from > to) {
return;
}
for (int i = 0; i < listValuesSize; i++) {
if (from == to) {
processList(currentList);
} else {
generate(from + 1, to);
}
roll(from);
}
}
private void roll(int position) {
currentList[position] = nextValue.get(currentList[position]);
}
private void processList(String[] list) {
permutations++;
System.out.println(ArrayUtils.toString(list));
}
public static void main(String... args) {
PermutationGenerator generator = new PermutationGenerator(new String[]{"1", "2", "3", "4", "5"}, 3);
generator.generate();
System.out.println(generator.permutations);
}
}