Email Signature Generator - FreeCodeCamp Daily Challenge
4 min
π Problem Description
The challenge is to create a function that generates personalized email signatures. Given three strings (name, title, and company), we must return a formatted signature following specific rules.
Formatting Rules
Prefix based on nameβs initial:
A-I: Use>>as prefixJ-R: Use--as prefixS-Z: Use::as prefix
Signature structure:
[prefix][name], [title] at [company]Example
>>Alice Reed, Engineer at TechCo
--Quinn Waverly, Founder and CEO at TechCo
::Tina Vaughn, Developer at example.com
```javascript
generateSignature('Quinn Waverly', 'Founder and CEO', 'TechCo')
// Result: "--Quinn Waverly, Founder and CEO at TechCo"π Problem Analysis
Decision Flow
graph TD
A[Start] --> B[Get first letter of name]
B --> C[Convert to uppercase]
C --> D{Letter between A-I?}
D -->|Yes| E[Prefix: >>]
D -->|No| F{Letter between J-R?}
F -->|Yes| G[Prefix: --]
F -->|No| H{Letter between S-Z?}
H -->|Yes| I[Prefix: ::]
H -->|No| J[Empty prefix]
E --> K[Build signature]
G --> K
I --> K
J --> K
K --> L[Return result]
Test Cases
graph LR
A[Alice Reed] -->|A-I| B[>>Alice Reed, Engineer at TechCo]
C[Quinn Waverly] -->|J-R| D[--Quinn Waverly, Founder and CEO at TechCo]
E[Tina Vaughn] -->|S-Z| F[::Tina Vaughn, Developer at example.com]
π‘ Solution
JavaScript Implementation
function generateSignature(name, title, company) {
const firstNameLetter = name[0].toUpperCase()
let prefix = ''
if (firstNameLetter >= 'A' && firstNameLetter <= 'I') {
prefix = '>>'
}
else if (firstNameLetter >= 'J' && firstNameLetter <= 'R') {
prefix = '--'
}
else if (firstNameLetter >= 'S' && firstNameLetter <= 'Z') {
prefix = '::'
}
return `${prefix}${name}, ${title} at ${company}`
}π― Edge Cases and Considerations
Special Cases Table
| Case | Input | Output | Consideration |
|---|---|---|---|
| Lowercase name | "windstorm" | "::windstorm, ..." | Converted to uppercase for comparison |
| Name with initials | "B. B." | ">>B. B., ..." | Takes first character |
| Empty name | "" | Potential error | Requires validation |
| Special character | "@lex" | ", ..." | Empty prefix |
Edge Cases Diagram
mindmap
root((Edge Cases))
Names
Empty
Leading spaces
Special characters
Only initials
Input
Empty titles
Empty companies
Strings needing trim
Comparison
Case sensitivity
Non-alphabetic characters
π Complexity Analysis
Time Complexity: O(1)
graph LR
A["Access name[0]"] -->|O1| B["toUpperCase conversion"]
B -->|O1| C["Conditional comparisons"]
C -->|O1| D["String concatenation"]
D -->|O1| E["Return result"]
style A fill:#e1f5ff, stroke:#333, stroke-width:1px
style B fill:#fff2e8, stroke:#333, stroke-width:1px
style C fill:#fff2e8, stroke:#333, stroke-width:1px
style D fill:#fff2e8, stroke:#333, stroke-width:1px
style E fill:#e1f5ff, stroke:#333, stroke-width:1px
- First character access: O(1)
- Uppercase conversion: O(1)
- Comparisons: O(1) - maximum 3 comparisons
- Concatenation: O(1) for fixed-length strings
Space Complexity: O(1)
Only temporary variables (firstNameLetter, prefix) are used, regardless of input size.
π§ Possible Optimizations
1. Input Validation
function generateSignature(name, title, company) {
// Validation
if (!name || name.trim().length === 0) {
throw new Error('Name cannot be empty')
}
const trimmedName = name.trim()
const firstNameLetter = trimmedName[0].toUpperCase()
let prefix = ''
if (firstNameLetter >= 'A' && firstNameLetter <= 'I') {
prefix = '>>'
}
else if (firstNameLetter >= 'J' && firstNameLetter <= 'R') {
prefix = '--'
}
else if (firstNameLetter >= 'S' && firstNameLetter <= 'Z') {
prefix = '::'
}
return `${prefix}${trimmedName}, ${title} at ${company}`
}2. Using Map for Prefixes
function generateSignature(name, title, company) {
const prefixMap = {
'A-I': '>>',
'J-R': '--',
'S-Z': '::'
}
const firstLetter = name[0].toUpperCase()
let prefix = ''
if (firstLetter >= 'A' && firstLetter <= 'I')
prefix = prefixMap['A-I']
else if (firstLetter >= 'J' && firstLetter <= 'R')
prefix = prefixMap['J-R']
else if (firstLetter >= 'S' && firstLetter <= 'Z')
prefix = prefixMap['S-Z']
return `${prefix}${name}, ${title} at ${company}`
}3. Finding First Valid Letter with Regex
function generateSignature(name, title, company) {
// Find first alphabetic letter
const match = name.match(/[a-z]/i)
if (!match)
return `${name}, ${title} at ${company}`
const firstLetter = match[0].toUpperCase()
let prefix = ''
if (firstLetter >= 'A' && firstLetter <= 'I')
prefix = '>>'
else if (firstLetter >= 'J' && firstLetter <= 'R')
prefix = '--'
else if (firstLetter >= 'S' && firstLetter <= 'Z')
prefix = '::'
return `${prefix}${name}, ${title} at ${company}`
}π§ͺ Testing
Test Suite
const testCases = [
{
input: ['Quinn Waverly', 'Founder and CEO', 'TechCo'],
expected: '--Quinn Waverly, Founder and CEO at TechCo'
},
{
input: ['Alice Reed', 'Engineer', 'TechCo'],
expected: '>>Alice Reed, Engineer at TechCo'
},
{
input: ['Tina Vaughn', 'Developer', 'example.com'],
expected: '::Tina Vaughn, Developer at example.com'
},
{
input: ['B. B.', 'Product Tester', 'AcmeCorp'],
expected: '>>B. B., Product Tester at AcmeCorp'
},
{
input: ['windstorm', 'Cloud Architect', 'Atmospheronics'],
expected: '::windstorm, Cloud Architect at Atmospheronics'
}
]
testCases.forEach(({ input, expected }, index) => {
const result = generateSignature(...input)
console.log(`Test ${index + 1}: ${result === expected ? 'β
PASS' : 'β FAIL'}`)
})π Key Concepts Learned
String Manipulation
- Individual character access
- Case conversion
- Template literals for concatenation
Character Comparison
- Lexicographic comparison in JavaScript
- Case-insensitive matching
Conditional Structures
- Efficient use of if-else if
- Alternatives with switch or maps
Input Validation
- Edge case handling
- Defensive programming
π Resources and References
- String.prototype.toUpperCase() - MDN
- String.prototype.charAt() - MDN
- Template Literals - MDN
- Regular Expressions in JS - MDN
π Final Thoughts
This exercise, though seemingly simple, allows us to practice fundamental concepts:
- Clear and maintainable conditional logic
- Efficient string handling
- Edge case consideration from the start
- Optimization without over-engineering
The proposed solution is straightforward and readable, with constant time and space complexity, making it ideal for production.
Did you like this article? Share it and follow me for more programming challenge solutions! π