Basic String Help for Java (newbie here) - java

I have a program that supposedly
prompts user to input a word, phrase, or sentence.
I should then "encrypt" what you entered 13 times, printing every single time. The last thing printed should match user input.
I can only encrypt alphabetical characters. Anything else remains the same.
"encrypt" by finding the ASCII value of each character then increasing it by 2. If the letter changes case, make it so that it starts over at the a for lowercase or A for uppercase instead.
My code right now just gives me 1 encryption and stops at 2. It also only works for the first letter. My class hasn't learned arrays yet but we can try it if we want.
import java.util.Scanner;
public class Encrypt{
Scanner keyboard = new Scanner(System.in);
String message = new String();
String g = new String();
char y;
public void input(){
System.out.printf("Welcome to Encrypt.java. Please enter a word,phrase, or sentence. \n");
System.out.println();
System.out.print("-> ");
message = keyboard.nextLine();
}
public void code(){
int x = message.length()-1;
boolean enter = true;
for(int i = 0; i <= x; i++){
int j = message.charAt(i);
if((j >= 32 && j <=64) ||
(j >= 91 && j <=96) ||
(j >= 123 && j <= 127)){
}
else if((j >= 65 && j <= 90)){
j = j + 2;
if(j>90){
j = (j-90)+64;
}
}
else if(j>=97 && j <= 122){
j = j + 2;
if(j>122){
j = (j-122) + 96;
}
}
if(enter == true){
System.out.println();
System.out.print(" ");
enter = false;
}
y = (char)(j);
g = g + y;
message = g;
x = message.length()-1;
}
System.out.print(g);
System.out.println();
}
public void print(){
for(int i = 1; i <= 13; i ++){
System.out.println("Encryption " + i + ":");
this.code();
}
}
public static void main(String [] args){
Encrypt e = new Encrypt();
e.input();
e.print();
}
}

Two Things :
Resetting the variable g after every iteration.
Proper placement of message.
public void code() {
int x = message.length() - 1;
boolean enter = true;
g = "";
for (int i = 0; i <= x; i++) {
int j = message.charAt(i);
if ((j >= 32 && j <= 64) || (j >= 91 && j <= 96)
|| (j >= 123 && j <= 127)) {
}
else if ((j >= 65 && j <= 90)) {
j = j + 2;
if (j > 90) {
j = (j - 90) + 64;
}
} else if (j >= 97 && j <= 122) {
j = j + 2;
if (j > 122) {
j = (j - 122) + 96;
}
}
if(enter == true){
System.out.println();
System.out.print(" ");
enter = false;
}
y = (char) (j);
g = g + y;
}
message = g;
}
Output:
Welcome to Encrypt.java. Please enter a word,phrase, or sentence.
-> abba
Encrypt.code() message >> abba
Encrypt.code() message >> cddc
Encrypt.code() message >> effe
Encrypt.code() message >> ghhg
Encrypt.code() message >> ijji
Encrypt.code() message >> kllk
Encrypt.code() message >> mnnm
Encrypt.code() message >> oppo
Encrypt.code() message >> qrrq
Encrypt.code() message >> stts
Encrypt.code() message >> uvvu
Encrypt.code() message >> wxxw
Encrypt.code() message >> yzzy

Here's your problem
y = (char) (j);
g = g + y;
message = g;
In the first run, g is only one char, and you're making message = g;. This makes message just that one character g. I ran it deleting the message = g and it works fine. I don't know if it's your desired output, but at least it's getting past Encryption 1
Note: You should really learn how to use a debugger. That's how I spotted the problem.

Related

Combine 2 2D arrays that both contain chars with java

