Finding Levenshtein distance on two string - java

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);
}
}

Related

For loop to print a numeric pattern does not print the correct pattern

This is what it should look like
9 8 7 6 5 4 3 2 1 0
8 8 7 6 5 4 3 2 1 0
7 7 7 6 5 4 3 2 1 0
6 6 6 6 5 4 3 2 1 0
5 5 5 5 5 4 3 2 1 0
4 4 4 4 4 4 3 2 1 0
3 3 3 3 3 3 3 2 1 0
2 2 2 2 2 2 2 2 1 0
1 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
Here's my attempt.
public class Main {
public static void main(String[] args) {
int i = 9;
int count = -1;
while (i >= count) {
int j = i;
while (j > count) {
System.out.print(j + " ");
j--;
}
System.out.println();
count++;
}
}
}
Here's my actual output:
9 8 7 6 5 4 3 2 1 0
9 8 7 6 5 4 3 2 1
9 8 7 6 5 4 3 2
9 8 7 6 5 4 3
9 8 7 6 5 4
9 8 7 6 5
9 8 7 6
9 8 7
9 8
9
This obviously does not match the expected output. Can someone point out where the mistake is in the code?
This is a Solution that has the right output, but instead of using while-Loops I used for-Loops
public class Main {
public static void main(String[] args) {
int count1 = 9;
for (int i = count1; i >= 0; i--) {
int count2 = i;
if (count1 > count2) {
int tmp = count1 - count2;
for (int j = tmp; j > 0; j--) {
System.out.print(count2 + " ");
}
}
for (int j = count2; j >= 0; j--) {
System.out.print(j + " ");
}
System.out.println();
}
}
}
You can keep two outer variables, counter and multiplier, for the matrix size and repetitions' count respectively:
public class Main {
public static void main(String[] args) {
int counter = 15;
int multiplier = 1;
for (int i = counter; i >= 0; i--) {
for (int j = 0; j<multiplier; j++) {
System.out.printf("%3d", counter); //using %3d for spacing numbers nicely
}
for (int k = counter-1; k >= 0; k--) {
System.out.printf("%3d", k);
}
++multiplier;
--counter;
System.out.println();
}
}
}
For every horizontal line, where counter decreases, and multiplier increases (9 once on 1st line; 8 twice on the second line, etc.):
it will first print the counter, multiplier times;
it will then fill the rest of the line with counter-multiplier number of descending sequence integers, starting from counter-1;
at the end of outer loop's each iteration, a new line is printed.
Output would be:
9 8 7 6 5 4 3 2 1 0
8 8 7 6 5 4 3 2 1 0
7 7 7 6 5 4 3 2 1 0
6 6 6 6 5 4 3 2 1 0
5 5 5 5 5 4 3 2 1 0
4 4 4 4 4 4 3 2 1 0
3 3 3 3 3 3 3 2 1 0
2 2 2 2 2 2 2 2 1 0
1 1 1 1 1 1 1 1 1 0
0 0 0 0 0 0 0 0 0 0
Since you already have your answer, here are a couple alternatives.
String str = "9 8 7 6 5 6 3 2 1 0";
System.out.println(str);
for (int i = 9; i > 0; i--) {
str = str.replace(i+"",(i-1)+"");
System.out.println(str);
}
Or use the String.repeatmethod.
for (int i = 9; i >= 0; i--) {
System.out.print((i+" ").repeat(9-i));
for(int k = i; k >= 0; k--) {
System.out.print(k + " ");
}
System.out.println();
}
With the help of Java8 stream you can write the code as below:
public static void main(String[] args) {
IntStream.range(0, 10)
.forEach(i -> {
IntStream.range(0, 10).forEach(j -> {
System.out.print((9- (j < i ? i : j)) + " " );
});
System.out.println("");
});
}

dividing matrix into four sub-blocks

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;
}

Struggling to keep an algorithm to order players by dice roll tidy

