Problem:
I have 2D array which is filled with numbers. I have to output it in a way that it shows: "*" between neighbours with different values and with " " if values are the same.
Example:
*********
*1 1*3*4*
***** * *
*2 2*3*4*
*********
I have tried many things like creating another array with [Nx2][Mx2] size or System.out.format, but in the end it's never formatted the way I like. Any suggestions how can I solve this?
private static void changeColumn(int[][] secondLayerArr, int n, int m) {
String[][] finalLayerArr = new String[n * 2 - 1][m];
int finalLayerRow = -2;
//second layer output
for (int i = 0; i < n; i++) {
finalLayerRow += 2;
for (int j = 0; j < m; j++) {
if (j < m - 1) {
if (secondLayerArr[i][j] != secondLayerArr[i][j + 1]) {
finalLayerArr[finalLayerRow][j] = (secondLayerArr[i][j]) + "*";
// System.out.print(secondLayerArr[i][j] + "*");
} else {
finalLayerArr[finalLayerRow][j] = (secondLayerArr[i][j]) + " ";
// System.out.print(secondLayerArr[i][j]);
}
} else {
finalLayerArr[finalLayerRow][j] = (secondLayerArr[i][j]) + "*";
//System.out.print(secondLayerArr[i][j]+"*");
}
}
}
printColumn(finalLayerArr);
}
public static void changeRow(String[][] finalLayerArr) {
for (int i = 0; i < finalLayerArr[0].length; i++) {
System.out.print("***");
}
System.out.println();
for (int i = 0; i < finalLayerArr.length; i++) {
System.out.print("*");
for (int j = 0; j < finalLayerArr[0].length; j++) {
if (finalLayerArr[i][j] == null) {
if (finalLayerArr[i - 1][j].equals(finalLayerArr[i + 1][j])) {
finalLayerArr[i][j] = " ";
} else {
finalLayerArr[i][j] = "*";
}
}
System.out.printf("%2s", finalLayerArr[i][j], "");
}
System.out.println();
}
}
It shows something like the result I want but its not formatted like in table.
Loop through the 2d array by first looping through the number of arrays inside the array, then looping through each individual one.
Inside the individual arrays, check if this is the first item in the array. If so, print a *. Then check whether the one before is equal etc.
For the " leave " " between neighbouring rows [which have the same item]", we can store the star line inside a StringBuilder and print it out at the end.
int[][] arr = {{1, 1, 3, 4}, {2, 2, 3, 4}};
int lineLength = arr[0].length * 2 + 1;
for (int i = 0; i < lineLength - 1; i++) {
System.out.print("*");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
int[] current = arr[i];
int before = 0;
StringBuilder str = new StringBuilder();
for (int j = 0; j < current.length; j++) {
int rn = current[j];
if (j == 0) {
System.out.print("*");
System.out.print(rn);
} else {
if (before == rn) {
System.out.print(" ");
System.out.print(rn);
} else {
System.out.print("*");
System.out.print(rn);
}
}
if (i != arr.length - 1 && arr[i + 1][j] == rn) {
str.append("* ");
} else {
str.append("**");
}
before = rn;
}
if (i != arr.length - 1) {
System.out.println();
System.out.println(str.toString());
}
}
System.out.println();
for (int i = 0; i < lineLength - 1; i++) {
System.out.print("*");
}
Which prints:
********
*1 1*3*4
**** * *
*2 2*3*4
********
You could loop through every line that isn't the last, then every letter that isn't the last in that array, and checks if it is equal to the one to the right and the one to the bottom. If it is, print the appropriate thing.
Something along these lines:
public class FormattingArray {
public static void printFormattedInts(int[][] unformattedInts) {
// getting maximum digits per number
int maxDigits = 0;
for (int[] intArray : unformattedInts) {
for (int num : intArray) {
if (lengthOfInt(num) > maxDigits) {
maxDigits = lengthOfInt(num);
}
}
}
// printing first line (purely aesthetic)
System.out.print("*".repeat(unformattedInts[0].length * maxDigits + unformattedInts[0].length + 1));
System.out.println();
// printing each row
for (int row = 0; row < unformattedInts.length - 1; row ++) {
String lowerRow = "*"; // the row to print below this one
System.out.print("*");
for (int i = 0; i < unformattedInts[row].length - 1; i ++) {
if (lengthOfInt(unformattedInts[row][i]) < maxDigits) {
System.out.print("0".repeat(maxDigits - (lengthOfInt(unformattedInts[row][i]))));
}
System.out.print(unformattedInts[row][i]);
if (unformattedInts[row][i] == unformattedInts[row][i + 1]) {
System.out.print(" ");
} else {
System.out.print("*");
}
if (unformattedInts[row][i] == unformattedInts[row + 1][i]) {
lowerRow += " ".repeat(maxDigits);
lowerRow += "*";
} else {
lowerRow += "*".repeat(maxDigits + 1);
}
}
if (lengthOfInt(unformattedInts[row][unformattedInts[row].length - 1]) < maxDigits) {
System.out.print("0".repeat(maxDigits - (lengthOfInt(unformattedInts[row][unformattedInts[row].length - 1]))));
}
System.out.print(unformattedInts[row][unformattedInts[row].length - 1]);
System.out.println("*");
// doing last char
if (unformattedInts[row][unformattedInts[row].length - 1] == unformattedInts[row + 1][unformattedInts[row].length - 1]) {
lowerRow += " ".repeat(maxDigits);
lowerRow += "*";
} else {
lowerRow += "*".repeat(maxDigits + 1);
}
System.out.println(lowerRow);
}
// doing last row
System.out.print("*");
for (int i = 0; i < unformattedInts[unformattedInts.length - 1].length - 1; i ++) {
if (lengthOfInt(unformattedInts[unformattedInts.length - 1][i]) < maxDigits) {
System.out.print("0".repeat(maxDigits - lengthOfInt(unformattedInts[unformattedInts.length - 1][unformattedInts[0].length - 1])));
}
System.out.print(unformattedInts[unformattedInts.length - 1][i]);
if (unformattedInts[unformattedInts.length - 1][i] == unformattedInts[unformattedInts.length - 1][i + 1]) {
System.out.print(" ");
} else {
System.out.print("*");
}
}
if (lengthOfInt(unformattedInts[unformattedInts.length - 1][unformattedInts[unformattedInts.length - 1].length - 1]) < maxDigits) {
System.out.print("0".repeat(maxDigits - lengthOfInt(unformattedInts[unformattedInts.length - 1][unformattedInts[unformattedInts.length - 1].length - 1])));
}
System.out.print(unformattedInts[unformattedInts.length - 1][unformattedInts[unformattedInts.length - 1].length - 1]);
System.out.println("*");
System.out.print("*".repeat(unformattedInts[0].length * maxDigits + unformattedInts[0].length + 1));
System.out.println();
}
public static int lengthOfInt(int num) {
return String.valueOf(num).length();
}
}
Hope this helps :)
You can compose an array of strings consisting of numbers from the first array and their neighboring elements, i. e. spaces and asterisks. Format them if necessary with a leading zeros and appropriate count of neighboring elements. For each row, create two arrays of strings, i. e. elements with their horizontal neighbours and intermediate array with vertical neighbours, plus leading and trailing rows of asterisks. Then flatten them vertically and join elements of the rows into one string horizontally.
Try it online!
int[][] arr1 = {
{1, 1, 3, 3, 4, 6, 5, 6, 8, 75},
{2, 2, 2, 3, 4, 5, 5, 5, 8, 8},
{3, 3, 5, 5, 6, 7, 7, 5, 2, 8}};
// numbers format, digits count
int s = 2;
// formatted array representation
// with neighbouring elements
String[] arr2 = IntStream
// iterate over indices of the rows of the
// array, plus leading row of asterisks
.range(-1, arr1.length)
// for each row create two arrays of strings:
// horizontal neighbours and vertical neighbours
.mapToObj(i -> {
// assume the lengths of the rows are identical
int length = arr1[0].length * s * 2 - s + 2;
String[] asterisks = new String[length];
Arrays.fill(asterisks, "*");
if (i == -1)
// leading row of asterisks
return Stream.of(null, asterisks);
else
// iterate over indices of the elements of the rows,
// add asterisks between neighbours with different
// values and spaces if values are the same
return Stream.of(IntStream.range(0, arr1[i].length)
// horizontal neighbours
.mapToObj(j -> {
// formatted representation
// of the element of the row,
// with a leading zeros if necessary
String val = String.format(
"%0" + s + "d", arr1[i][j]);
if (j == 0)
// leading asterisk
val = "*" + val;
if (j == arr1[i].length - 1)
// trailing asterisk
val += "*";
else
// neighbour element
val += arr1[i][j] == arr1[i][j + 1] ?
" ".repeat(s) : "*".repeat(s);
return val;
}).toArray(String[]::new),
// second array
(i == arr1.length - 1) ?
// trailing row of asterisks
asterisks :
// vertical neighbours
IntStream.range(0, arr1[i].length)
.mapToObj(j -> {
String val = "";
if (j == 0)
// leading asterisk
val = "*";
// neighbour element
val += (arr1[i][j] == arr1[i + 1][j] ?
" ".repeat(s) : "*".repeat(s));
if (j == arr1[i].length - 1)
// trailing asterisk
val += "*";
else
// intermediate asterisks
val += "*".repeat(s);
return val;
}).toArray(String[]::new));
}).flatMap(Function.identity())
// skip first null
.skip(1)
// Stream<Stream<String>>
.map(Arrays::stream)
// join each row into one string
.map(stream -> stream.collect(Collectors.joining()))
.toArray(String[]::new);
// output
Arrays.stream(arr2).forEach(System.out::println);
Output:
****************************************
*01 01**03 03**04**06**05**06**08**75*
************* ** ****** ****** *****
*02 02 02**03**04**05 05 05**08 08*
***************************** ****** *
*03 03**05 05**06**07 07**05**02**08*
****************************************
Related
public int[] nextSmallerNumber(int[] array){}
Given an array of integers, return an array containing the indices of the next smaller number of every number or -1 if the next smaller number does not exist.
Example for clarification :
input: 10, 9, 2, 7, 6, 1, 2
output: 1, 2, 5, 4, 5, -1, -1
(((the algorithm should run in O(n) time)))
my code
public void nextSmallerNumber(int[] array) {
int next, i, j;
for (i = 0; i < array.length; i++) {
next = -1;
for (j = i + 1; j < array.length; j++) {
if (array[i] > array[j]) { next = array[j]; }}
System.out.println(i + " , " + next); }
}
but it I can't handle -1 case and I can't make it in O(n).
public static void nextSmallerNumber(int[] arr)
{
Stack<Integer> s = new Stack<Integer>();
int n=arr.length
s.push(arr[0]);
for (int i = 1; i < n; i++) {
if (s.empty()) {
s.push(arr[i]);
continue;
}
while (s.empty() == false && s.peek() > arr[i]) {
System.out.println(s.peek() + " --> " + arr[i]);
s.pop();
}
s.push(arr[i]);
}
while (s.empty() == false) {
System.out.println(s.peek() + " --> " + "-1");
s.pop();
}
}
I need a code for making a Pascal's triangle. This code is for a Right triangle, but I need it to be a Pascal's triangle. It needs to have 10 rows and does have a gap in the middle of the Top and the Bottom.
Can anyone please help me on this? for loops will be fine.
public static int get_pascal(int row, int col) {
if (col == 0 || col == row) {
return 1;
} else {
return get_pascal(row - 1, col - 1) + get_pascal(row - 1, col);
}
}
public static void main(String[] args) {
//row size variable
int rowNum = 5;
levels = new String[rowNum];
int i = 0;
int arIndex = 0;
System.out.println(recurseRow(i, rowNum, arIndex));
System.out.println(" ");
System.out.println(upsideDown(rowNum - 1));
}
//Recursion for row
public static String recurseRow(int i, int rowNum, int arrayIndex) {
if (i == rowNum)
return "";
else {
int k = 0;
int next = i + 1;
String str = recurseCol(i, k);
levels[arrayIndex] = str;
arrayIndex += 1;
return str + "\n" + recurseRow(next, rowNum, arrayIndex);
}
}
//Recursion for column
public static String recurseCol(int i, int k) {
if (k > i)
return "";
else {
int next = k + 1;
return get_pascal(i, k) + " " + recurseCol(i, next);
}
}
//upside down recursion
public static String upsideDown(int index) {
if (index < 0) {
return "";
} else {
String str = levels[index];
index -= 1;
return str + "\n" + upsideDown(index);
}
}
Pascal's triangle - is a triangular array of binomial coefficients where the elements of the first row and column are equal to one, and all other elements are the sum of the previous element in the row and column.
T[i][j] = T[i][j-1] + T[i-1][j];
You can create an iterative method to populate such an array:
public static int[][] pascalsTriangle(int n) {
// an array of 'n' rows
int[][] arr = new int[n][];
// iterate over the rows of the array
for (int i = 0; i < n; i++) {
// a row of 'n-i' elements
arr[i] = new int[n - i];
// iterate over the elements of the row
for (int j = 0; j < n - i; j++) {
if (i == 0 || j == 0) {
// elements of the first row
// and column are equal to one
arr[i][j] = 1;
} else {
// all other elements are the sum of the
// previous element in the row and column
arr[i][j] = arr[i][j - 1] + arr[i - 1][j];
}
}
}
return arr;
}
public static void main(String[] args) {
int n = 10;
System.out.println("n = " + n);
System.out.println("Pascal's triangle:");
int[][] arr = pascalsTriangle(n);
for (int[] row : arr) {
for (int element : row)
System.out.printf("%2d ", element);
System.out.println();
}
}
Output:
n = 10
Pascal's triangle:
1 1 1 1 1 1 1 1 1 1
1 2 3 4 5 6 7 8 9
1 3 6 10 15 21 28 36
1 4 10 20 35 56 84
1 5 15 35 70 126
1 6 21 56 126
1 7 28 84
1 8 36
1 9
1
See also: Array of binomial coefficients
You can add prefix of multiple spaces where you recursively create a row: instead of
String str = recurseCol(i, k);
you'll have
String str = "";
for (int spaces = 0; spaces < 2 * (rowNum - i - 1); spaces++) {
str += " ";
}
str += recurseCol(i, k);
You also need to format all numbers to have the same width inside recurseCol, for example now all numbers will be 3 digits wide:
return String.format("%3d %s", get_pascal(i, k), recurseCol(i, next));
The resulting code of the modified methods:
//Recursion for row
public static String recurseRow(int i, int rowNum, int arrayIndex) {
if( i == rowNum)
return "";
else {
int k = 0;
int next = i + 1;
String str = "";
for (int spaces = 0; spaces < 2 * (rowNum - i - 1); spaces++) {
str += " ";
}
str += recurseCol(i, k);
levels[arrayIndex] = str;
arrayIndex += 1;
return str + "\n" + recurseRow(next, rowNum, arrayIndex);
}
}
//Recursion for column
public static String recurseCol(int i, int k) {
if(k > i)
return "";
else {
int next = k + 1;
return String.format("%3d %s", get_pascal(i, k), recurseCol(i, next));
}
}
The "magic" numbers 2 and 3 are related to each other: if each number is n-digits wide, then we need to add a prefix to the string consisting of n-1 spaces repeated rowNum - i - 1 times.
There are other methods to achieve these, but I think that the above allows to get the result with minimum modifications.
I'm supposed to write a program that reads an array of ints and outputs the number of "triples" in the array.
A "triple" is three consecutive ints in increasing order differing by 1 (i.e. 3,4,5 is a triple, but 5,4,3 and 2,4,6 are not).
How do I check for the "triples"?
Current Code:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] array = new int[size];
int iterator = 0;
for(int i = 0; i < size; i++){
array[i] = scanner.nextInt();
} for(int j =0; j < size; j++){
iterator++;
}
}
}
The following code loops through the entire array of integers. Inside of the loop it is checked if the third integer exists inside of the array ((i + 2) < array.Length) and the other 2 conditions are all about whether value1 is the same as the value2 decreased by 1 (array[i] == array[i + 1] - 1 and array[i + 1] == array[i + 2] - 1):
for (int i = 0; i < array.Length; i++)
{
if((i + 2) < array.Length && array[i] == array[i + 1] - 1 && array[i + 1] == array[i + 2] - 1)
System.out.println("Three values at indexes" + i + " " + (i + 1) + " and " + (i + 2) + " are a triple");
}
The code below is C# and sadly not compatible to Java that easily, I'll just leave that here for anyone who wants to know how its handled in C# (the vt variable is a so called ValueTriple):
(int, int, int) vt;
for (var i = 0; i < array.Length; i++)
{
if (i + 2 >= array.Length) continue;
vt = (array[i], array[i + 1], array[i + 2]);
if (vt.Item1 == vt.Item2 - 1 && vt.Item2 == vt.Item3 - 1)
Console.WriteLine($"Three values at indexes {i}, {i + 1} and {i + 2} (Values: {array[i]}, {array[i + 1]}, {array[i + 2]}) are a triple");
}
You may try following code
import java.util.Scanner;
public class Triplet {
public static void main(String[] args) {
// put your code here
Scanner scanner = new Scanner(System.in);
int size = scanner.nextInt();
int[] array = new int[size];
for(int i = 0; i < size; i++){
array[i] = scanner.nextInt();
}
Integer counter = 0;
for(int i = 0; i < size-2; i++) {
if(array[i] == array[i+1] - 1 && array[i] == array[i+2] - 2) { //checking if three consecutive ints in increasing order differing by 1
counter++;
}
}
System.out.println(counter);
}
}
Hope this will help.
A method to find out the number of triplets could look like this. You then just have to call the method depending how your input is obtained and you wish to present the result.
public static int getNumberOfTriplets(int[] toBeChecked) {
int numberOfTriplets = 0;
int nextIndex = 0;
while (nextIndex < toBeChecked.length - 2) {
int first = toBeChecked[nextIndex];
int second = toBeChecked[nextIndex + 1];
int third = toBeChecked[nextIndex + 2];
if ((first + 1 == second) && (second + 1 == third)) {
numberOfTriplets++;
}
nextIndex++;
}
return numberOfTriplets;
}
Regardless of allowing the numbers to be in more than one triplet, the answer is fairly similar in how I would personally approach it:
//determines if the input sequence is consecutive
public boolean isConsecutive(int... values) {
return IntStream.range(1, values.length)
.allMatch(i -> values[i] == values[i - 1] + 1);
}
public int countTriples(int[] input, boolean uniques) {
if (input.length < 3) {
return 0;
}
int back = 0;
for(int i = 2; i < input.length; i++) {
if (isConsecutive(input[i - 2], input[i - 1], input [i]) {
back++;
if (uniques) { //whether to disallow overlapping numbers
i += 2; //triple found, ignore the used numbers if needed
}
}
}
return back;
}
Then in calling it:
Int[] input = new int[] {1, 2, 3, 5, 6, 7, 8};
countTriples(input, true); //3
countTriples(input, false); //2
So I have been asked this question and I could only solve the top part of the code, I am stuck on the bottom part.
Write a Java program called EmptyDiamond.java that contains a method that takes an integer n and prints a empty rhombus on 2n − 1 lines as shown below. Sample output where n = 3:
1
2 2
3 3
2 2
1
Here's my code so far:
public static void shape(int n) {
//TOP PART
for (int i = 1; i <= (n - 1); i++) {
System.out.print(" ");
}
System.out.println(1);
for (int i = 2; i <= n; i++) {
for (int j = 1; j <= (n - i); j++) {
System.out.print(" ");
}
System.out.print(i);
for (int j = 1; j <= 2 * i - n + 1; j++) {
System.out.print(" ");
}
System.out.println(i);
}
//BOTTOM PART (The messed up part)
for (int i = n + 1; i <= 2 * n - 2; i++) {
for (int j = 1; j <= n - i; j++) {
System.out.print(" ");
}
System.out.print(i);
for (int j = 1; j <= n; j++) {
System.out.print(" ");
}
System.out.print(i);
}
for (int i = 1; i <= (n - 1); i++) {
System.out.print(" ");
}
System.out.println(1);
}
public static void main(String[] args) {
shape(4);
}
Maybe a little bit late, but because the bottom part of your message is just the first part mirrored you can use a Stack to print the message in reverse order:
public static void main(String[] args) {
int maxNumber = 3;
Stack<String> message = new Stack<>();
// upper part
for (int row = 0; row < maxNumber; row++) {
int prefix = maxNumber - (row + 1);
int spaces = row >= 2 ? row * 2 - 1 : row;
String line = getLine(row, prefix, spaces);
System.out.println(line);
if (row != maxNumber - 1)
message.add(line);
}
// bottom part
while (!message.isEmpty())
System.out.println(message.pop());
}
public static String getLine(int row, int prefix, int spaces) {
StringBuilder line = new StringBuilder("_".repeat(prefix));
line.append(row + 1);
if (row != 0) {
line.append("_".repeat(spaces));
line.append(row + 1);
}
return line.toString();
}
Output:
__1
_2_2
3___3
_2_2
__1
You can of course use any method you want to fill the stack (i.e. to generate the upper part of your message) like with the method this question suggessted. This upper part I describe contains the first line (inclusive) up to the middle line (exclusive).
Here is the program for printing empty diamond:
int n = 3; //change the value of n to increase the size of diamond
int upperCount = 1;
for (int i = n; i >= 1; i--) {
for (int j = i; j >= 1; j--) {
System.out.print(" ");
}
System.out.print(upperCount);
for (int j = 0; j <= upperCount - 2; j++) {
System.out.print(" ");
}
for (int j = 0; j <= upperCount - 2; j++) {
System.out.print(" ");
}
if (upperCount != 1) {
System.out.print(upperCount);
}
upperCount++;
System.out.print("\n");
}
int lowerCount = n - 1;
for (int i = 1; i <= n - 1; i++) {
for (int j = 0; j <= i; j++) {
System.out.print(" ");
}
System.out.print(lowerCount);
for (int j = 0; j <= lowerCount - 2; j++) {
System.out.print(" ");
}
for (int j = 0; j <= lowerCount - 2; j++) {
System.out.print(" ");
}
if (lowerCount != 1) {
System.out.print(lowerCount);
}
lowerCount--;
System.out.print("\n");
}
Do following changes in the Bottom Part of your code:
int lowerCount = n - 1;
for (int i = n - 1; i >= 2; i--) {
for (int j = 1; j <= (n - i); j++) {
System.out.print(" ");
}
System.out.print(i);
for (int j = 1; j <= lowerCount; j++) {
System.out.print(" ");
}
System.out.print(i);
lowerCount -= 2;
}
You can print an empty diamond shape with numbers using two nested for loops over rows and columns from -n to n. The diamond shape is obtained when iAbs + jAbs == n:
int n = 2;
for (int i = -n; i <= n; i++) {
// absolute value of 'i'
int iAbs = Math.abs(i);
for (int j = -n; j <= n; j++) {
// absolute value of 'j'
int jAbs = Math.abs(j);
// empty diamond shape
System.out.print(iAbs + jAbs == n ? jAbs + 1 : " ");
if (j < n) {
System.out.print(" ");
} else {
System.out.println();
}
}
}
Output:
1
2 2
3 3
2 2
1
You can separately define width and height:
int m = 4;
int n = 2;
int max = Math.max(m, n);
for (int i = -m; i <= m; i++) {
// absolute value of 'i'
int iAbs = Math.abs(i);
for (int j = -n; j <= n; j++) {
// absolute value of 'j'
int jAbs = Math.abs(j);
// empty diamond shape
System.out.print(iAbs + jAbs == max ? jAbs + 1 : " ");
if (j < n) {
System.out.print(" ");
} else {
System.out.println();
}
}
}
Output:
1
2 2
3 3
3 3
2 2
1
See also:
• Filling a 2d array with numbers in a rhombus form
• How to print a diamond of random numbers?
java-11
Using String#repeat introduced as part of Java-11, you can do it using a single loop.
public class Main {
public static void main(String[] args) {
int n = 3;
for (int i = 1 - n; i < n; i++) {
int x = Math.abs(i);
System.out.println(" ".repeat(x) + (n - x)
+ " ".repeat(Math.abs((n - x) * 2 - 3))
+ ((i == 1 - n || i == n - 1) ? "" : (n - x)));
}
}
}
Output:
1
2 2
3 3
2 2
1
You can print a variant of the diamond simply by increasing the amount of space by one character:
public class Main {
public static void main(String[] args) {
int n = 3;
for (int i = 1 - n; i < n; i++) {
int x = Math.abs(i);
System.out.println(" ".repeat(x) + (n - x)
+ " ".repeat(Math.abs((n - x) * 2 - 3))
+ ((i == 1 - n || i == n - 1) ? "" : (n - x)));
}
}
}
Output:
1
2 2
3 3
2 2
1
Alternative solution:
public static void main(String[] args) {
int n = 7;
for (int i = -n; i <= n; i++) {
for (int j = -n; j <= n; j++) {
// edge of the diamond
int edge = Math.abs(i) + Math.abs(j);
// diamond shape with numbers
if (edge == n) System.out.print(n - Math.abs(i) + 1);
// beyond the edge && in chessboard order || vertical borders
else if (edge > n && (i + j) % 2 != 0 || Math.abs(j) == n)
System.out.print("*");
// empty part
else System.out.print(" ");
}
System.out.println();
}
}
Output:
** * * 1 * * **
* * * 2 2 * * *
** * 3 3 * **
* * 4 4 * *
** 5 5 **
* 6 6 *
*7 7*
8 8
*7 7*
* 6 6 *
** 5 5 **
* * 4 4 * *
** * 3 3 * **
* * * 2 2 * * *
** * * 1 * * **
See also: How to print a given diamond pattern in Java?
Solution: Java program called EmptyDiamond.java that contains a method that takes an integer n and prints a empty rhombus on 2n − 1 lines.
public class EmptyDiamond {
public static void main(String[] args) {
shape(3); // Change n to increase size of diamond
}
public static void shape(int n) {
int max = 2 * n - 1; // length of the diamond - top to bottom
int loop = 0; // with of each loop. initialized with 0
for (int i = 1; i <= max; i++) {
int val = 0;
if (i <= n) {
loop = n + i - 1;// e.g. when i = 2 and n = 3 loop 4 times
val = i; // value to be printed in each loop ascending
} else {
loop = n + (max - i); //e.g. when i = 4 and n = 3 loop 4 times
val = max - i + 1; // value to be printed in each loop descending
}
for (int j = 1; j <= loop; j++) {
// (value end of loop)
// || (value in the beginning when i <= n)
// || (value in the beginning when i > n)
if (j == loop
|| j == (n - i + 1)
|| j == (n - val + 1)) {
System.out.print(val); // Print values
} else {
System.out.print(" "); // Print space
}
}
System.out.println(); // Print next line
}
}
}
Output when n = 3:
1
2 2
3 3
2 2
1
Stream-only function:
public static void printEmptyDiamond(int n) {
IntStream.range(1, 2*n)
.map(i-> i > n ? 2*n-i : i)
.mapToObj(i -> " ".repeat(n-i) + i + (i>1 ? " ".repeat(2*(i-1)-1)+i : ""))
.forEach(System.out::println);
}
Example output (printEmptyDiamond(7)):
1
2 2
3 3
4 4
5 5
6 6
7 7
6 6
5 5
4 4
3 3
2 2
1
With explainations:
public static void printEmptyDiamond(int n) {
IntStream.range(1, 2*n)
.map(i-> i > n? 2*n-i : i) // numbers from 1 to n ascending, then descending to 1 again
.mapToObj(i -> " ".repeat(n-i) // leading spaces
+ i // leading number
+ (i>1 ? // only when number is > 1
" ".repeat(2*(i-1)-1) // middle spaces
+ i // trailing number
: ""))
.forEach (System.out::println);
}
I did it for fun, here's the code :
import java.util.Scanner;
public class Diamond {
public static void main(String[] args) {
Scanner read = new Scanner(System.in);
int num = read.nextInt();
read.nextLine();
//TOP
for(int i = 1;i<=num;i++) {
//LEFT
for(int k = i; k<num;k++) {
if ( k % 2 == 0 ) {
System.out.print(" ");
}
else {
System.out.print(" ");
}
}
if(i>1) {
for(int j =1;j<=i;j++) {
if (j==1 || j== i) {
for(int u=0;u<j;u++) {
System.out.print(" ");
}
System.out.print(i);
}
else {
System.out.print(" ");
}
}
System.out.println("");
}
else {
System.out.println(" "+i);
}
}
//BOTTOM
for(int i = num-1;i>0;i--) {
for(int k = i; k<num;k++) {
if ( k % 2 == 0 ) {
System.out.print(" ");
}
else {
System.out.print(" ");
}
}
if(i>1) {
for(int j =1;j<=i;j++) {
if (j==1 || j== i) {
for(int u=0;u<j;u++) {
System.out.print(" ");
}
System.out.print(i);
}
else {
System.out.print(" ");
}
}
System.out.println("");
}
else {
System.out.println(" "+i);
}
}
}
}
And the output :
7
1
2 2
3 3
4 4
5 5
6 6
7 7
6 6
5 5
4 4
3 3
2 2
1
Having seen the other answers, there's a whole load of loops I could've skipped. Just decided to wing it at the end and do it as quick as possible.
In my project the user input is translated to a string in the form of [x,x,x,x,x,x,x,x,x,x] where x is a number between 1 and 8 and stored to a library of this type of strings. Later I have to compare the user new input with every string in that library.
So I'm trying to find the similarity between two strings of the mention format. I tried the Levenhstein distance algorithm but it does not suit my needs. For the strings [1,8,7,6,5,4,3,2,0,0] and [1,7,6,5,4,3,2,0,0,0], Levenhstein finds distance of 7 while in my prospective the distance is only one. Levenhstein only edits each character but does not shift the characters.
Can someone suggest another spell-check or string-compare algorithm with the criteria I mentioned before?
Levenshtein algorithm I used:
public static int getLevenshteinDistance(String s, String t)
{
if (s == null || t == null)
{
throw new IllegalArgumentException("Strings must not be null");
}
int d[][]; // matrix
int n; // length of s
int m; // length of t
int i; // iterates through s
int j; // iterates through t
char s_i; // ith character of s
char t_j; // jth character of t
int cost; // cost
// Step 1
n = s.length();
m = t.length();
if (n == 0)
{
return m;
}
if (m == 0)
{
return n;
}
d = new int[n + 1][m + 1];
// Step 2
for (i = 0; i <= n; i++)
{
d[i][0] = i;
}
for (j = 0; j <= m; j++)
{
d[0][j] = j;
}
// Step 3
for (i = 1; i <= n; i++)
{
s_i = s.charAt(i - 1);
// Step 4
for (j = 1; j <= m; j++)
{
t_j = t.charAt(j - 1);
// Step 5
if (s_i == t_j)
{
cost = 0;
}
else
{
cost = 1;
}
// Step 6
d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost);
}
}
// Step 7
return d[n][m];
}