Rot 13 Minimal Version Java - java

I tried to implement Rot13 and to make it as minimal as possible, this are my results so far:
if ( (c >= 'A') && (c <= 'Z') )
c=((c-'A'+13)%26)+'A';
if ( (c >= 'a') && (c <= 'z') )
c=((c-'a'+13)%26)+'a';
return c;
I showed this to my Prof and he said it would be possible in two lines. I don't know how i could shrink this code further and not generating wrong output.
Thanks for your help
EDIT: if nothing changed (outer range ascii) it should only return c. Maybe the solution is the second answer + return line c in case nothing returned.

You don't need to update c; just return:
if ((c >= 'A') && (c <= 'Z')) {
return ((c - 'A' + 13) % 26) + 'A';
}
if ((c >= 'a') && (c <= 'z')) {
return ((c - 'a' + 13) % 26) + 'a';
}
I also made the code more readable.
This could easily be made into two lines:
if ((c >= 'A') && (c <= 'Z')) return ((c - 'A' + 13) % 26) + 'A';
if ((c >= 'a') && (c <= 'z')) return ((c - 'a' + 13) % 26) + 'a';
Or one:
if ((c >= 'A') && (c <= 'Z')) return ((c - 'A' + 13) % 26) + 'A'; if ((c >= 'a') && (c <= 'z')) return ((c - 'a' + 13) % 26) + 'a';
But of course, that is much less readable, and not a good idea.

One line:
return (c < 'a') ? ((c - 'A' + 13) % 26) + 'A' : ((c - 'a' + 13) % 26) + 'a';
This simply makes use of the fact that lower case letters come after upper case letters in ASCII and UTF-8. Of course, it doesn't verify the input in any way.

There is a little trick using the ASCII table. Upper and lower case chars only differ one bit. So you could handle them at once. Take a look at this:
A = 0100 0001 M = 0100 1101
a = 0110 0001 m = 0110 1101
So, I think this should work:
if (Character.isLetter(c))
return (char) ((((c & 0b01011111) - 'A' + 13) % 26 + 'A') | (c & 0b00100000));
return c;
Explanation:
c & 0b01011111 turns the char into an uppercase.
- 'A' + 13 converts to an 0-based int and applies the offset.
% 26 + 'A' Take the modulo and make it back a char.
(c & 0b00100000) takes the bit that indicates wether the char was lower case or not.
| Add that bit back to the result to make it lowercase if it was.
You could use the conditional operator here to make it a one-liner:
return Character.isLetter(c) ? (char) ((((c & 0b01011111) - 'A' + 13) % 26 + 'A') | (c & 0b00100000)) : c;
After replacing the binary and char literals by decimal int literals, you get:
return Character.isLetter(c) ? (char) ((((c & 95) - 52) % 26 + 65) | (c & 32)) : c;
Eliminating spaces and some extra brackets gives: (65 chars)
return Character.isLetter(c)?(char)((((c&95)-52)%26+65)|c&32):c;
Which is a win, IMHO, if it comes to code golfing. This is of course not readable.
Demo: Yep, confirmed. It works: http://ideone.com/l6xYy6
Excerpt from the output:
= -> =
> -> >
? -> ?
# -> #
A -> N
B -> O
C -> P
D -> Q
And a bit further:
W -> J
X -> K
Y -> L
Z -> M
[ -> [
\ -> \
] -> ]
^ -> ^
_ -> _
` -> `
a -> n
b -> o
c -> p
d -> q

Slightly more correct than Sibbo's answer. This returns c as is if it falls in neither range. and in 1 line.
return ((c >= 'A') && (c <= 'Z')) ? ((c-'A'+13)%26)+'A'
:((c >= 'a') && (c <= 'z') ? ((c-'a'+13)%26)+'a'
: c);

Even shorter and (perhaps) still easier to read is
char a = c < 'a' ? 'A' : 'a';
return (c - a + 13) % 26 + a;
Note that this solution, like some of the previous answers, doesn't check the input. Moreover, in Java this code returns an int, not a char, so a cast would be necessary if the method in which it is included returns a char.
As already mentioned, I also like to stress that shortest is not necessarily best. Write readable code.

Well, if we're going for short over readable;
return (c&~32) >= 'A' && (c&~32) <= 'Z' ? ((c&31) + 12) % 26 + (c&~31) + 1 : c;

Related

How to prevent IntelliJ to stop continuing double-slash comments on the next line?

Short version
When pressing <enter> at the end of a // comment, Intellij sometimes decides to continue the // comment on the next line. How can I prevent that? Is there a setting somewhere to disable this automation?
Long version
There is a thing I do regularily, it is to break a long expression with a double-slash.
Let's say I have a line like
boolean isHex = c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f';
and I want to split it like that
boolean isHex = c >= '0' && c <= '9' //
|| c >= 'A' && c <= 'F' //
|| c >= 'a' && c <= 'f';
Note that I want the final // in order to prevent any formatter to join the lines again.
So I insert a double-slash-return after the '9', by pressing //<enter>. But Intellij will auto-continue the comment on the next line.
boolean isHex = c >= '0' && c <= '9' //
// || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f';
It forces me to uncomment and reindent the line manually.
I want Intellij to not continue the comment on the next line and optionally indent my code:
boolean isHex = c >= '0' && c <= '9' //
|| c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f';
So I want to disable this "continue // comment after <enter>" feature. Is it possible? I haven't found any setting related to that.
The closest you are going to get is to define a macro to insert a new line and remove the comment and then bind that macro to a suitable key.
Go to Settings → Code Style → Java → Wrapping and Braces and check "Line breaks" under "Keep when reformatting". This will make IntelliJ's formatter respect any manual line breaks, even if they contradict other formatting rules.