I am writing a Java algorithm which gets each of six players in a game to roll a dice and the highest roll takes the first turn and so on. I have already written the dice rolling method which takes in a map of players in the form of <String playerName, Player player>, and gets each player to roll the dice, where player is a class storing many player attributes necessary for the game.
The problem I am having trouble overcoming when ordering the players is that if two players roll the same number, they then roll again in order to see who goes ahead of the other. Here is an example scenario:
Position: Player (number rolled)
1: Tom (5)
2: Jerry (4)
=3: Jack (3)
=3: Jill (3)
5: Harry (2)
6: Ron (1)
So Jack and Jill roll again. Jack rolls a 6 and Jill rolls a 3. Jack is now in 3rd position and Jill in 4th.
Any strategy I have began to write quickly becomes seemingly overly complicated and very untidy and difficult to read. This is due to having to check if there are any duplicate rolls at any number, all while storing every roll in the correct order, allowing for two or more positions if there is a duplicate roll.
Can anyone come up with a neat structure in which this order can be determined and stored?
Each instance of Player, has a nextPlayer variable that will point to the player in the position after them. It would probably be best to also store numberRolled in the class too. Any players who roll the same number can be stored in a new map and then passed into the rollDice method again.
EDIT
Thanks to Andy Turner, here is my solution:
private Player[] playerOrder = new Player[ModelConstants.NUM_PLAYERS_PLUS_NEUTRALS];
playerOrder = getPlayerOrder();
Player[] getPlayerOrder() {
Player[] players = ModelConstants.PLAYERS.values().toArray(new Player[ModelConstants.PLAYERS.size()]);
String[] playerNames = ModelConstants.PLAYERS.keySet().toArray(new String[ModelConstants.PLAYERS.size()]);
getPlayerOrder(playerNames, players, 0, players.length);
return players;
}
void getPlayerOrder(String[] playerNames, Player[] players, int start, int end) {
// Get all players between players[start] (inclusive) and
// players[end] (exclusive) to re-roll the dice.
for (int i = start; i < end; ++i) {
players[i].setDiceNumberRolled(rollDice(playerNames[i], players[i]));
}
// Sort this portion of the array according to the number rolled.
Arrays.sort(players, start, end, new Comparator<Player>() {
#Override public int compare(Player a, Player b) {
return Integer.compare(a.getDiceNumberRolled(), b.getDiceNumberRolled());
}
});
for (int i = 0; i < playerNames.length; i++) {
playerNames[i] = HashMapUtilities.getKeyFromValue(ModelConstants.PLAYERS, players[i]);
}
// Look for players who rolled the same number.
int i = start;
while (i < end) {
// Try to find a "run" of players with the same number.
int runStart = i;
int diceNumberRolled = players[runStart].getDiceNumberRolled();
i++;
while (i < end && players[i].getDiceNumberRolled() == diceNumberRolled) {
i++;
}
if (i - runStart > 1) {
// We have found more than one player with the same dice number.
// Get all of the players with that dice number to roll again.
addMessageToLog(MessageType.INFO, "There has been a tie." , 2000);
tiedPlayers = true;
getPlayerOrder(playerNames, players, runStart, i);
tiedPlayers = false;
}
}
}
private int rollDice(String playerName, Player player) {
int numberRolled = 0;
if (player.getPlayerType().equals(PlayerType.HUMAN)) {
boolean diceRolled = false;
while (!diceRolled) {
String message = ", roll the dice";
if (tiedPlayers == true) {
message += " again.";
}
else {
message += ".";
}
String userInput = getCommand(playerName + message, "Invlaid command. Type \"Roll Dice\" or something similar.", 2000);
if (userInput.equalsIgnoreCase("Roll Dice") || userInput.equalsIgnoreCase("roll the dice") || userInput.equalsIgnoreCase("Roll")) {
numberRolled = dice.rollDice();
diceRolled = true;
}
else {
addMessageToLog(MessageType.ERROR, "Invlaid command. Type \"Roll Dice\" or something similar.", 0);
}
}
}
else {
String message = " is now rolling the dice";
if (tiedPlayers == true) {
message += " again...";
}
else {
message += "...";
}
addMessageToLog(MessageType.INFO, playerName + message, 2000);
numberRolled = dice.rollDice();
}
player.setDiceNumberRolled(numberRolled);
addMessageToLog(MessageType.SUCCESS, playerName + " rolled a " + numberRolled, 1000);
addDicePanel(numberRolled);
return numberRolled;
}
private void setPlayerOrder() {
for (int i = 0; i < playerOrder.length; i++) {
if (i == (playerOrder.length - 1)) {
playerOrder[i].setNextPlayer(playerOrder[0]);
}
else {
playerOrder[i].setNextPlayer(playerOrder[i + 1]);
}
}
activePlayer = playerOrder[0];
}
private void changePlayer() {
activePlayer = activePlayer.getNextPlayer();
}
There are 2 ways to deal with this.
1) The simple thing is to forget the "dice-roll". Generate 32 random (one int) bits for each player and use that for ordering. If they happen to match pick whatever player you want. It's going to be so rare that it doesn't really matter (1 in 4 billion that you get 2 numbers to be the same).
2) If you want to stick to dice-roll. Create a function that takes a list of players, rolls the dice internally and returns the correctly ordered one. Whenever you have equal rolls call create a smaller list with the players that are equals and call the function recursively to give you the ordering of those players. When it returns copy it in the result and continue. You can prove mathematically that it's highly unlikely(read impossible) that this will result in an infinite loop.
To organize stuff, try to create a separate method for each "action" you need - one method for rolling the dice, another to find duplicates, and another to sort. here are the steps:
Roll dice for all players, store in a List
Find duplicates
For all duplicates, repeat step 1 and 2 until no duplicates are found.
Sort the players.
3 methods. 4 steps. logically executed to do what you need.
public int rolldice(Player player);
public List<Player> findDuplicates (List<Player> players);
public void sortPlayers(List<Player> players);
you can already work with these 3 methods. Hope this helps
You can put all of the players into an array - the order of the players in an array can be used to indicate the order of play.
Get them all to pick a dice roll; then sort them by the number they rolled (using a custom comparator).
Now, look for 2 or more players that rolled the same number - these are next to each other because the array is sorted. Now, you can recursively call the same logic to get just those players to re-roll, but only on the portion of the array where those players had the same dice roll.
For example:
Player[] getPlayerOrder() {
Player[] players = playerMap.values().toArray(new Player[playerMap.size()]);
getPlayerOrder(players, 0, players.length);
return players;
}
void getPlayerOrder(Player[] players, int start, int end) {
// Get all players between players[start] (inclusive) and
// players[end] (exclusive) to re-roll the dice.
for (int i = start; i < end; ++i) {
// Logic to roll dice...
players[i].setDiceNumberRolled(...);
}
// Sort this portion of the array according to the number rolled.
Arrays.sort(players, start, end, new Comparator<Player>() {
#Override public int compare(Player a, Player b) {
return Integer.compare(b.getDiceNumberRolled(), a.getDiceNumberRolled());
}
});
// Look for players who rolled the same number.
int i = start;
while (i < end) {
// Try to find a "run" of players with the same number.
int runStart = i;
int diceNumberRolled = players[runStart].getDiceNumberRolled();
++i;
while (i < end && players[i].getDiceNumberRolled() == diceNumberRolled) {
++i;
}
if (i - runStart > 1) {
// We have found more than one player with the same dice number.
// Get all of the players with that dice number to roll again.
getPlayerOrder(players, runStart, i);
}
}
}
My attemp would be to let everyone roll the dice and just store it without any sort. Then check for duplicates and let the players who got the same numbers roll again. Afterwards when every Player rolled and nothig duplicate anymore just use some Sort Algorithm. Simplest one for that would be BubbleSort since you have no time issue when sorting. Check out this enter link description here
The iterative solution not as simple as I first thought!
I originally posted a solution using primitive int arrays for players & dice.
But this was needlessly complex to code. Easier by far to use composite class, PlayerDice. An array of such objects can be sorted using Arrays.sort(...) method for desired range of the array according to the compareTo(.) method defined for PlayerDice.
You have to be careful to store the end index when some of a group of players tied on the same dice again tie after a roll-off. These I put into a stack - except where the entire group of tied players throw the same dice on a roll-off.
The overall finish condition is when there are no ties and the start-index is greater than the end-index.
package snakesAndLadders;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Stack;
public class PlayOrderTest6
{
private final static int numPlayers = 16;
private PlayerDice[] playersDice = new PlayerDice[numPlayers];
/** Composite class to enable sorting of players according to dice they throw.*/
public static class PlayerDice implements Comparable<PlayerDice>
{
private int player;
private int dice;
public PlayerDice(int player, int dice)
{
this.player = player;
this.dice = dice;
}
public int getPlayer()
{
return player;
}
public void setPlayer(int player)
{
this.player = player;
}
public int getDice()
{
return dice;
}
public void setDice(int dice)
{
this.dice = dice;
}
public String toString()
{
return "Player# " + player + " | Dice: " + dice;
}
#Override
public int compareTo(PlayerDice pd)
{
// Default comparison is on basis of dice value descending:
return pd.getDice() - this.dice;
}
}
/** Main method basically runs the getPlayOrder(.) method for the number of
players involved in this game, i.e. the attribute players. */
public static void main(String[] args)
{
int[] playOrder = new int[numPlayers]; // Holds final play order
// Initialize playerDice array and give each player a number between 1 .. players :
for(int i = 0; i < numPlayers; i++)
{
playersDice[i] = new PlayerDice(i + 1, 1);
playOrder[i] = i + 1;
}
// Generate the order of play by rolling dice & re-rolling for tied players :
getPlayOrder(playersDice);
// Extract play order :
for(int i = 0; i < numPlayers; i++)
playOrder[i] = playersDice[i].getPlayer();
System.out.println("\n\nFinal Player Order is : " + Arrays.toString(playOrder));
}
public static void getPlayOrder(PlayerDice[] p)
{
int start = 0, // Start index of unsorted PlayerDice array
end = numPlayers - 1; // End index of unsorted PlayerDice array
Integer[] sdInds = new Integer[2]; // For start & end indices of first group of tied players.
Stack<Integer> endStack = new Stack<Integer>(); // Holds end index when a dice-roll to sort a tie produces another tie.
while (start < numPlayers && end > start)
{
// Roll dice for players in index range between start & end :
for(int i = start; i < end + 1; i++)
p[i].setDice( (int) (6 * Math.random() + 1));
// Output player/dice values :
System.out.print("\n\nPlayer Order:\t\t");
for(int i = 0; i < numPlayers; i++)
System.out.print(p[i].getPlayer() + "\t");
System.out.print("\nDice Rolled:\t\t");
for(int i = 0; i < numPlayers; i++)
System.out.print(p[i].getDice() + "\t");
// Sort players between start & end indices by their dice number descending :
Arrays.sort(p, start, end + 1); // Uses PlayerDice compareTo(.) method, i.e. by dice value descending.
// Output player/dice values :
System.out.print("\n\nSorted Player Order:\t");
for(int i = 0; i < numPlayers; i++)
System.out.print(p[i].getPlayer() + "\t");
System.out.print("\nSorted Dice Rolled:\t");
for(int i = 0; i < numPlayers; i++)
System.out.print(p[i].getDice() + "\t");
// Find first group of players (from leftmost element of p) on the same dice :
sdInds[0] = -1;
sdInds[1] = -1;
findTiedPlayers(p, start, end, sdInds);
System.out.print("\nsdInds[0]: " + sdInds[0]);
System.out.print("\nsdInds[1]: " + sdInds[1]);
// Where tied players are found ...
if (sdInds[0] != -1)
{ // Re-set start and end indices and re-roll dice to sort the tied group :
start = sdInds[0];
if (sdInds[1] != end)
{
endStack.push(end); // Keeps priority of tied players over those on lower first dice roll
end = sdInds[1];
}
}
else // Where no ties, reset start & end indices till ties found or all players sorted.
while (sdInds[0] == -1 && end >= start)
{
start = end + 1;
if(!endStack.isEmpty())
end = endStack.pop();
else
break; // When no more players to be checked !
// Get indices of first tied group in remaining players :
sdInds[0] = -1; // Initializing start- ...
sdInds[1] = -1; // ... and end-indices before tie search.
findTiedPlayers(p, start, end, sdInds);
if (sdInds[0]!= -1) // If ties found, adjust start & end indices before tie-breaker roll
{
start = sdInds[0];
endStack.push(end); // Store old end index
end = sdInds[1];
}
}
System.out.print("\nstart: " + start);
System.out.print("\nend: " + end);
}
}
/** Method to find first group of tied players in an array holding player & dice data.
* #param pt - a PlayerDice array;
* #param st - an int holding the start index of the range of pt being examined;
* #param en - an int holding the end index of the range of pt being examined;
* #param tInds - an int array holding the start & end index of the
first group of tied players.
This parameter also acts as a return parameter since it's a reference type,
tInds[0] holding the index of the first tied player and tInds[1] the index of
the last. Where no ties are found, both tInds elements retain their received
values of -1 which signifies no ties. */
public static void findTiedPlayers(PlayerDice[] pt, int st, int en, Integer[] tInds)
{
for(int i = st; i < en; i++)
{
for(int j = i + 1; j < en + 1; j++)
if (pt[i].getDice() == pt[j].getDice())
{
tInds[0] = i;
tInds[1] = j;
}
if (tInds[0] != -1) // First group of tied players found ...
break; // ... finish search !
}
}
}
OUTPUT:
Player Order: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
Dice Rolled: 4 4 6 5 2 1 3 6 1 3 4 4 1 2 1 3
Sorted Player Order: 3 8 4 1 2 11 12 7 10 16 5 14 6 9 13 15
Sorted Dice Rolled: 6 6 5 4 4 4 4 3 3 3 2 2 1 1 1 1
sdInds[0]: 0
sdInds[1]: 1
start: 0
end: 1
Player Order: 3 8 4 1 2 11 12 7 10 16 5 14 6 9 13 15
Dice Rolled: 5 6 5 4 4 4 4 3 3 3 2 2 1 1 1 1
Sorted Player Order: 8 3 4 1 2 11 12 7 10 16 5 14 6 9 13 15
Sorted Dice Rolled: 6 5 5 4 4 4 4 3 3 3 2 2 1 1 1 1
sdInds[0]: -1
sdInds[1]: -1
start: 3
end: 6
Player Order: 8 3 4 1 2 11 12 7 10 16 5 14 6 9 13 15
Dice Rolled: 6 5 5 2 6 1 1 3 3 3 2 2 1 1 1 1
Sorted Player Order: 8 3 4 2 1 11 12 7 10 16 5 14 6 9 13 15
Sorted Dice Rolled: 6 5 5 6 2 1 1 3 3 3 2 2 1 1 1 1
sdInds[0]: 5
sdInds[1]: 6
start: 5
end: 6
Player Order: 8 3 4 2 1 11 12 7 10 16 5 14 6 9 13 15
Dice Rolled: 6 5 5 6 2 4 4 3 3 3 2 2 1 1 1 1
Sorted Player Order: 8 3 4 2 1 11 12 7 10 16 5 14 6 9 13 15
Sorted Dice Rolled: 6 5 5 6 2 4 4 3 3 3 2 2 1 1 1 1
sdInds[0]: 5
sdInds[1]: 6
start: 5
end: 6
Player Order: 8 3 4 2 1 11 12 7 10 16 5 14 6 9 13 15
Dice Rolled: 6 5 5 6 2 5 1 3 3 3 2 2 1 1 1 1
Sorted Player Order: 8 3 4 2 1 11 12 7 10 16 5 14 6 9 13 15
Sorted Dice Rolled: 6 5 5 6 2 5 1 3 3 3 2 2 1 1 1 1
sdInds[0]: -1
sdInds[1]: -1
start: 7
end: 9
Player Order: 8 3 4 2 1 11 12 7 10 16 5 14 6 9 13 15
Dice Rolled: 6 5 5 6 2 5 1 2 6 3 2 2 1 1 1 1
Sorted Player Order: 8 3 4 2 1 11 12 10 16 7 5 14 6 9 13 15
Sorted Dice Rolled: 6 5 5 6 2 5 1 6 3 2 2 2 1 1 1 1
sdInds[0]: -1
sdInds[1]: -1
start: 10
end: 11
Player Order: 8 3 4 2 1 11 12 10 16 7 5 14 6 9 13 15
Dice Rolled: 6 5 5 6 2 5 1 6 3 2 4 6 1 1 1 1
Sorted Player Order: 8 3 4 2 1 11 12 10 16 7 14 5 6 9 13 15
Sorted Dice Rolled: 6 5 5 6 2 5 1 6 3 2 6 4 1 1 1 1
sdInds[0]: -1
sdInds[1]: -1
start: 12
end: 15
Player Order: 8 3 4 2 1 11 12 10 16 7 14 5 6 9 13 15
Dice Rolled: 6 5 5 6 2 5 1 6 3 2 6 4 5 4 5 5
Sorted Player Order: 8 3 4 2 1 11 12 10 16 7 14 5 6 13 15 9
Sorted Dice Rolled: 6 5 5 6 2 5 1 6 3 2 6 4 5 5 5 4
sdInds[0]: 12
sdInds[1]: 14
start: 12
end: 14
Player Order: 8 3 4 2 1 11 12 10 16 7 14 5 6 13 15 9
Dice Rolled: 6 5 5 6 2 5 1 6 3 2 6 4 6 2 5 4
Sorted Player Order: 8 3 4 2 1 11 12 10 16 7 14 5 6 15 13 9
Sorted Dice Rolled: 6 5 5 6 2 5 1 6 3 2 6 4 6 5 2 4
sdInds[0]: -1
sdInds[1]: -1
start: 16
end: 15
Final Player Order is : [8, 3, 4, 2, 1, 11, 12, 10, 16, 7, 14, 5, 6, 15, 13, 9]

