Skip to content

Commit 06c27e5

Browse files
committed
Content edit.
Removed typo Shorten sentences Made more readable
1 parent 06103a2 commit 06c27e5

File tree

1 file changed

+115
-113
lines changed

1 file changed

+115
-113
lines changed

content/google-foobar-first-codechallenge-caesar-cipher.md

Lines changed: 115 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -10,184 +10,186 @@ type: 'BlogPost'
1010
---
1111

1212
In this post I will share my experience solving the first `Google FooBar Challenge`.
13+
14+
While doing some search on Google, I received an invitation to participate in a code challenge by Google. I had no previous idea about it, frankly never heard of it. I accepted the invitation and I was redirected to [FooBar](https://foobar.withgoogle.com). After log in, a `CLI` with the instructions about the challenge and how to request a challenge was provided. The challenge had to be solved within 2 days.
1315

14-
I received a surprise code challenge invitation from Google on July 26, 2020 while doing some search on Google. I had no previous idea about it, frankly never heard of it. I accepted the invitation and I was redirected to [FooBar](https://foobar.withgoogle.com). After log in, a `CLI Interface` with the instructions about the challenge and how to request a challenge was provided. The challenge had to be solved within 2 days.
15-
16-
### The Challenge
16+
### The Challenge
1717
Decrypt a code where every lowercase letter [a..z] is replaced with the corresponding one in [z..a], while every other character (including uppercase letters and punctuation) is left untouched. That is, 'a' becomes 'z', 'b' becomes 'y', 'c' becomes 'x', etc. For instance, the word "vmxibkgrlm", when decoded, would become "encryption".
1818

19-
__Constraints__
20-
- Java Runtime Environment(JRE) 8.
21-
- Limited execution time.
22-
- Prohibit usage of third-party libraries.
23-
- Parallel procession not allowed.
24-
- Character limit to around 3000 (I don’t remember exactly).
19+
__Constraints for the solution:__
20+
- Java 8
21+
- Limited execution time
22+
- Prohibit usage of third-party libraries
23+
- Parallel processing disabled
24+
- Character limit to around 3000 (I don’t remember exactly)
2525

2626
### Initial Thoughts
2727
The rough idea I could come up after the analysis was:
2828
- Manipulation of the ASCII value of the letters
2929
- Simple maths, addition/subtraction, on numeric value of letters
3030

31-
Since converting this idea to a concrete algorithm took time, I moved to another solution.
31+
Since converting this idea into a concrete algorithm was taking longer than expected, I moved to another solution.
3232

3333
### First Attempt
3434
The next simplest design for the solution I could come up with consisted of the following data structures:
35-
- `HashMap` to store the entire `a` to `z` encryption for easy access of decrypted letters.
36-
- `StringBuilder` to store the deciphered text.
37-
- Use `Java 8` new method `String.chars()` API which returns a stream of `int` (IntStream) that represents the character codes.
35+
- `HashMap` to store the encrypted letters and easy access of decrypted letters
36+
- `StringBuilder` to store the deciphered text
37+
- Use Java 8 new method `String.chars()` API
38+
3839
```java
3940
public static String solnWithStrBuilder(String x) {
40-
StringBuilder stb = new StringBuilder();
41-
x.chars().forEach(i -> stb.append(decrypt(i)));
42-
return stb.toString();
41+
StringBuilder stb = new StringBuilder();
42+
x.chars().forEach(i -> stb.append(decrypt(i)));
43+
return stb.toString();
4344
}
4445
public static char decrypt(int encryptedVal) {
45-
if ( encryptedVal >= 97 && encryptedVal <= 122) {
46-
char encodedChar;
47-
Map<Integer, Character> decryptKey = new HashMap<>();
48-
for (int i = 122, j = 97; i >= 97; i--, j++) {
49-
encodedChar = (char) i;
50-
decryptKey.put(j, encodedChar);
51-
}
52-
return decryptKey.get(encryptedVal);
53-
}
54-
else return (char)encryptedVal;
46+
if ( encryptedVal >= 97 && encryptedVal <= 122) {
47+
char encodedChar;
48+
Map<Integer, Character> decryptKey = new HashMap<>();
49+
for (int i = 122, j = 97; i >= 97; i--, j++) {
50+
encodedChar = (char) i;
51+
decryptKey.put(j, encodedChar);
52+
}
53+
return decryptKey.get(encryptedVal);
54+
}
55+
else return (char)encryptedVal;
5556
}
5657
```
58+
5759
The implementation provided desired output in the local environment but it failed to pass the tests.
58-
60+
5961
### Second Iteration
6062
I reflected back on the constraints and refactored the code to use more primitive data structure:
61-
- Replaced `StringBuilder` with `Character Array`.
63+
- Replaced `StringBuilder` with `Character Array`
64+
6265
```java
6366
public static String solnWithArray(String encryptedText) {
64-
char[] encryptedCharArr = new char[encryptedText.length()];
65-
Map<Integer, Character> decryptKey = new HashMap<>();
66-
char encodedChar;
67-
for (int i = 122, j = 97; i >= 97; i--, j++) {
68-
encodedChar = (char) i;
69-
decryptKey.put(j, encodedChar);
70-
}
71-
for (int i = 0; i < encryptedText.length(); i++) {
72-
char encryptedVal = encryptedText.charAt(i);
73-
if ( encryptedVal >= 97 && encryptedVal <= 122) {
74-
encryptedCharArr[i] = decryptKey.get((int)encryptedVal);
75-
} else encryptedCharArr[i] = encryptedVal;
76-
}
77-
return new String(encryptedCharArr);
67+
char[] encryptedCharArr = new char[encryptedText.length()];
68+
Map<Integer, Character> decryptKey = new HashMap<>();
69+
char encodedChar;
70+
for (int i = 122, j = 97; i >= 97; i--, j++) {
71+
encodedChar = (char) i;
72+
decryptKey.put(j, encodedChar);
73+
}
74+
for (int i = 0; i < encryptedText.length(); i++) {
75+
char encryptedVal = encryptedText.charAt(i);
76+
if ( encryptedVal >= 97 && encryptedVal <= 122) {
77+
encryptedCharArr[i] = decryptKey.get((int)encryptedVal);
78+
} else encryptedCharArr[i] = encryptedVal;
79+
}
80+
return new String(encryptedCharArr);
7881
}
7982
```
80-
But again the solution did not pass!
81-
At this point I got getting a little bit frustrated because there were no proper errors thrown. The output was just a list of failed tests.
82-
I lost interest after around an hour and I went back to my previous preparation method, solving challenges from other sources.
83+
84+
But again the solution did not pass! At this point I was getting a little bit frustrated because there were no proper errors thrown. The output was just a list of failed tests. I lost interest after around an hour and I went back to my previous preparation method, solving challenges from other sources.
8385

8486
### Third Iteration
85-
The next day I went back to the challenge with around 3 hours remaining. To make sure the time spent here would be worthwhile, I did some search to know more about the challenge. Only then I realized that the challenge was `invitation only`, and was used by Google for recruitment. Those were good enough reasons for me to continue, but then I was seriously running out of time.
87+
The next day I went back to the challenge with around 3 hours remaining. To make sure the time spent here would be worthwhile, I did some search to know more about the challenge. Only then I realized that the challenge was invitation only, and was used by Google for recruitment. Those were good enough reasons for me to continue, but then I was seriously running out of time.
8688

8789
Then I searched for similar problems and solutions to find answers to these questions:
88-
- How to encrypt a letter by another?
89-
- What are the standard encryption algorithms?
90+
- How to encrypt a letter by another
91+
- What are the standard encryption algorithms
92+
93+
A simple example by [Baeldung](https://www.baeldung.com/java-caesar-cipher) answered my queries.
9094

91-
A simple example by [Baeldung](https://www.baeldung.com/java-caesar-cipher) answered my queries.
9295
```java
9396
StringBuilder result = new StringBuilder();
9497
for (char character : message.toCharArray()) {
95-
if (character != ' ') {
96-
int originalAlphabetPosition = character - 'a';
97-
int newAlphabetPosition = (originalAlphabetPosition + offset) % 26;
98-
char newCharacter = (char) ('a' + newAlphabetPosition);
99-
result.append(newCharacter);
100-
} else {
101-
result.append(character);
102-
}
98+
if (character != ' ') {
99+
int originalAlphabetPosition = character - 'a';
100+
int newAlphabetPosition = (originalAlphabetPosition + offset) % 26;
101+
char newCharacter = (char) ('a' + newAlphabetPosition);
102+
result.append(newCharacter);
103+
} else {
104+
result.append(character);
105+
}
103106
}
104-
105107
return result;
106-
```
107-
108-
`“Any fool can know. The point is to understand.” - Albert Einstein`
109-
110-
The standard encryption algorithm used was `Caesar Cipher`. Knowing that the encryption was `Caesar Cipher`, I wanted to understand more which led to [Cryptography](https://github.com/codeanit/til/issues/43), [Cipher](https://github.com/codeanit/til/issues/107) and [more](https://github.com/codeanit/til/issues). Keeping limited time to mind, I skimmed the contents.
108+
```
109+
110+
**“Any fool can know. The point is to understand.” - Albert Einstein**
111+
112+
Knowing that standard encryption algorithm used was `Caesar Cipher`, I wanted to understand more that led to [Cryptography](https://github.com/codeanit/til/issues/43), [Cipher](https://github.com/codeanit/til/issues/107) and [more](https://github.com/codeanit/til/issues).
113+
114+
Keeping in mind that the time was limited, I skimmed the contents.
111115

112116
`A **Cipher** is a method for encrypting a message, intending to make it less readable. **Caesar Cipher** is a substitution cipher that transforms a message by shifting its letters by a given offset.`
113117

114118
Baeldung's post also made me realize that understanding of the encryption process was important to decipher. Therefore, based on Baeldung's framework, I created an encryption system that generated the cipher from the challenge.
119+
115120
```java
116121
public static String encrypt(String textToEncrypt) {
117-
StringBuilder result = new StringBuilder();
118-
for (char character : textToEncrypt.toCharArray()) {
119-
if ( (int)character >= 97 && (int)character <= 122 ) {
120-
int originalAlphabetPosition = character - 'z';
121-
int newAlphabetPosition = ( originalAlphabetPosition + 25 ) % 26;
122-
result.append((char) ('z' - newAlphabetPosition));
123-
} else {
124-
result.append(character);
125-
}
126-
}
127-
return new String(result);
122+
StringBuilder result = new StringBuilder();
123+
for (char character : textToEncrypt.toCharArray()) {
124+
if ( (int)character >= 97 && (int)character <= 122 ) {
125+
int originalAlphabetPosition = character - 'z';
126+
int newAlphabetPosition = ( originalAlphabetPosition + 25 ) % 26;
127+
result.append((char) ('z' - newAlphabetPosition));
128+
} else {
129+
result.append(character);
130+
}
131+
}
132+
return new String(result);
128133
}
129134
```
130135

131136
After generating the exact cipher, It was pretty much easier to write a program to decipher.
137+
132138
```java
133139
public static String solutionWithOffset(String encryptedText) {
134-
StringBuilder result = new StringBuilder();
135-
for (char character : encryptedText.toCharArray()) {
136-
if ( (int)character >= 97 && (int)character <= 122 ) {
137-
int originalAlphabetPosition = character - 'z';
138-
int newAlphabetPosition = (originalAlphabetPosition + 25 ) % 26;
139-
result.append((char) ('z' + newAlphabetPosition));
140-
} else {
141-
result.append(character);
142-
}
143-
}
144-
return new String(result);
140+
StringBuilder result = new StringBuilder();
141+
for (char character : encryptedText.toCharArray()) {
142+
if ( (int)character >= 97 && (int)character <= 122 ) {
143+
int originalAlphabetPosition = character - 'z';
144+
int newAlphabetPosition = (originalAlphabetPosition + 25 ) % 26;
145+
result.append((char) ('z' + newAlphabetPosition));
146+
} else {
147+
result.append(character);
148+
}
149+
}
150+
return new String(result);
145151
}
146152
```
153+
147154
I submitted the solution then again it failed.
148155

149-
__Time on the clock less than 10mins left!__
156+
__Time <10mins!__
150157

151158
### Accepted Solution
152-
Reflected back on the constraints, and refactored the code
159+
Refactored the code:
153160
- Replaced `StringBuilder` with `Character Array`.
161+
154162
```java
155163
public static String solution(String x) {
156-
int strLength = x.length();
157-
char[] encryptedCharArr = new char[strLength];
158-
for (int i = 0; i < strLength; i++) {
159-
int character = x.charAt(i);
160-
if ( character >= 97 && character <= 122 ) {
161-
int originalAlphabetPosition = character - 'z';
162-
int newAlphabetPosition = (originalAlphabetPosition + 25 ) % 26;
163-
encryptedCharArr[i] = (char) ('z' + newAlphabetPosition);
164-
} else {
165-
encryptedCharArr[i] = (char)character;
166-
}
167-
}
168-
return new String(encryptedCharArr);
164+
int strLength = x.length();
165+
char[] encryptedCharArr = new char[strLength];
166+
for (int i = 0; i < strLength; i++) {
167+
int character = x.charAt(i);
168+
if ( character >= 97 && character <= 122 ) {
169+
int originalAlphabetPosition = character - 'z';
170+
int newAlphabetPosition = (originalAlphabetPosition + 25 ) % 26;
171+
encryptedCharArr[i] = (char) ('z' + newAlphabetPosition);
172+
} else {
173+
encryptedCharArr[i] = (char)character;
174+
}
175+
}
176+
return new String(encryptedCharArr);
169177
}
170178
```
171-
__YAY!!! Solution Passed All Tests!__
172179

173-
__Time on the clock less than 2mins__
174-
180+
__Yay! All Tests Passed. Time <2mins.__
181+
182+
**Solution Submitted.**
183+
175184
### Review
176185
The next day I reviewed the solution and recalled the overall process. Phew! It was a close call.
177186

178-
I wanted to refactor the submitted code as had I submitted in a hurry. Before refactoring, I wrote `Unit Tests` to make sure nothing is broken after the changes are made. These tests did not need to be extensive covering all edge cases; neither should have many use cases covered as it had already passed the test cases of Google.
187+
I wanted to refactor the submitted code as it was done in a hurry. And prior to refactoring, I wrote `Unit Tests` to make sure that all the methods will work as before. Those tests did not needed to be extensive covering all edge cases; neither should have many use cases, the solution had already passed Google's test cases.
179188

180-
Google's first code challenge was fun, I turned it to an exhilarating moment :joy:.
189+
Previously, I had an interview with Google in July 2019. It was more of a casual talk I had with a nice lady to see if I fit the available role at a certain location. Unfortunately, it did not work out.
181190

182-
Previously, I had an interview with Google in July 2019. It was more of a casual talk I had with a nice lady who wanted to know a bit of me and to see if I fit the available role at a certain location. Unfortunately, it did not work out.
183-
184-
I am grateful for both opportunities but I must say I have enjoyed this experience more may be because I'm more of a code person.
191+
I am grateful for both opportunities but I have enjoyed this experience more may be because I'm more of a code person.
185192

186193
__Thank you Google!__
187194

188-
189195
If code is a better language to you then please find more at [Github](https://github.com/JavaCheatsheet/codechallenge).
190-
191-
192-
193-

0 commit comments

Comments
 (0)