java for loop pyramid - java

I want to create a loop with a string so that with each successive loop, the last and first characters from the previous line will not be displayed. I'm also trying to print the length of each loop next to each line. It will look like an upside-down pyramid.
I had this:
for(int scounter = fullName.length(); scounter > 0; scounter--)
for (String name : fullName)
for(int counter = 0; counter < fullName.length(); counter++)
System.out.println(scounter + "[ " + fullName.substring(0, fullName.length() counter)+ " ]");
It prints something like this:
24******
24****
24**
24*
Yet I'm looking for something similar to this:
7*******
5*****
4***
1*

String str = "*******";
for (int i = 0, l = str.length(); i <= l/2; i++) {
String line = str.substring(i, l - i);
System.out.printf("%" + (i + 1) + "d%s\n", line.length(), line);
}
This will print:
7*******
5*****
3***
1*
I'm assuming you meant 3 instead of 4 in your example, that is, that you want to decrement by 2.

I started working on this problem and found my solution to be slightly different from Joao's. Hope this helps!
public class pyramid
{
public static void main(String[] args)
{
for(int i=0, sz=args[0].length();i<sz; ++i,--sz)
{
System.out.printf("%"+(i+1)+"d%s\n", sz-i, args[0].substring(i,sz));
}
}
}
Invocation as per request:
java pyramid abcdefg
7abcdefg
5bcdef
3cde
1d
java pyramid abcdef
6abcdef
4bcde
2cd

Your example does not match the words of your question, so here's a method that behaves according to your words as I understand them:
public void pyramid(String text) {
int len = text.length();
int start = 0;
while (start < len) {
for (int i = 0; i < start; ++i) {
System.out.print(" ");
}
System.out.println(text.substring(start, len));
++start;
--len;
}
}

for(int i = 1; i<=4; i++) {
for(int k = 3;k>=i; k--){
System.out.print(" ");
}
for(int j = 1; j<=i; j++){
System.out.print("*");
}
for(int n = 2; n<=i;n++){
System.out.print("*");
}
System.out.println(" ");
}
for(int m = 1 ;m<=3; m++){
for(int o = 1;o<=m; o++){
System.out.print(" ");
}
for(int p = 3;p>=m;p--){
System.out.print("*");
}
for(int q = 2;q>=m;q--){
System.out.print("*");
}
System.out.println();
}
}
}

Related

Crossed words game in Java