Either ints in range in one "if" statement

Maybe I am swatting flies with a sledgehammer but...
I was doing this exerice on CodingBat;
Given 2 ints, a and b, return their sum. However, "teen" values in the range [13, 19] are extra lucky. So if either value is a teen, just return 19.
and this is the answer I came up with;
public int teenSum(int a, int b)
{
if (a >= 13 && a <= 19) return 19;
if (b >= 13 && b <= 19) return 19;
else return a + b;
}
I was wondering if there was a way to solve this problem in just one "if" statement... is there?
If you use a ternary operator (? :) you could do it with zero if statements. Something like,
public int teenSum(int a, int b)
{
return (a > 12 && a < 20) || (b > 12 && b < 20) ? 19 : a + b;
}
You can have a logically equivalent expression using logical OR:
if ((a >= 13 && a <= 19) || (b >= 13 && b <= 19)) return 19;
Sure. By putting two if statements as guard clauses, what you're really doing is a logical OR. So:
if ((a >= 13 && a <= 19) || (b >= 13 && b <= 19)) return 19;
would also work.
By the way, the else is redundant.
You can do it entirely without if statements, using the ?: ternary operator.
return (a >= 13 && a <= 19) || (b >= 13 && b <= 19) ? 19 : a + b;

To check whether a character is of English Alphabet (a-zA-Z)

The method Character.isLetter(Char c) tells whether the character is a unicode letter. What if I want to check for English letters (a-zA-Z) without regex.
Easy
char c = ...;
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
//english letter
}

Base64.encode(bytearray, Base64.DEFAULT) result of this method will add 10 at last item

When i encode my byte array using Base64.encode(bytearray, Base64.DEFAULT) so result of this method will add 10 at last item in the resulting byte array and when i converting this resulting byte array into string than 10 will convert into \n(line feed) at the end
please let me know why the \n will append at the end
below is the code that will convert the string into byte array
int inLength = hexValue.length();
int i, o = 0;
long outByte = 0;
byte[] outBytes = new byte[(inLength / 2)];
for (i = 0; i < inLength; i++) {
char c = hexValue.charAt(i);
int value = -1;
if (c >= '0' && c <= '9')
value = (c - '0');
else if (c >= 'A' && c <= 'F')
value = 10 + (c - 'A');
else if (c >= 'a' && c <= 'f')
value = 10 + (c - 'a');
if (value >= 0) {
if (i % 2 == 1) {
outBytes[o++] = (byte) ((outByte << 4) | value);
outByte = 0;
} else {
outByte = value;
}
} else {
if (o != 0)
break;
}
}
return outBytes;
I can't comment right now so i had to leave a reply.
Is this code written by you? or Someone else?
For Base64 encoding, byte are processed in blocks of 3 bytes at a time. If the length of the array is not a multiple of three then either one or two '0' zero bytes is appended to make full block.
And why are you writing your own logic where there are some API available to do the work for you?
Update: I just run the code again with help of API.
Input String: 51b034267f00000144495444
And
Corresponding Base64 encoded String: NTFiMDM0MjY3ZjAwMDAwMTQ0NDk1NDQ0
Simply put, 3 bytes will result in 4 plain text encoded bytes.

can't == be used instead of unary & to check if two values are equal

Recently I came across a code snippet in a book which sets a Boolean value to a field like this
the input identifier is a List of Strings
if (identifier.size() >= 2) {
int c = Integer.parseInt(identifier.get(1));
bulk = (c & 4) == 4;
hazardous = (c & 2) == 2;
toxic = (c & 1) == 1;
}
what is the need for unary & operators here?Can't this be done using a simple
c==4 etc instead of (c & 4)== 4 ?
No, this is a bitwise operation.
Imagine c=7. In that case all conditions would be true.
c = 7;
bulk = (c & 4) == 4; // true
hazardous = (c & 2) == 2; //true
toxic = (c & 1) == 1; //true
In binary, you'd have this:
c = 0111; //4-bit to simplify output
bulk = (c & 0100) == 0100; //
hazardous = (c & 0010) == 0010; //true
toxic = (c & 0001) == 0001; //true
Due to bitwise AND (&) you get 0111 & 0010 = 0010 etc.
This is added for bit masking
if
c =3 then also it will be considered as toxic with this
toxic = (c & 1) == 1;
if you write
toxic = c == 1;
then it would be stcict 1 check
The variable c is clearly a bitmask. The effect of doing the bitwise & is mask off the other bits, leaving just the one bit still set. For example, this statement:
bulk = (c & 4) == 4;
tests if bit 2 of c is set (and doesn't care about the other bits) - bit 2 being the 1 bit in this byte: 00000100
c == 4 checks if c equals 4, meaning the binary form of c is 000...00100. (c & 4) == 4 if the binary form of c is the following xxx...xx1xx.

Categories

Resources