I have to write a code as a task for my university and we have to recreate Minesweeper with java and it has to be runned in the command line.
For the matchfield we have to make an array that looks in the end like this picture:
Example how it sould look in the end
And to choose the field we have to use the scanner.
For example if you want to chose field C3, you have to type into the scanner C3.
At the moment im struggleing a little bit with the field.
I had 2 ideas but both didn't work out very well.
in the first try i tried to create everything with 2 for loops and 1 array but my problem was that I couldn't add 2 charrs, so I had the chars 0 to 9 and the charrs A to J.
In the second try I created 3 array, one with the numbers 0 to 9 and anothe array A to J and in the third array i wanted to combine both arrays. And now I'm wondering if this it's possible if I can acctually combine them in the way I want and if it's possible could somebody give me some help?
import java.util.Scanner;
import java.util.Arrays;
public class Minesweeper {
public static void main (String[] args) {
char c = 'A';
char d = '0';
char e = '9';
char f = 'J';
char[][] feldz = new char[11][11];
char[][] feldb = new char[11][11];
char[][] feld = new char[11][11];
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (i == 0 && j == 0) {
feldz[i][j] = ' ';
System.out.print(feldz[i][j] + " |");
}
if (d > e) {
d = '0';
}
if (d <= e && i > 0){
feldz[i][j] = d;
System.out.print(feldz[i][j] + " |");
}
if (i > 0 && j == 10) {
d++;
}
}
System.out.println("");
}
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (i == 0 && j == 0) {
feldb[i][j] = ' ';
System.out.print(feldb[i][j] + " |");
}
if (i > 0 && j == 0){
feldb[i][j] = ' ';
System.out.print(feldb[i][j] + " |");
}
if (c > f) {
c = 'A';
}
if(c <= f && j > 0){
feldb[i][j] = c;
System.out.print(feldb[i][j] + " |");
c++;
}
if (j == 10){
System.out.println("");
}
}
}
}
}
You don't actually need array to print the maze , nested loops is enough for that. 2d Array is only required to store the input. Please try the below code:
int size = 10;
int [][] maze = new int[size][size];
while (true){
System.out.print(' ');
for (int i = 0; i < size; i++) {
System.out.print('|');
System.out.print((char) ('A' + i));
}
for (int i = 0; i < size; i++) {
System.out.println("");
System.out.print(i);
for (int j = 0; j < size; j++) {
System.out.print('|');
if(maze[i][j] > 0) {
System.out.print(maze[i][j]);
} else {
System.out.print(' ');
}
}
}
int row = -1;
int col = -1;
System.out.println("\nEnter CoOrdinates");
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
if(input.length() == 2) {
char charAt = input.charAt(0);
if(charAt >= 'A' && charAt <= 'A'+size-1) {
col = charAt-'A';
}
charAt = input.charAt(1);
if(charAt >= '0' && charAt <= '0'+size-1) {
row = charAt-'0';
}
if(row != -1 && col != -1) {
System.out.println("Enter Action");
input = scanner.nextLine();
int action = Integer.parseInt(input);
maze[row][col] = action;
} else {
System.out.println("Incorrect Input");
}
}
}

How do I combine an Output of two for loops into a "table" format?

I used two for loops to convert miles to km and km to miles respectively for selected values. However the issue I am facing is that the output for the first for loop is not side by side with the output of the second table. Appreciate some help on this!
public static double miletoKilometer(double mile) {
double conversion = mile * 1.609;
return conversion;
}
public static double kilometerToMile(double km) {
double conversion2 = km / 1.609;
return conversion2;
}
public static void main(String[] args) {
int mileInput = 0;
double kmOutput = 0;
int kmInput = 0;
double mileOutput = 0;
int displayRow1 = 0;
int displayRow2 = 0;
System.out.print("Miles\tKilometres\tKilometres\tMiles \n");
for (int i = 0; i < 11; i++) {
if (i == 1 || i == 2 || i == 9 || i == 10) {
mileInput = i;
System.out.printf("\n" + i);
kmOutput = miletoKilometer(mileInput);
System.out.printf("\t %.3f\n", kmOutput);
}
}
for (int j = 0; j < 66; j++) {
if (j == 20 || j == 25 || j == 60 || j == 65) {
kmInput = j;
System.out.printf("\n\t\t " + j);
mileOutput = kilometerToMile(kmInput);
System.out.printf("\t\t%.3f", mileOutput);
}
}
}
Current Output:
enter image description here
Changing your loop to match the code below should put everything in the right order. Not the most elegant solution but it gets the job done.
int j = 0;
for (int i = 0; i < 11; i++) {
if (i == 1 || i == 2 || i == 9 || i == 10) {
mileInput = i;
System.out.printf("\n" + i);
kmOutput = miletoKilometer(mileInput);
System.out.printf("\t %.3f", kmOutput);
for (; j < 66; j++) {
if (j == 20 || j == 25 || j == 60 || j == 65) {
kmInput = j;
System.out.printf("\t\t " + j);
mileOutput = kilometerToMile(kmInput);
System.out.printf("\t\t%.3f\n", mileOutput);
j++;
break;
}
}
}
}

How would one go about printing out a certain pattern to the console, given a random size?