I have been stuck on this exercise for 2 weeks now, hopefully someone can help...
So basically the user starts by providing the number of lines and columns and the corresponding crossed words table(which is a 2d char array) , then inputs the number of words and the words that have to be detected in that board.
The program is supposed to print the table that was given but with every non-word substituted for zeros.
An example:
Input:
4 5
GBCDP
AGGGM
MYIEU
ENBHJ
2
GAME
JUMP
Should output:
G000P
A000M
M000U
E000J
My problem is still in the method for finding the words...
this is my code(it's commented to be easier to understand)
NOTE: the words cannot be found diagonally... also I am missing the part of the program that's supposed to substitute non-words for zeros, because I still can't find the words
import java.util.Scanner;
class game {
private int rows;
private int cols;
private char m[][];
game(int r, int c)
{
rows = r;
cols = c;
m = new char[r][c];
}
//read the game
public void read(Scanner in) {
for (int i=0; i<rows; i++) {
m[i] = in.next().toCharArray();
}
}
//writes the game
public void write() {
for(int i = 0; i < rows;i++)
{
for(int j = 0; j < cols; j++)
{
System.out.print(m[i][j]);
}
System.out.println();
}
}
//finds the words
public void find(String word) {
for(int i = 0; i < rows; i++)
{
if(word.equals(new String(m[i]))){
System.out.print(i);
}
}
for(int z = 0; z < cols; z++)
{
if(word.equals(new String(m[z]))) {
System.out.print(z);
}
}
}
}
public class wordg {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int rows = scan.nextInt();
int columns = scan.nextInt();
game j = new game(rows,columns);
j.read(scan);
//j.write();
int wordnumber = scan.nextInt();
String words[] = new String[wordnumber];
for(int i = 0; i < wordnumber; i++)
{
words[i] = scan.nextLine();
}
for(int w = 0; w < words.length; w++)
{
j.find(words[w]);
}
}
}
Thanks!
How to fix the code
In this part of the answer, I will try to give a step-by-step guide on how to make your code work properly:
The first problem with your code is that you are using the rows instead of the columns, although you obviously want to use columns. This can be done like this:
String col = "";
for(int i = 0; i < rows; i++) {
col += m[i][z];
}
The next problem is that you also have to search for the reversed words. You can do that by just calling the method find with the reversed words also:
for(int w = 0; w < words.length; w++)
{
j.find(words[w]);
j.find(j.reverse(words[w]);
}
The reverse-method could look like this:
public String reverse(String word) {
String result = "";
for(int i = word.length() - 1; i >= 0; i--) {
result += word.charAt(i);
}
return result;
}
After this, your find-method should work.
To output the grid like you want it to look like, we will have to save, where we found a word. This can be done like this:
if(word.equals(new String(m[i]))){
System.out.println("Word found in row: " + i);
for(int j = 0; j < cols; j++) {
test[i][j] = true;
}
}
test is a boolean-array initialized with false in the constructor.
Now we just have to change the write-method:
//writes the game
public void write() {
for(int i = 0; i < rows;i++)
{
for(int j = 0; j < cols; j++)
{
if(test[i][j]) { //Only print found words, otherwise print "0"
System.out.print(m[i][j]);
}
else {
System.out.print("0");
}
}
System.out.println();
}
}
At this point the program should produce the output you want it to produce.
Possible improvements
If you want to improve your find-method, you could make the program recognize words inside a row or a column, for example recognize the word "YOU" in this grid:
AAYOUA
AAAAAA
AAAAAA
AAAAAA
This can be done like this:
public void find(String word) {
for(int i = 0; i < rows; i++) {
int index = new String(m[i]).indexOf(word); //Index were found word starts (-1 if row/col doesn't contain the word)
if(index >= 0) {
System.out.println("Word found in row: " + i); //Added some information for the user
for(int j = index; j < index + word.length(); j++) {
test[i][j] = true; //Save that word was found in this "cell"
}
}
}
for(int z = 0; z < cols; z++) {
String col = "";
for(int i = 0; i < rows; i++) { //Get column
col += m[i][z];
}
int index = col.indexOf(word);
if(index >= 0) {
System.out.println("Word found in col: " + z);
for(int j = index; j < index + word.length(); j++) {
test[j][z] = true;
}
}
}
}
Some other suggestions:
Class-names should begin with an uppercase-letter
Try to always use the same indentation
Try to always use the same "bracket-style"
(I changed this for you in the final code.)
Final code
All in all your code looks like this now:
Game.java
import java.util.Scanner;
public class Game { //Classes start with uppercase
private int rows;
private int cols;
private char m[][];
private boolean test[][]; //Purpose: test if "cell" where word was found
Game(int r, int c) {
rows = r;
cols = c;
m = new char[r][c];
test = new boolean[r][c];
}
//read the game
public void read(Scanner in) {
for (int i=0; i<rows; i++) {
m[i] = in.next().toCharArray();
}
}
//writes the game
public void write() {
for(int i = 0; i < rows;i++) {
for(int j = 0; j < cols; j++) {
if(test[i][j]) { //Only print found words, otherwise print "0"
System.out.print(m[i][j]);
}
else {
System.out.print("0");
}
}
System.out.println();
}
}
//finds the words
public void find(String word) {
for(int i = 0; i < rows; i++) {
int index = new String(m[i]).indexOf(word); //Index were found word starts (-1 if row/col doesn't contain the word)
if(index >= 0) {
System.out.println("Word found in row: " + i); //Added some information for the user
for(int j = index; j < index + word.length(); j++) {
test[i][j] = true; //Save that word was found in this "cell"
}
}
}
for(int z = 0; z < cols; z++) {
String col = "";
for(int i = 0; i < rows; i++) { //Get column
col += m[i][z];
}
int index = col.indexOf(word);
if(index >= 0) {
System.out.println("Word found in col: " + z);
for(int j = index; j < index + word.length(); j++) {
test[j][z] = true;
}
}
}
}
public String reverse(String word) {
String result = "";
for(int i = word.length() - 1; i >= 0; i--) {
result += word.charAt(i);
}
return result;
}
}
WordG.java
import java.util.Scanner;
public class WordG {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int rows = scan.nextInt();
int columns = scan.nextInt();
Game j = new Game(rows,columns);
j.read(scan);
int wordnumber = scan.nextInt();
scan.nextLine(); //To clear the scanner
String words[] = new String[wordnumber];
for(int i = 0; i < wordnumber; i++) {
words[i] = scan.nextLine();
}
for(int w = 0; w < words.length; w++) {
j.find(words[w]);
j.find(j.reverse(words[w])); //You also have to search for reversed words!
}
j.write(); //Write grid after searching
}
}
(I added comments on the right where I changed your code to explain what I did.)
Output
With your example-input, this code creates the following output:
Word found in col: 0
Word found in col: 4
G000P
A000M
M000U
E000J
And with the added functionality, the input
5 5
SHARK
AYOUB
MABCD
EABCD
ABCDE
3
YOU
ME
SHARK
gives the output
Word found in row: 1
Word found in col: 0
Word found in row: 0
SHARK
0YOU0
M0000
E0000
00000

