Skip to content

Commit 23d24fe

Browse files
feat: implement greatest common divisor of strings
1 parent aba8a20 commit 23d24fe

File tree

2 files changed

+63
-0
lines changed

2 files changed

+63
-0
lines changed

Diff for: src/algorithms/common-divisor/common-divisor.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* Finds the greatest common divisor string of two strings.
3+
* A string is a divisor if concatenating it multiple times produces the original string.
4+
*
5+
* @param str1 First string (1 <= length <= 1000)
6+
* @param str2 Second string (1 <= length <= 1000)
7+
* @returns The largest common divisor string, or empty string if none exists
8+
*/
9+
export const gcdOfStrings = (str1: string, str2: string): string => {
10+
// If concatenation in both orders isn't equal, no solution exists
11+
if (str1 + str2 !== str2 + str1) {
12+
return '';
13+
}
14+
15+
// Helper function to calculate GCD of two numbers using Euclidean algorithm
16+
const gcd = (a: number, b: number): number => {
17+
return b === 0 ? a : gcd(b, a % b);
18+
};
19+
20+
// The length of the GCD string will be the GCD of the lengths
21+
const gcdLength = gcd(str1.length, str2.length);
22+
23+
// The potential GCD string is the first gcdLength characters
24+
const candidate = str1.slice(0, gcdLength);
25+
26+
// Verify if this candidate actually divides both strings
27+
const divides = (str: string, divisor: string): boolean => {
28+
const times = str.length / divisor.length;
29+
return divisor.repeat(times) === str;
30+
};
31+
32+
return divides(str1, candidate) && divides(str2, candidate) ? candidate : '';
33+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { describe, expect, test } from 'vitest';
2+
import { gcdOfStrings } from '../common-divisor';
3+
4+
describe('gcdOfStrings', () => {
5+
test('finds GCD when one string is a multiple of the other', () => {
6+
expect(gcdOfStrings('ABCABC', 'ABC')).toBe('ABC');
7+
});
8+
9+
test('finds GCD when both strings have a common divisor', () => {
10+
expect(gcdOfStrings('ABABAB', 'ABAB')).toBe('AB');
11+
});
12+
13+
test('returns empty string when no common divisor exists', () => {
14+
expect(gcdOfStrings('LEET', 'CODE')).toBe('');
15+
});
16+
17+
test('handles identical strings', () => {
18+
expect(gcdOfStrings('AAA', 'AAA')).toBe('AAA');
19+
});
20+
21+
test('handles single character strings', () => {
22+
expect(gcdOfStrings('A', 'A')).toBe('A');
23+
});
24+
25+
test('handles longer strings with common divisor', () => {
26+
expect(
27+
gcdOfStrings('TAUXXTAUXXTAUXXTAUXXTAUXX', 'TAUXXTAUXXTAUXXTAUXX'),
28+
).toBe('TAUXX');
29+
});
30+
});

0 commit comments

Comments
 (0)