I have a homework assignment for my computer science class in school, in which we have to print out the following pattern, of random size (width, height).
..............................X..............................
..................................X..........................
.......................................X.....................
...........................................X.................
...............................................X.............
...................................................X.........
......................................................X......
........................................................X....
..........................................................X..
...........................................................X.
............................................................X
...........................................................X.
..........................................................X..
........................................................X....
......................................................X......
...................................................X.........
...............................................X.............
...........................................X.................
.......................................X.....................
..................................X..........................
..............................X..............................
..........................X..................................
.....................X.......................................
.................X...........................................
.............X...............................................
.........X...................................................
......X......................................................
....X........................................................
..X..........................................................
.X...........................................................
X............................................................
.X...........................................................
..X..........................................................
....X........................................................
......X......................................................
.........X...................................................
.............X...............................................
.................X...........................................
.....................X.......................................
..........................X..................................
..............................X..............................
I'm almost 100% certain that my way of going about it is wrong, considering most of it is hard coded. I've spent hours thinking of different ways to go about the problem. I tried finding a formula for the curve, but I cannot, for the life of me, find one that fits perfectly. Also, even if I did have a formula, I don't know how to go about implementing it while printing to the console. My code currently only prints a fixed size of the pattern.
My code:
String pattern = "X";
String background = ".";
for(int i = 31; i < 61; i += 0) {
String output = "";
for(int j = 0; j < 61; j++) {
if(j == i) {
output += pattern;
} else {
output += background;
}
}
output = output.substring(2);
System.out.println(output);
if(i == 35) i += 5;
else if(i > 30 && i < 52) i += 4;
else if(i == 52) i += 3;
else if(i >= 55 && i < 59) i += 2;
else i++;
}
for(int i = 59; i >= 31; i += 0) {
String output = "";
for(int j = 0; j < 61; j++) {
if(j == i) {
output += pattern;
} else {
output += background;
}
}
output = output.substring(2);
System.out.println(output);
if(i <= 59 && i >= 57) i -= 2;
else if(i == 55) i -= 3;
else if(i <= 52 && i > 40) i -= 4;
else if(i == 40) i -= 5;
else i -= 4;
}
for(int i = 27; i >= 0; i += 0) {
if(i <= 1) break;
String output = "";
for(int j = 0; j < 61; j++) {
if(j == i) {
output += pattern;
} else {
output += background;
}
}
output = output.substring(2);
System.out.println(output);
if(i == 31) i -= 4;
else if(i == 27) i -= 5;
else if(i == 10) i -= 3;
else if(i <= 7 && i >= 5) i -= 2;
else if(i <= 5) i--;
else i -= 4;
}
for(int i = 3; i <= 31; i += 0) {
String output = "";
for(int j = 0; j < 61; j++) {
if(j == i) {
output += pattern;
} else {
output += background;
}
}
output = output.substring(2);
System.out.println(output);
if(i >= 3 && i <= 5) i += 2;
else if(i == 7) i += 3;
else if(i >= 10 && i <= 18) i += 4;
else if(i == 22) i += 5;
else i += 4;
}
Obviously, my way is inefficient and incorrect. I don't want the code typed out for me, but some pseudocode that points me in the right direction would be very much appreciated.
Pattern you show reminds me of sinusoid.
Though my Sine Wave Printer doesn't 100% match with the original output, it can give you an idea where to start. You can try rotating and joining several parabolas or graphs of other math functions that come to your mind, or play with the example below to get what you need.
Example
The following code snippet prints 'X' relying on Math.sin function (note that it uses angle in radians as argument):
// Configurations
Integer DEFAULT_ROW_LEN = 61;
Integer NUMBER_OF_ROWS = 1000;
char DEFAULT_ROW_CONTENT = '.';
Double SPEED = 2.8;
// Preparing row of dots
StringBuilder row = new StringBuilder();
for (int i = 0; i < DEFAULT_ROW_LEN; i++) {
row.append(DEFAULT_ROW_CONTENT);
}
for (int i = 0; i < NUMBER_OF_ROWS; i += SPEED) {
// Loop progress
double relativeProgress = i / DEFAULT_ROW_LEN.doubleValue();
// In projection on a circle
double circleProgress = relativeProgress * Math.PI * 2;
// Remember that sin goes from -1 to +1, but we need to fit the curve within 0 to +1
double consoleProgress = (Math.sin(circleProgress) + 1) / 2;
// Exact index in the row to highlight
int exactPosition = (int) (consoleProgress * DEFAULT_ROW_LEN);
row.setCharAt(exactPosition, 'X');
// Print current progress and restore defaults
System.out.println(row);
row.setCharAt(exactPosition, DEFAULT_ROW_CONTENT);
}
Output
..............................X..............................
....................................X........................
..........................................X..................
................................................X............
....................................................X........
........................................................X....
...........................................................X.
............................................................X
............................................................X
...........................................................X.
.........................................................X...
.....................................................X.......
.................................................X...........
............................................X................
......................................X......................
................................X............................
.........................X...................................
...................X.........................................
..............X..............................................
.........X...................................................
.....X.......................................................
..X..........................................................
X............................................................
X............................................................
X............................................................
..X..........................................................
......X......................................................
..........X..................................................
...............X.............................................
.....................X.......................................
...........................X.................................
.................................X...........................
Ok as requested, not gonna mouth feed you with code but rather a direction towards your coding pattern
The bottom line is to use methods, they are amazing features and helps you simplify your problem (and your thinking pattern).
One method, I particularly find useful is to print a line printLine(int length,int location,char c){...}
where length is the length of the line, location is where the char c should be printed.
another method you should consider is to calculate X location: getLocation(int length,int prev) : which uses the previous location and calculate the next one .
now all you need to do is loop through the number of lines, calculate next location and print the line.
I hope this helps you understand the problem better.

