Java add array to array special mode - java

I am working on a game in Java and I need to cache some position-based information. If I have the following array:
int[][] array = {
{1, 2, 3},
{1, 2, 3},
{1, 2, 3}
};
And then I have this other array:
int[][] otherArray = {
{4, 5, 6},
{4, 5, 6},
{4, 5, 6}
};
Now I want to combine them in a special way. I want to add otherArray to the left of array. So the result would look like this:
int[][] combinedArray = {
{4, 5, 6, 1, 2, 3},
{4, 5, 6, 1, 2, 3},
{4, 5, 6, 1, 2, 3}
};
Then I have this other combined array:
int[][] otherCombinedArray = {
{30, 17, 139, 65, 335, 99},
{50, 43, 57, 53, 423, 534},
{90, 67, 78, 24, 99, 67}
};
Now I want to add it to the top of the original combined array. So the final result would look like this:
int[][] finalCombinedArray = {
{30, 17, 139, 65, 335, 99},
{50, 43, 57, 53, 423, 534},
{90, 67, 78, 24, 99, 67},
{4, 5, 6, 1, 2, 3},
{4, 5, 6, 1, 2, 3},
{4, 5, 6, 1, 2, 3}
};
Can someone point me to a good library or built in method for doing this? I also wanted to note that the method shouldn't be too computationally heavy (like looping through all the arrays multiple times, and it shouldn't use too much memory, like 80MB).
Thank you for the help!

On it's own, Java does not provide concatenation methods, but we can use System.arraycopy (as suggested by #user16320675 above)
With System.arraycopy you specify the array to copy + the destination array -> you have array A of size 10 and B of size 2, and you use the command to copy your B array into A.
int[] source = { 1,2,3,4,5 };
int[] destination = new int[10];
// You can play with the numbers below
int COPY_AT_INDEX = 0; // Start to copy at position destination[0]
int AMOUNT_TO_COPY = 5; // Copying from 0 to source.length
System.arraycopy(source, 0, destination, COPY_AT_INDEX, AMOUNT_TO_COPY);
System.out.println(Arrays.toString(source)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(destination)); // [1, 2, 3, 4, 5, 0, 0, 0, 0, 0]
Now, if we use arraycopy, seems you have to determine when to copy as rows, and when to copy as columns.
// Assuming a[][] and b[][] have the same size.
public int[][] mergeAsColumns(int[][] a, int[][] b) {
int rows = a.length;
int columns = a[0].length;
int[][] merged = new int[rows][2 * columns];
for (int i = 0; i < a.length; i++) {
System.arraycopy(a[i], 0, merged[i], 0, columns);
System.arraycopy(b[i], 0, merged[i], rows, columns);
}
return merged;
}
Merging as Rows is similar to the other one, but changes in which positions you want to affect and how you create the merged array.
// Assuming a[][] and b[][] have the same size.
public int[][] mergeAsRows(int[][] a, int[][] b) {
int rows = a.length;
int columns = a[0].length;
int[][] merged = new int[2 * rows][columns];
for (int i = 0; i < rows; i++) {
System.arraycopy(a[i], 0, merged[i], 0, columns);
System.arraycopy(b[i], 0, merged[rows + i], 0, columns);
}
return merged;
}

Related

Sudoku solver using recursion and backtracking