My X's are being placed 1 space off in my histogram

import java.util.*;
public class HistogramGenerator {
public int getHeightOfHistogram(int[] occurences) {
// occurences = {1,0,0,0,1,0,0,0,0,1,0,0,0,2,0,0,0,0,0,0,0,0,0,0]
int max = occurences[0];
for (int i = 1; i < occurences.length; i++) {
if (occurences[i] > max) {
max = occurences[i];
}
}
return max;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a line: ");
String sentenceEntered = sc.nextLine();
System.out.println("Letter Histogram");
HistogramGenerator histogram = new HistogramGenerator();
String letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //Map of all the characters
int[] occurences = new int[letters.length()]; //max size of all possible matches
// loop through sentenceEntered to find occurences of each character
for (int i = 0; i < sentenceEntered.length(); i++) {
int charValue = sentenceEntered.charAt(i);
int index = letters.indexOf(charValue); // index of the character we are searching for
if (index < 0)
continue;
occurences[index]++;
}
int heightOfHistogram = histogram.getHeightOfHistogram(occurences);
String[][] histogramArray = new String[heightOfHistogram][letters.length()]; //[2][26]
for (int j =0; j < occurences.length; j++) {
int numXtoInsert = occurences[j];
while(numXtoInsert > 0){
histogramArray[heightOfHistogram - numXtoInsert][j] = "X";
numXtoInsert--;
}
}
// print 26 dashes (length of letters)
for(int k=0; k < letters.length(); k++){
System.out.print("-");
}
System.out.println();
// print histogram
for(int row =0; row < histogramArray.length; row++){
for(int col=0; col < histogramArray[row].length; col++){
if (histogramArray[row][col] == null) {
System.out.print("");
continue;
}
System.out.print(histogramArray[row][col] + " ");
}
System.out.println();
}
System.out.println();
// print 26 dashes ( length of letters)
for(int u=0; u < letters.length(); u++){
System.out.print("-");
}
System.out.println();
// print all characters in letters
System.out.print(letters);
}
}
basically whatever word i put in it prints out something close to it, but not really correctly, if i type in apple for example it'll print out an X close to A, and X on P and an X close to P, and and X close to l and E.
maybe there's something wrong with the logic? I don't know, need some quick help!
The issue is with the printing logic. When you find a null value, you need to print a space. When you don't find a null value, you should not add an extra space. See below for the updated working logic:
// print histogram
for(int row =0; row < histogramArray.length; row++){
for(int col=0; col < histogramArray[row].length; col++){
if (histogramArray[row][col] == null) {
System.out.print(" ");
continue;
}
System.out.print(histogramArray[row][col]);
}
System.out.println();
}
System.out.println();

Printing a word in a diamond format