Trouble formatting with 2-dimensional array matrices

I need my matrices to look exactly like this.(with numbers lined up under text)
Here are the two matrices, and the result when added:
2 2 7 4 3 4 3 3 5 6 10 7
4 4 8 8 6 8 5 5 10 12 13 13
1 9 3 7 6 8 6 9 7 17 9 16
2 3 2 9 + 4 4 7 1 = 6 7 9 10
2 9 1 1 9 8 2 5 11 17 3 6
6 1 8 4 4 8 2 2 10 9 10 6
The results I am currently getting look like.
Here are the two matrices, and the result when added:
8 5 6 6 3 8 2 3 11 13 8 9
7 7 4 5 4 9 2 1 11 16 6 6
9 4 4 8 5 1 1 1 14 5 5 9
4 2 7 7 + 7 9 1 3 = 11 11 8 10
4 3 5 3 5 6 8 7 9 9 13 10
4 2 2 1 3 9 5 5 7 11 7 6
As you can see the code for the arrays sum is shifted to the right, and I am not quite sure how to fix this.
public static void printResult(int [][]array1, int [][]array2, int[][]sum, char arithmetic)
{
if (arithmetic == '+') {
// Text for two matrices when added
System.out.print("Here are the two matrices, and the result when added:\n");
// For loop to print array1 + array2 = sum with format
for (int i = 0; i < array1.length; i++) {
// For loop to print out array 1 and add string, if to place +
for (int j = 0; j < array1[i].length; j++) {
System.out.printf("%4s", array1[i][j]);
if (i == array1.length / 2 && j == array1[i].length-1) {
System.out.printf("%4s", '+');
}
}
System.out.print("\t");
// For loop to print out array2 and equals string, if to place =
for (int j = 0; j < array1[i].length; j++) {
System.out.printf("%2s", array2[i][j] + " ");
if (i == array1.length / 2 && j == array1[i].length-1) {
System.out.printf("%1s", '=');
}
}
System.out.print(" ");
// For loop to print out sum of array1 + array2
for (int j = 0; j < array1[i].length; j++) {
System.out.printf("%4s", sum[i][j]);
}
System.out.print("\n");
}
}
else if (arithmetic == '-') {
}
else if (arithmetic == '*') {
}
else if (arithmetic == '/') {
}
else if (arithmetic == '%') {
}
}
Also a 3x3 array when printed out looks like.
Here are the two matrices, and the result when added:
2 2 7 3 4 3 5 6 8
4 4 8 + 6 8 5 = 7 9 13
1 9 3 6 8 6 7 7
I think this is meant to insure that numbers, when printed, always take up 2 spaces:
System.out.printf("%2s", array2[i][j] + " ");
But because of the added (technically, concatenated) " ", you get a string that is bigger than the %2s field, so there is no padding of short numbers.
Plus, you have code to decide when to print the + & =, but each should be deciding between printing the symbol and printing a space, to keep everything lined up.

How to iterate over every permutation of independent choices?

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);
}
}

Categories

Resources