I am trying to implement a Sudoku solver using Java. This is the code I've written as of now. If I try to run it, it goes on to an endless loop that keeps on printing the first row of the Sudoku board, and that too with an incorrect solution. I guess I'm implementing backtracking the incorrect way over here. I think I am printing the final and wrong as well, as only the first row is printed every time. Can someone please help me fix my code and tell me as to where I am going wrong?
public static void display(int[][] board) {
for(int[] arr : board) {
System.out.println(Arrays.toString(arr));
return;
}
}
public static boolean isSafe(int[][] board, int row, int col, int i) {
//check row
for(int a=0; a<board.length; a++) {
if(board[a][col]==i) {
return false;
}
}
//check col
for(int b=0; b<board.length; b++) {
if(board[row][b]==i) {
return false;
}
}
//check cell
int strow = row-(row%3);
int stcol = col-(col%3);
for(int x=strow; x<strow+3; x++) {
for(int y=stcol; y<stcol+3; y++) {
if(board[x][y]==i) {
return false;
}
}
}
return true;
}
public static void sudoku(int[][] board, int row, int col) {
if(row==board.length) {
display(board);
System.out.println();
return; //modify this to print ans
}
if(col==board.length) {
sudoku(board, row+1, 0);
return;
}
if(board[row][col]==0) {
for(int i=1; i<=9; i++) {
if(isSafe(board, row, col, i)) {
board[row][col]=i;
sudoku(board, row, col+1);
board[row][col]=0;
}
}
}
sudoku(board, row, col+1);
}
public static void main(String args[]) {
int[][] board=
{ {3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0},
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0} };
sudoku(board, 0, 0);
}
A bactracking algorithm can be applied here and the problem happens in your sudoku method.
First of all we can just pass the board and we don't want to pass the row and col.
We can just pass the board and the just traverse through each and every cell.
Only consider those cells that are 0's.
We don't want to consider any other cells as 0"s are the cells we are interested in.
Now if we see a cell which is 0, we try to find all the different possibilites from 1 to 9 which can fit in that cell and apply the 'isSafe()` logic which will just do the same check.
And we backtrack and continue with our checking.
public static void display(int[][] board) {
for(int[] arr : board) {
System.out.println(Arrays.toString(arr));
}
}
public static boolean isSafe(int[][] board, int row, int col, int i) {
//check row
for(int a=0; a<board.length; a++) {
if(board[a][col]==i) {
return false;
}
}
//check col
for(int b=0; b<board.length; b++) {
if(board[row][b]==i) {
return false;
}
}
//check cell
int strow = row-(row%3);
int stcol = col-(col%3);
for(int x=strow; x<strow+3; x++) {
for(int y=stcol; y<stcol+3; y++) {
if(board[x][y]==i) {
return false;
}
}
}
return true;
}
public static boolean sudoku(int [][] board) {
for (int i=0; i<9; i++) {
for (int j=0; j<9; j++) {
int current = board[i][j];
if (current == 0) {
for (int ch = 1; ch <= 9; ch++) {
if (isSafe(board, i, j, ch)) {
board[i][j] = ch;
if (sudoku(board)) {
return true;
}
board[i][j] = 0;
}
}
return false;
}
}
}
return true;
}
public static void main(String args[]) {
int[][] board=
{ {3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0},
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0} };
sudoku(board);
display(board);
}
Here is the output after the change
[3, 1, 6, 5, 7, 8, 4, 9, 2]
[5, 2, 9, 1, 3, 4, 7, 6, 8]
[4, 8, 7, 6, 2, 9, 5, 3, 1]
[2, 6, 3, 4, 1, 5, 9, 8, 7]
[9, 7, 4, 8, 6, 3, 1, 2, 5]
[8, 5, 1, 7, 9, 2, 6, 4, 3]
[1, 3, 8, 9, 4, 7, 2, 5, 6]
[6, 9, 2, 3, 5, 1, 8, 7, 4]
[7, 4, 5, 2, 8, 6, 3, 1, 9]
Note : I changed the return type to true or false inorder to make sure that a particular cell can be filled with a number say x. If its possible we return true and continue with the next cell which is 0, other wise we backtrack and check for other possibilities.
Updates :
The only change you are missing is an else block at the very end because even if the cell is 0 or any other number you are doing recursion sudoku(board, row, col+1);. So just enclose that statement in the else block and will give the desired output.
Code change without changing the return type:
public static void display(int[][] board) {
for(int[] arr : board) {
System.out.println(Arrays.toString(arr));
}
}
public static boolean isSafe(int[][] board, int row, int col, int i) {
//check row
for(int a=0; a<board.length; a++) {
if(board[a][col]==i) {
return false;
}
}
//check col
for(int b=0; b<board.length; b++) {
if(board[row][b]==i) {
return false;
}
}
//check cell
int strow = row-(row%3);
int stcol = col-(col%3);
for(int x=strow; x<strow+3; x++) {
for(int y=stcol; y<stcol+3; y++) {
if(board[x][y]==i) {
return false;
}
}
}
return true;
}
public static void sudoku(int[][] board, int row, int col) {
if(row==board.length) {
display(board);
System.out.println();
return; //modify this to print ans
}
if(col==board.length) {
sudoku(board, row+1, 0);
return;
}
if(board[row][col]==0) {
for(int i=1; i<=9; i++) {
if(isSafe(board, row, col, i)) {
board[row][col]=i;
sudoku(board, row, col+1);
board[row][col]=0;
}
}
}
else
sudoku(board, row, col+1);
}
public static void main(String args[]) {
int[][] board=
{ {3, 0, 6, 5, 0, 8, 4, 0, 0},
{5, 2, 0, 0, 0, 0, 0, 0, 0},
{0, 8, 7, 0, 0, 0, 0, 3, 1},
{0, 0, 3, 0, 1, 0, 0, 8, 0},
{9, 0, 0, 8, 6, 3, 0, 0, 5},
{0, 5, 0, 0, 9, 0, 6, 0, 0},
{1, 3, 0, 0, 0, 0, 2, 5, 0},
{0, 0, 0, 0, 0, 0, 0, 7, 4},
{0, 0, 5, 2, 0, 6, 3, 0, 0} };
sudoku(board, 0, 0);
}
Output :
[3, 1, 6, 5, 7, 8, 4, 9, 2]
[5, 2, 9, 1, 3, 4, 7, 6, 8]
[4, 8, 7, 6, 2, 9, 5, 3, 1]
[2, 6, 3, 4, 1, 5, 9, 8, 7]
[9, 7, 4, 8, 6, 3, 1, 2, 5]
[8, 5, 1, 7, 9, 2, 6, 4, 3]
[1, 3, 8, 9, 4, 7, 2, 5, 6]
[6, 9, 2, 3, 5, 1, 8, 7, 4]
[7, 4, 5, 2, 8, 6, 3, 1, 9]