My assignment is to print a word in the shape of a diamond like so:
*****s
****p*p
***i***i
**d*****d
*e*******e
r*********r
*e*******e
**d*****d
***i***i
****p*p
*****s
P.S. The asterisks are only there to show spacing, pretend one asterisk represent one space.
So far I have this:
public class DiamondWords
{
public static void main(String[] args)
{
Scanner kbReader = new Scanner(System.in);
System.out.print("Enter a word to be printed in diamond format: ");
String word = kbReader.nextLine();
int wordLength = word.length();
for(int i = 0; i<wordLength-1; i++)
{
System.out.print(" ");
}
wordLength = wordLength - 1;
System.out.print(word.charAt(0));
System.out.println();
int x =1;
int d =1;
for(int j =wordLength; j>0; j--)
{
wordLength = j;
for(int a =1; a<wordLength; a++)
{
System.out.print(" ");
}
System.out.print(word.charAt(x));
for(int q =0; q<d; q++)
{
System.out.print(" ");
}
d+=2;
System.out.print(word.charAt(x));
x++;
System.out.println();
}
//r*********r
//*e*******e
//**d*****d
//***i***i
//****p*p
//*****s
}
}
Which prints the first half of the diamond perfectly:
*****s
****p*p
***i***i
**d*****d
*e*******e
r*********r
The only part where I'm getting stuck is when I have to print the latter half of the diamond. Can anyone point me in the right direction? Please do not write the code for me, just try and give me some pointers based off the logic I've shown. Thank you.
Try to have only one loop. A very easy way to handle the "technicalities" of the problem is to work with an char array for the output. First you initialize it with the proper length, fill it with blanks (there is a library function for it), fill the two characters, and only then convert it to a String.
The only open question is where to put the characters, and I don't want (and should) to spoil that.
int fullLength = 2 * word.length() - 1;
for(int i = 0; i < fullLength; i++) {
char[] line = new char[fullLength];
Arrays.fill(line, ' ');
int k = ???;
char c = s.charAt(k);
line[word.length() - 1 - k] = c;
line[word.length() - 1 + k] = c;
System.out.println(new String(line));
}
Obviously, you want to calculate the position "from the middle" (so we have something like word.length() - 1 +- k), and for the first half of the word, k is equal to i.
Your task, should you decide to accept it, is to find out how to "bend k back" for the second half of the word.
import java.util.Scanner;
public class DiamondWords
{
public static void main(String[] args)
{
Scanner kbReader = new Scanner(System.in);
System.out.print("Enter a word to be printed in diamond format: ");
String word = kbReader.nextLine();
int wordLength = word.length();
int wordLength2 = word.length();
int wordSize = word.length();
int wordLengthReverse = word.length();
for(int i = 0; i<wordLength-1; i++)
{
System.out.print(" ");
}
wordLength = wordLength - 1;
System.out.print(word.charAt(0));
System.out.println();
int x =1;
int d =1;
for(int j =wordLength; j>0; j--)
{
wordLength = j;
for(int a =1; a<wordLength; a++)
{
System.out.print(" ");
}
System.out.print(word.charAt(x));
for(int q =0; q<d; q++)
{
System.out.print(" ");
}
d+=2;
System.out.print(word.charAt(x));
x++;
System.out.println();
}
System.out.print(" " + word.charAt(wordLength2-2));
int spaceLength =((wordLength2*2)-1) -4;
int u =spaceLength -2;
for(int i =0; i < spaceLength; i++)
{
System.out.print(" ");
}
System.out.print(word.charAt(wordLength2-2));
System.out.println();
int m=3;
for(int num =2; num<wordSize-1; num++)
{
wordLength2 = num;
for(int i =0; i<num; i++)
{
System.out.print(" ");
}
System.out.print(word.charAt(wordSize-m));
for(int b = 0; b<u; b++)
{
System.out.print(" ");
}
System.out.print(word.charAt(wordSize-m));
System.out.println();
m++;
u = u-2;
}
for(int r =0; r<word.length()-1; r++)
{
System.out.print(" ");
}
System.out.print(word.charAt(0));
}
}
I have finished. This is my final code. I understand it is not as efficient as possible, or easy to follow, but it is flexible and not hard-coded, so I am content.

Printing for value of ArrayList Integer

