Skip to content

Commit 21c52a9

Browse files
committed
Update title content
1 parent ab65585 commit 21c52a9

26 files changed

+1146
-4
lines changed

Diff for: gatsby-config.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ module.exports = {
2121
'Technical Articles',
2222
'Programming Blog',
2323
],
24-
title: "Anit Shrestha Manandhar | Software Development Service | Blog",
24+
title: "Blog By Anit Shrestha Manandhar",
2525
titleAlt: 'codeanit.com',
2626
description:
2727
"Anit is a hands-on code experienced software engineer who blogs and provides software development service.",
@@ -76,8 +76,8 @@ module.exports = {
7676
{
7777
resolve: `gatsby-plugin-manifest`,
7878
options: {
79-
name: `Technical Blog by Anit Shrestha Manandhar.`,
80-
short_name: `blog by codeanit`,
79+
name: `Blog By Anit Shrestha Manandhar.`,
80+
short_name: `Blog By Anit`,
8181
start_url: `/`,
8282
background_color: `#ffffff`,
8383
theme_color: `#ffffff`,

Diff for: package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "codeanit.com",
33
"author": "Anit Shrestha Manandhar @codeanit <[email protected]>",
4-
"description": "Anit Shrestha Manandhar | Software Development Service | Blog",
4+
"description": "Blog By Anit",
55
"version": "0.5.0",
66
"private": true,
77
"scripts": {

Diff for: test-content/.gitkeep

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
---
2+
title: Google FooBar First Challenge
3+
subtitle: Solving Caesar Cipher
4+
date: '2020-07-19'
5+
categories: ['google', 'challenge', 'series', 'cipher']
6+
keywords: ['google', 'challenge', 'series', 'cipher', 'first', 'caesar']
7+
slug: google-foobar-first-challenge-caesar-cipher
8+
cover: './img/google-foobar-first-challenge-solved.png'
9+
type: 'Blog'
10+
---
11+
12+
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.
15+
16+
### The Challenge
17+
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".
18+
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)
25+
26+
### Initial Thoughts
27+
The rough idea I could come up after the analysis was:
28+
- Manipulation of the ASCII value of the letters
29+
- Simple maths, addition/subtraction, on numeric value of letters
30+
31+
Since converting this idea into a concrete algorithm was taking longer than expected, I moved to another solution.
32+
33+
### First Attempt
34+
The next simplest design for the solution I could come up with consisted of the following data structures:
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+
39+
```java
40+
public static String solnWithStrBuilder(String x) {
41+
StringBuilder stb = new StringBuilder();
42+
x.chars().forEach(i -> stb.append(decrypt(i)));
43+
return stb.toString();
44+
}
45+
public static char decrypt(int 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;
56+
}
57+
```
58+
59+
The implementation provided desired output in the local environment but it failed to pass the tests.
60+
61+
### Second Iteration
62+
I reflected back on the constraints and refactored the code to use more primitive data structure:
63+
- Replaced `StringBuilder` with `Character Array`
64+
65+
```java
66+
public static String solnWithArray(String encryptedText) {
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);
81+
}
82+
```
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.
85+
86+
### Third Iteration
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.
88+
89+
Then I searched for similar problems and solutions to find answers to these questions:
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.
94+
95+
```java
96+
StringBuilder result = new StringBuilder();
97+
for (char character : message.toCharArray()) {
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+
}
106+
}
107+
return result;
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.
115+
116+
`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.`
117+
118+
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+
120+
```java
121+
public static String encrypt(String textToEncrypt) {
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);
133+
}
134+
```
135+
136+
After generating the exact cipher, It was pretty much easier to write a program to decipher.
137+
138+
```java
139+
public static String solutionWithOffset(String encryptedText) {
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);
151+
}
152+
```
153+
154+
I submitted the solution then again it failed.
155+
156+
__Time <10mins!__
157+
158+
### Accepted Solution
159+
Refactored the code:
160+
- Replaced `StringBuilder` with `Character Array`.
161+
162+
```java
163+
public static String solution(String x) {
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);
177+
}
178+
```
179+
180+
__Yay! All Tests Passed. Time <2mins.__
181+
182+
**Solution Submitted.**
183+
184+
### Review
185+
The next day I reviewed the solution and recalled the overall process. Phew! It was a close call.
186+
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 need to be extensive covering all edge cases; neither should have many use cases, the solution had already passed Google's test cases.
188+
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.
190+
191+
I am grateful for both opportunities but I have enjoyed this experience more may be because I'm more of a code person.
192+
193+
__Thank you Google!__
194+
195+
If code is a better language to you then please find more at [Github](https://github.com/JavaCheatsheet/codechallenge).

Diff for: test-content/img/application_hosting_evolution.svg

+1
Loading

Diff for: test-content/img/gatsbyjs-logo-banner.jpg

8.75 KB
Loading
44.1 KB
Loading

0 commit comments

Comments
 (0)