How to delete last element in array and put new in front?

I have a question concerning Java. I started up new to Java and my google search brought many results but non was the final help.
I created a class to track historical information. I have different values for different days and need to update them un a regular basis. I want to keep track of the last 30 days and created an array with 30 elements. When I call my 'shift' function I want to drop the last n elements and put zeros in front. Here is a minial example for 5 days:
public class Testclass {
private int[] histInfo;
public Element()
{
this.histInfo = new int[5];
}
public void shift_histInfo(long m)
{
//do magic
}
}
What I want shift to do is
INPUT:
histInfo = [50,21,1,45,901]
OPERATION:
shift_histInfo(2);
RESULT:
histInfo = [0,0,50,21,1]
I am thankfull for every kind of help you can support as well for thought-provoking impulses if you think that there is a way more elegant or efficient way.
Best :-)
Unless there are very tight performance constraints using the standard Collection classes will get the job done. Have a look at java.util.LinkedList.
As a programming exercise you might consider creating a ring buffer. The idea being to avoid copying the array on every insertion.
Keep a oldestIndex value.
When writing simply replace item[oldestIndex] and increment oldestIndex.
To iterate you start at oldestIndex and use an increment method to deal with wrapping round to the start of the array.
int nextIndex(int current) {
return (current + 1) % arrayLength;
}
Writing a nice encapsulating class to hide all this would be a good exercise.
You can try this :
public static void shift_histInfo(long m)
{
int[] myIntArray = {50,21,1,45,901};
int[] myIntArray2 = {50,21,1,45,901};
for (int j=0 ;j< myIntArray.length ; j++){
int temp = (int) (j+m);
if (temp >= myIntArray.length){
temp = temp - myIntArray.length;
myIntArray2[temp] = 0;
} else {
myIntArray2[temp] = myIntArray[j];
}
}
for (int j=0 ;j< myIntArray2.length ; j++){
System.out.println(myIntArray2[j]);
}
}
Output :
when shift_histInfo(2) ,
[0,0,50,21,1]
int[] array={1,2,3,4,5,6};
int removelength=2;
int e=1;
while(e<=removelength) {
for(int i=1;i<array.length;i++)
array[array.length-i]=array[array.length-i-1];
e++;
}
for(int i=0;i<removelength;i++) {
array[i]=0;
}
for(int g:array)
{
System.out.print(g);
}
For constraints that you wanted, although I did initialise the data in the same method instead of Element(). I don't know why the parameter is of type long so I left it and made an int local variable.
All it does is copy the index value over to the new array starting at m then increments/iterates until the end of the array.
You can also make the method return type int[] and then simply return changedInfo array. Instead of histInfo = changedInfo.clone();
private int[] histInfo;
public void shift_histInfo(long m) {
int n = (int) m;
this.histInfo = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15};
int length = this.histInfo.length;
int[] changedInfo = new int[length];
if (length - n >= 0) System.arraycopy(histInfo, 0, changedInfo, n + 0, length - n); //Edit: shortened to one line.
histInfo = changedInfo.clone();
System.out.println("Remove: " + n + " - " + Arrays.toString(changedInfo) + "\n");
}
public static void main(String[] args) {
Main main = new Main();
main.shift_histInfo(0);
main.shift_histInfo(30);
main.shift_histInfo(1);
main.shift_histInfo(15);
main.shift_histInfo(29);
}
println:
Remove: 0 - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Remove: 30 - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Remove: 1 - [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
Remove: 15 - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
Remove: 29 - [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]

Shrink Array maintaining number distribution in Java

I have a function that builds an array with N elements, with the distribution to 0 to 100 . For example:
int[] a = {100,80, 50,20, 0};
I want to resize this array to fill a new array with the size of N = 10, but keep the number distribution of the previous array. I think that with some probabilistic distribution, I can achieve this, but don't know how to do it.
Can someone please help?
If I understood the question right, the goal is to redistribute numbers from source array into new array, putting numbers in bins by 10. So, if number is 0 it should go to new array at index 0 (since it's in the range [0, 10]), and if the number is 20 - it should go to index 1 (since, it's in the range [11, 20]), and so forth.
If the assumption is correct, then this is one approach:
import java.util.Arrays;
public class ReDistribution {
public static void main(String[] args) {
int[] distribution = {100, 80, 50, 20, 0};
System.out.println(Arrays.toString(reDistribute(distribution)));
// prints: [0, 20, 0, 0, 50, 0, 0, 80, 0, 100]
}
/**
* Assuming source array contains only integers in range [0, 100], redistributes into array
* index 0, 1, 2, 3, 4, 5, 6, 7, 8, 9
* range [0, 10], [11, 20], [21, 30], [31, 40], [41, 50], [51, 60], [61, 70], [71, 80], [81, 90], [91, 100]
*/
private static int[] reDistribute(int[] source) {
int[] target = new int[10];
for (int num : source) {
target[(num - 1) / 10] = num;
}
return target;
}
}

Mini AES java issue

So I am having some issues running some code for a minu-AES I am making on Java. Each time I run the code I am given a null exception in thread "main" java.lanf.stringIndexOutOfBoundsException: String index out of range: 8
I wonder if this might be a memory issue.
Currently running netbeans 8.2
The code worked before I implemented the classes.
package miniaestesting;
import java.util.*;
class Tables {
public Tables() {
}
public HashMap fillSubTable(HashMap emptyTable, boolean isInverse) {
if (isInverse == false) {
emptyTable.put(0b0000, 0b1110);
emptyTable.put(0b0001, 0b0100);
emptyTable.put(0b0010, 0b1101);
emptyTable.put(0b0011, 0b0001);
emptyTable.put(0b0100, 0b0010);
emptyTable.put(0b0101, 0b1111);
emptyTable.put(0b0110, 0b1011);
emptyTable.put(0b0111, 0b1000);
emptyTable.put(0b1000, 0b0011);
emptyTable.put(0b1001, 0b1010);
emptyTable.put(0b1010, 0b0110);
emptyTable.put(0b1011, 0b1100);
emptyTable.put(0b1100, 0b0101);
emptyTable.put(0b1101, 0b1001);
emptyTable.put(0b1110, 0b0000);
emptyTable.put(0b1111, 0b0111);
}
//Call the .put method, fill the HashMap with the NibbleSub table
else {
emptyTable.put(0b0000, 0b1110);
emptyTable.put(0b0001, 0b0011);
emptyTable.put(0b0010, 0b0100);
emptyTable.put(0b0011, 0b1000);
emptyTable.put(0b0100, 0b0001);
emptyTable.put(0b0101, 0b1100);
emptyTable.put(0b0110, 0b1010);
emptyTable.put(0b0111, 0b1111);
emptyTable.put(0b1000, 0b0111);
emptyTable.put(0b1001, 0b1101);
emptyTable.put(0b1010, 0b1001);
emptyTable.put(0b1011, 0b0110);
emptyTable.put(0b1100, 0b1011);
emptyTable.put(0b1101, 0b0010);
emptyTable.put(0b1110, 0b0000);
emptyTable.put(0b1111, 0b0101);
}
return emptyTable;
}
public int[][] fillHexTable() {
int[][] table = {
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF},
{0, 2, 4, 6, 8, 0xA, 0xC, 0xE, 3, 1, 7, 5, 0xB, 9, 0xF, 0xD},
{0, 3, 6, 5, 0xC, 0xF, 0xA, 9, 0xB, 8, 0xD, 0xE, 7, 4, 1, 2},
{0, 4, 8, 0xC, 3, 7, 0xB, 0xF, 6, 2, 0xE, 0xA, 5, 1, 0xD, 9},
{0, 5, 0xA, 0xF, 7, 2, 0xD, 8, 0xE, 0xB, 4, 1, 9, 0xC, 3, 6},
{0, 6, 0xC, 0xA, 0xB, 0xD, 7, 1, 5, 3, 9, 0xF, 0xE, 8, 2, 4},
{0, 7, 0xE, 9, 0xF, 8, 1, 6, 0xD, 0xA, 3, 4, 2, 5, 0xC, 0xB},
{0, 8, 3, 0xB, 6, 0xE, 5, 0xD, 0xC, 4, 0xF, 7, 0xA, 2, 9, 1},
{0, 9, 1, 8, 2, 0xB, 3, 0xA, 4, 0xD, 5, 0xC, 6, 0xF, 7, 0xE},
{0, 0xA, 7, 0xD, 0xE, 4, 9, 3, 0xF, 5, 8, 2, 1, 0xB, 6, 0xC},
{0, 0xB, 5, 0xE, 0xA, 1, 0xF, 4, 7, 0xC, 2, 9, 0xD, 6, 8, 3},
{0, 0xC, 0xB, 7, 5, 9, 0xE, 2, 0xA, 6, 1, 0xD, 0xF, 3, 4, 8},
{0, 0xD, 9, 4, 1, 0xC, 8, 5, 2, 0xF, 0xB, 6, 3, 0xE, 0xA, 7},
{0, 0xE, 0xF, 1, 0xD, 3, 2, 0xC, 9, 7, 6, 8, 4, 0xA, 0xB, 5},
{0, 0xF, 0xD, 2, 9, 6, 4, 8, 1, 0xE, 0xC, 3, 8, 7, 5, 0xA}
};
// Return the hex-multiplication table used in MixColumns
return table;
}
}
class Substitutions {
private Tables tables;
private HashMap<Integer, Integer> subTable;
public Substitutions() {
this.tables = new Tables();
this.subTable = new HashMap<>();
}
public int keyNibbleSub(int nibble) {
tables.fillSubTable(subTable, false); // Call a helper method to fill the HashMap with key-value pairs
System.out.println(subTable.get(nibble)); // Get the substitution value for the nibble and return it
return 5;
}
public int[][] nibbleSub(int[][] cipherState, boolean isInverse) {
int[][] nextCipherState = new int[2][2]; // Declare and initialise empty 2x2 array
tables.fillSubTable(subTable, isInverse); // Call a helper method to fill the HashMap with key-value pairs
for (int row = 0; row < 1; row++) {
for (int col = 0; col < 1; col++) {
// For each element in block
nextCipherState[row][col] = subTable.get(cipherState[row][col]);
// Call the .get method on the HashMap, using the element as a key-lookup
// Assign the returned element to the index in returnBlock
}
}
return nextCipherState;
}
public int getKeyNibbleSub(int nibble) {
return keyNibbleSub(nibble);
}
public int[][] getNibbleSub(int[][] cipherState, boolean isInverse) {
return
nibbleSub(cipherState, isInverse);
}
}
class KeySet {
//-----------------------------//Fields//-----------------------------//
private int[][] key_0, key_1, key_2;
private Substitutions substitutions;
private Tables tables;
//-----------------------------//Constructor//-----------------------------//
public KeySet(int[][] startingKey) {
this.substitutions = new Substitutions();
this.key_0 = startingKey;
this.key_1 = genKey(key_0, 1);
this.key_2 = genKey(key_1, 2);
}
//-----------------------------//Methods//-----------------------------//
private int[][] genKey(int[][] key, int roundConst) {
int[][] newKey = new int[2][2]; // Declare an empty 2x2 array to store the new key
newKey[0][0] = key[0][0] ^ substitutions.keyNibbleSub(key[1][1]) ^
roundConst;
// For the first nibble in the new key,
// XOR the first value in the given key
// with the nibbleSub of the final value in the given key
//, and with the rounding constant variable
newKey[0][1] = key[0][1] ^ newKey[0][0];
newKey[1][0] = key[1][0] ^ newKey[0][1];
newKey[1][1] = key[1][1] ^ newKey[1][0];
// Generate the other three nibbles
return newKey;
}
//----Getter methods for full implementation---//
public int[][] getKey_0() {
return key_0;
}
public int[][] getKey_1() {
return key_1;
}
public int[][] getKey_2() {
return key_2;
}
}
class MiniAES {
private KeySet keys;
private String startingString;
private String finalString;
private int[][] character;
private int[][] cipherState;
private Substitutions substitutions;
private Tables tables;
public MiniAES(String startingString, String startKey) {
this.substitutions = new Substitutions();
this.tables = new Tables();
this.startingString = startingString;
this.keys = new KeySet(convertToArray(startKey));
}
public String encryptString() {
//ystem.out.println(startingString);
for (int i = 0; i < this.startingString.length() - 1; i++) {
character =
convertToArray(Integer.toBinaryString(startingString.charAt(i)));
cipherState = encryptChar(character);
finalString = finalString + convertToString(cipherState);
}
return finalString;
}
public static String convertToString(int[][] array) {
String[][] toFill = new String[2][2];
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array[0].length; j++) {
toFill[i][j] = Integer.toString(array[i][j]);
while (toFill[i][j].length() <= 3) {
toFill[i][j] = "0" +
toFill[i][j];
}
}
}
String charAsBinaryString = toFill[0][0] + toFill[0][1] + toFill[1][0]
+ toFill[1][1];
int asInteger = Integer.parseInt(charAsBinaryString, 2);
String charAsString = Character.toString((char) asInteger);
return charAsString;
}
public static int[][] convertToArray(String toConvert) {
int[][] newBlock = new int[2][2];
newBlock[0][0] = Integer.parseInt(toConvert.substring(0, 4));
newBlock[0][1] = Integer.parseInt(toConvert.substring(4, 8));
newBlock[1][0] = Integer.parseInt(toConvert.substring(8, 12));
newBlock[1][1] = Integer.parseInt(toConvert.substring(12, 16));
return newBlock;
}
private int[][] encryptChar(int[][] character) {
addRoundKey(character, keys.getKey_0());
cipherState = substitutions.nibbleSub(cipherState, false);
shiftRows();
mixColumns();
addRoundKey(cipherState, keys.getKey_1());
cipherState = substitutions.nibbleSub(cipherState, false);
shiftRows();
addRoundKey(cipherState, keys.getKey_2());
return cipherState;
}
private void addRoundKey(int[][] cipherState, int[][] key) {
int[][] nextCipherState = new int[2][2]; // Declare and initialise an empty 2x2 array
for (int row = 0; row < cipherState.length; row++) {
for (int col = 0; col < cipherState[0].length; col++) {
// For each element in cipherState
nextCipherState[row][col] = cipherState[row][col] ^ key[row]
[col]; // XOR it with the corresponding element in key
// Assign it to the same index in nextCipherState
}
}
this.cipherState = nextCipherState;
}
private void shiftRows() {
int[][] nextCipherState = new int[2][2]; // Declare and initialise new array
nextCipherState[0][0] = this.cipherState[0][0];
nextCipherState[0][1] = this.cipherState[0][1];
//Copy the values from cipherState into the top row of the new array
nextCipherState[1][0] = this.cipherState[1][1];
nextCipherState[1][1] = this.cipherState[1][0];
//Copy the values from cipherState into the bottom row of the new array, in reverse order
this.cipherState = nextCipherState;
}
private void mixColumns() {
int[][] nextCipherState = new int[2][2]; // Declare and initialise empty 2x2 array
nextCipherState[0][0] = hexSubstitution(this.cipherState[0][0],
this.cipherState[1][0], 0);
nextCipherState[1][0] = hexSubstitution(this.cipherState[0][0],
this.cipherState[1][0], 1);
nextCipherState[0][1] = hexSubstitution(this.cipherState[0][1],
this.cipherState[1][1], 0);
nextCipherState[01][1] = hexSubstitution(this.cipherState[0][1],
this.cipherState[1][1], 1);
this.cipherState = nextCipherState;
}
private int hexSubstitution(int topRowElement, int bottomRowElement, int
constRow) {
int[][] hexTable = tables.fillHexTable(); // Declare an empty 2d array and call the getHexTable() helper method to fill it
// Due to the large size of the hex table, this is implemented for readability.
int[][] constantMatrix = {
{0b0011, 0b0010},
{0b0010, 0b0011}}; // declare and fill the 2d array which stores the constant matrix
int hexCol, XOR_operand_1, XOR_operand_2; // Declare variables
hexCol = constantMatrix[constRow][0]; // Get index for the hex table lookup
XOR_operand_1 = hexTable[hexCol][topRowElement]; // Find the appropriate element in hexTable and assign to XOR_operand_1
hexCol = constantMatrix[constRow][1]; // // Get index for the hex table lookup
XOR_operand_2 = hexTable[hexCol][bottomRowElement]; // Find the appropriate elemen tin hexTable and assign to XOR_operand_2
return XOR_operand_1 ^ XOR_operand_2; // XOR the two operands and return the result
}
}
package miniaestesting;
public class MiniAESTesting {
public static void main(String[] args) {
int[][] startKey = {
{0b0011, 0b1001},
{0b0110, 0b0111}};
MiniAES encryption1 = new MiniAES("Hello", "0010101100100011");
System.out.println(encryption1.encryptString());
}
}