I'm working on a small game that essentially has piles of coins, and you must take some coins from a pile then the program prints out the resulting piles in the format:
Pile 1: ****
Pile 2: *****
Pile 3: **
I have an array list that store all these values like so:
List<Integer> coins = new ArrayList<>();
[4,5,2]
But I can't figure out how to get it to properly print the *'s.
How can I write this code to print out a * for each value in an element. IE 4 *'s if the element value is 4?
Here is my current method:
static void printGameState(){
for(int i = 0; i <= coins.size()-1; i++){
int k = i+1;
System.out.print("Pile " + k + ": ");
for(int j = 0; j <= coins.indexOf(i); j++){
System.out.print("*");
}
}
}
Instead of using this condition:
j <= coins.indexOf(i);
Use this condition:
j < coins.get(i);
Try it:
for(int i = 0; i <= coins.size()-1; i++) {
int k = i+1;
System.out.print("Pile " + k + ": ");
for(int j = 0; j < coins.get(i); j++) {
System.out.print("*");
}
System.out.println();
}
You'll get:
Pile 1: ****
Pile 2: *****
Pile 3: **
You should be using < instead of <=. Also, you should be able to use get(i) to take the value at index i.
static void printGameState(){
for(int i = 0; i < coins.size(); i++){
int k = i+1;
System.out.print("Pile " + k + ": ");
for(int j = 0; j < coins.get(i); j++){
System.out.print("*");
}
}
}
You could also make it a bit cleaner by forming another method to print * such as:
public void ast(int n){
for(int i=0; i<n; i++){
System.out.print("*");
}
}
Then the contents of printGameState loop would be
int k = i+1;
System.out.print("Pile " + k + ": ");
ast(coins.get(i));
You have to look at the values of the different stacks by accessing the array coins[i] instead of using the number of stacks as stack height:
static void printGameState(){
for(int i = 0; i < coins.size(); i++) {
// Build the coin stack
String coinStack = "";
for(int j = 0; j < coins.get(i); j++) {
coinStack += "*";
}
// And output it
System.out.println("Pile " + (i + 1) + ": " + coinStack);
}
}

Different variations for using loops to a pattern in java

I have been trying different variations of for loops and have no clue how to make these patterns:
Pattern
1
121
12321
1234321
My code is the following but doesn't work like the example above.
for (int i = 1 ; i <= rows ; i++) {
for (int j = (rows + 1 - i) ; j > 0 ; j-- ) {
System.out.print(j);
}
System.out.print("\n");
}
Your code prints only the suffix of each line, you are missing to write 12....i for each line.
In addition, the loop should start from i, not from rows-i+1.
for (int i = 1 ; i <= rows ; i++) {
//add an inner loop that prints the numbers 12..i
for (int j = 1 ; j < i ; j++ ) {
System.out.print(j);
}
//change where j starts from
for (int j = i ; j > 0 ; j-- ) {
System.out.print(j);
}
System.out.println(""); //to avoid inconsistency between different OS
}
First note that 11*11 = 121, 111*111=12321, etcetera.
Then that 10n - 1 is a number that consists of n 9's, so (10n - 1)/9 consists of n 1's.
So we get:
int powerOfTen = 1;
for (int len = 0; len < 5; len++)
{
powerOfTen = powerOfTen*10;
int ones = (powerOfTen-1)/9;
System.out.println(ones*ones);
}
Code explains everything!
public static void main(String[] args) {
String front = "";
String back = "";
int rows = 5;
for (int i = 1; i <= rows; i++) {
System.out.println(front+i+back);
front += i;
back = i + back;
}
}
Try this one: it may seems too much looping, but yet easy to understand and effective.
public static void main(String[] args) {
int rows=5;
int i,j;
for(i=1;i<=rows;i++)
{
/*print left side numbers form 1 to ...*/
for(j=1;j<i;j++)
{
System.out.printf("%d", j);
}
/*Print the middle number*/
System.out.printf("%d", i);
/*print right numbers form ... to 1*/
for(j=i-1;j>0;j--)
{
System.out.printf("%d", j);
}
System.out.println("");
}
}
int n=0;
for(int m =0; m<=5; m++){
for(n= 1;n<=m;n++){
System.out.print(n);
}
for(int u=n;u>=1;u--){
System.out.print(u);
}
System.out.print("");
}

Categories

Resources