Code working properly in java, but same code failing in some Test Cases in C

I was doing practice algorithms problems HackerRank website and I submitted my code firstly in C language but I got some Test Cases incorrect. I thought my logic was right so I ported my code to Java and I passed all my Test Cases.
Link to the problem definition:
https://www.hackerrank.com/challenges/caesar-cipher-1
Here is my code in C:
int main(){
int n;
scanf("%d", &n);
char* s = (char *)malloc(n * sizeof(char));
scanf("%s", s);
int k;
scanf("%d", &k);
k = k % 26;
for(int i = 0; i < n; i++){
if(s[i] >= 65 && s[i] <= 90){
s[i] += k;
if(s[i] > 90){
s[i] = s[i] - 90 + 64;
}
}
if(s[i] >= 97 && s[i] <= 122){
s[i] += k;
if(s[i] > 122){
s[i] = s[i] - 122 + 96;
}
}
}
printf("%s", s);
return 0;
}
And here is my code in Java:
public class Solution {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
String str = br.readLine();
int K = Integer.parseInt(br.readLine());
K %= 26;
for(int i = 0; i < N; i++){
char c = str.charAt(i);
if(c >= 65 && c <= 90){
c += K;
if(c > 90){
c = (char)(c - 90 + 64);
}
}
if(c >= 97 && c <= 122){
c += K;
if(c > 122){
c = (char)(c - 122 + 96);
}
}
System.out.print(c);
}
}
}
Both my solutions are passing Sample Test Cases and logic is all the same. I can't understand why it is showing W/A in C in some Test Cases.
P.S. This is practice problem solution and not a live contest solution.
C strings are terminated with a special '\0' character appended to their end. So an actual string is always 1 character longer than the visible text.
You are not allocating memory for the input string null terminator:
Replace
char* s = (char *)malloc(n * sizeof(char));
with
char* s = malloc(n * sizeof(char) + 1);
or even
char* s = malloc(n + 1);
as sizeof(char) is guaranteed to be 1.
In addition there would be a problem with these lines:
if(s[i] >= 97 && s[i] <= 122){
s[i] += k;
s[i] might be 122 and k might be very well greater than 5. As s[i] is most likely signed char type, and it might overflow past the value of 127, which is the maximum for signed char. And signed integer overflow has an undefined behavior.
This one is working fine.
int main(){
int n;
scanf("%d",&n);
char* s = (char *)malloc(10240 * sizeof(char));
scanf("%s",s);
int k;
scanf("%d",&k);
for(int i = 0; i < n; i++){
if(s[i] >= 65 && s[i] <= 90){
s[i] = (s[i]-'A'+k)%26 +'A';
}
if(s[i] >= 97 && s[i] <= 122){
s[i] = (s[i]-'a'+k)%26 +'a';
}
}
printf("%s", s);
return 0;
}
Just updated contents of if blocks and malloc size.

Vigenère cipher implementation outputs an unexpected number

I have this Vigenère cipher code that works, but it spits out a number one on the first encryption when I put "Attack at Dawn" (POTTER). It comes out as 1inuhc Qi Xubf. What is causing this?
public class vigenere {
public static void main(String[] args) {
System.out.println();
char[] message = args[0].toCharArray();
int code;
int index = 0;
code = args[1].charAt(index%args[1].length()) - 96;
for(int i = 0; i < message.length; i++){
code = args[1].charAt(index%args[1].length()) - 96;
if(65 <= message[i] && message[i] <= 90){
index++;
message[i] = (char) (65 + ((message[i] - 65) + code) % 26);
}
else if(97 <= message[i] && message[i] <= 122){
index++;
message[i] = (char) (97 + ((message[i] - 97) + code) % 26);
}
System.out.print(message[i]);
}
}
}
I think that you input is
text to be encrypted "Attack at Dawn"
key = potter (should be in all low case letter right) because of this line
code = args[1].charAt(index%args[1].length()) - 96;
I enter the key as Potter and get your result posted.but I use potter, it works fine.

Categories

Resources