Sorting 2d arrays using Java Comparator

I have a 2d array called interval[g][2] where g is some number.
Currently, I'm trying to sort the array first by increasing order in the first element, and if they are equal, sort by decreasing order in the second element.
I've attempted this in two ways:
1) Using Java 8's Comparator.comparing method:
Arrays.sort(interval, Comparator.comparing((int[] arr) -> arr[0]));
2) Using Arrays.sort:
Arrays.sort(interval, new Comparator<int[]>() {
#Override
public int compare(int[] s1, int[] s2) {
if (s1[0] > s2[0])
return 1;
else if (s1[0] < s2[0])
return -1;
else {
if(s1[1] < s2[1])
return 1;
else if (s1[1] > s2[1])
return -1;
else
return 0;
}
}
});
The first method returns a partially sorted list.
[[0, 10], [10, 30], [30, 50]]
[[0, 10], [3, 19], [35, 45]]
[[10, 30], [27, 33], [30, 50]]
[[-10, 10], [0, 20], [35, 45]]
[[10, 30], [20, 40], [30, 50]]
[[0, 20], [8, 28], [37, 43]]
[[0, 20], [15, 35], [37, 43]]
[[0, 0], [8, 28], [10, 40]]
As you can see, it's sorting things in a set of three tuples.
The second method doesn't sort the array at all. Can I not sort using primitive data types? Can anyone advise?
I think you're looking for this:
Arrays.sort(interval, Comparator.comparingInt((int[] arr) -> arr[0]).thenComparing(Comparator.comparingInt((int[] arr) -> arr[1]).reversed()));
Or if you want to go with the custom Comparator:
Arrays.sort(interval, new Comparator<int[]>() {
#Override
public int compare(int[] o1, int[] o2) {
int result = Integer.compare(o1[0], o2[0]);
if (result == 0) {
result = Integer.compare(o2[1], o1[1]);
}
return result;
}
});
int[][] interval = new int[][] { {0, 10}, {10, 30}, {30, 50}, {0, 10}, {3, 19}, {35, 45}, {10, 30}, {27, 33}, {30, 50}, {-10, 10}, {0, 20}, {35, 45}, {10, 30}, {20, 40}, {30, 50}, {0, 20}, {8, 28}, {37, 43}, {0, 20}, {15, 35}, {37, 43}, {0, 0}, {8, 28}, {10, 40} };
Arrays.sort(interval, Comparator.<int[]>comparingInt(arr -> arr[0]).thenComparing(arr -> arr[1], Comparator.<Integer>naturalOrder().reversed()));
Stream.of(interval).forEachOrdered(ints -> System.out.println(Arrays.toString(ints)));

Categories