πŸ‘©‍πŸ’»/JavaScript

[Programmers] μ‹ κ·œ 아이디 μΆ”μ²œν•˜κΈ° (JavaScript/μ •κ·œμ‹)

ν•œλ‚˜ 2021. 1. 29. 20:20

문제

μ‹ κ·œ 아이디 μΆ”μ²œ 문제. 

 

μΉ΄μΉ΄μ˜€μ— μž…μ‚¬ν•œ μ‹ μž… 개발자 λ„€μ˜€λŠ” μΉ΄μΉ΄μ˜€κ³„μ •κ°œλ°œνŒ€μ— λ°°μΉ˜λ˜μ–΄, 카카였 μ„œλΉ„μŠ€μ— κ°€μž…ν•˜λŠ” μœ μ €λ“€μ˜ 아이디λ₯Ό μƒμ„±ν•˜λŠ” 업무λ₯Ό λ‹΄λ‹Ήν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€. λ„€μ˜€μ—κ²Œ 주어진 첫 μ—…λ¬΄λŠ” μƒˆλ‘œ κ°€μž…ν•˜λŠ” μœ μ €λ“€μ΄ 카카였 아이디 κ·œμΉ™μ— λ§žμ§€ μ•ŠλŠ” 아이디λ₯Ό μž…λ ₯ν–ˆμ„ λ•Œ, μž…λ ₯된 아이디와 μœ μ‚¬ν•˜λ©΄μ„œ κ·œμΉ™μ— λ§žλŠ” 아이디λ₯Ό μΆ”μ²œν•΄μ£ΌλŠ” ν”„λ‘œκ·Έλž¨μ„ κ°œλ°œν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
λ‹€μŒμ€ 카카였 μ•„μ΄λ””μ˜ κ·œμΉ™μž…λ‹ˆλ‹€.
  • μ•„μ΄λ””μ˜ κΈΈμ΄λŠ” 3자 이상 15자 μ΄ν•˜μ—¬μ•Ό ν•©λ‹ˆλ‹€.
  • μ•„μ΄λ””λŠ” μ•ŒνŒŒλ²³ μ†Œλ¬Έμž, 숫자, λΉΌκΈ°(-), 밑쀄(_), λ§ˆμΉ¨ν‘œ(.) 문자만 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
  • 단, λ§ˆμΉ¨ν‘œ(.)λŠ” 처음과 끝에 μ‚¬μš©ν•  수 μ—†μœΌλ©° λ˜ν•œ μ—°μ†μœΌλ‘œ μ‚¬μš©ν•  수 μ—†μŠ΅λ‹ˆλ‹€.

λ„€μ˜€λŠ” λ‹€μŒκ³Ό 같이 7λ‹¨κ³„μ˜ 순차적인 처리 과정을 톡해 μ‹ κ·œ μœ μ €κ°€ μž…λ ₯ν•œ 아이디가 카카였 아이디 κ·œμΉ™μ— λ§žλŠ” 지 κ²€μ‚¬ν•˜κ³  κ·œμΉ™μ— λ§žμ§€ μ•Šμ€ 경우 κ·œμΉ™μ— λ§žλŠ” μƒˆλ‘œμš΄ 아이디λ₯Ό μΆ”μ²œν•΄ μ£Όλ €κ³  ν•©λ‹ˆλ‹€.

 

1단계 new_id의 λͺ¨λ“  λŒ€λ¬Έμžλ₯Ό λŒ€μ‘λ˜λŠ” μ†Œλ¬Έμžλ‘œ μΉ˜ν™˜ν•©λ‹ˆλ‹€.

2단계 new_idμ—μ„œ μ•ŒνŒŒλ²³ μ†Œλ¬Έμž, 숫자, λΉΌκΈ°(-), 밑쀄(_), λ§ˆμΉ¨ν‘œ(.)λ₯Ό μ œμ™Έν•œ λͺ¨λ“  문자λ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

3단계 new_idμ—μ„œ λ§ˆμΉ¨ν‘œ(.)κ°€ 2번 이상 μ—°μ†λœ 뢀뢄을 ν•˜λ‚˜μ˜ λ§ˆμΉ¨ν‘œ(.)둜 μΉ˜ν™˜ν•©λ‹ˆλ‹€.

4단계 new_idμ—μ„œ λ§ˆμΉ¨ν‘œ(.)κ°€ μ²˜μŒμ΄λ‚˜ 끝에 μœ„μΉ˜ν•œλ‹€λ©΄ μ œκ±°ν•©λ‹ˆλ‹€.

5단계 new_idκ°€ 빈 λ¬Έμžμ—΄μ΄λΌλ©΄, new_id에 "a"λ₯Ό λŒ€μž…ν•©λ‹ˆλ‹€.

6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ λ¬Έμžλ“€μ„ λͺ¨λ‘ μ œκ±°ν•©λ‹ˆλ‹€. λ§Œμ•½ 제거 ν›„ λ§ˆμΉ¨ν‘œ(.)κ°€ new_id의 끝에 μœ„μΉ˜ν•œλ‹€λ©΄ 끝에 μœ„μΉ˜ν•œ λ§ˆμΉ¨ν‘œ(.) 문자λ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

7단계 new_id의 길이가 2자 μ΄ν•˜λΌλ©΄, new_id의 λ§ˆμ§€λ§‰ 문자λ₯Ό new_id의 길이가 3이 될 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•΄μ„œ 끝에 λΆ™μž…λ‹ˆλ‹€.

μ½”λ“œ

풀이

μ •κ·œμ‹κ³Ό λ¬Έμžμ—΄μ„ λ‹€λ£¨λŠ” λ©”μ„œλ“œλ₯Ό 적절히 ν™œμš©ν•΄ 순차적으둜 ν‘ΈλŠ” λ¬Έμ œμ΄λ‹€.

1λ‹¨κ³„λŠ” λ¬Έμžμ—΄μ˜ λͺ¨λ“  λŒ€λ¬Έμžλ₯Ό λŒ€μ‘λ˜λŠ” μ†Œλ¬Έμžλ‘œ μΉ˜ν™˜ν•˜λ―€λ‘œ toLowerCase()λ₯Ό μ‚¬μš©ν•œλ‹€.

만일 μ •κ·œμ‹μœΌλ‘œ λŒ€λ¬Έμžλ§Œ κ³¨λΌμ„œ λ°”κΎΌλ‹€κ³  ν•˜λ©΄, id.replace(/[A-Z]/g, (match) => match.toLowerCase());  μ΄λ ‡κ²Œλ„ 써볼 수 μžˆκ² μ§€λ§Œ, 효율이 떨어진닀.

 

2λ‹¨κ³„λŠ” νŠΉμ • λ¬Έμžλ“€μ„ μ œκ±°ν•  수 μžˆλ„λ‘ μ •κ·œμ‹μ„ μ“΄λ‹€.

id.replace(/[^a-z0-9\-_.]/g, ""); ν•œ 번 lowerCase둜 λ°”κΏ”μ£Όμ—ˆμ§€λ§Œ, a-z둜 λͺ…μ‹œμ μœΌλ‘œ λ‚˜νƒ€λ‚Ό μˆ˜λ„ 있고, μ•„λž˜ 그림처럼 \w둜 λͺ¨λ“  λΌν‹΄κ³„μ—΄μ˜ 문자λ₯Ό λ‚˜νƒ€λ‚΄λŠ” Character Classλ₯Ό 써주어도 λœλ‹€.

(단, \wμ—λŠ” μˆ«μžμ™€ 밑쀄을 ν¬ν•¨ν•œλ‹€)

[ ] λŒ€λ¬Έμž μ•ˆμ— μ“΄ ^(캐럿) κΈ°ν˜ΈλŠ” λŒ€λ¬Έμž 내뢀에 써둔 0-9(숫자) a-z(μ†Œλ¬Έμž), -(ν•˜μ΄ν”ˆ), _ (언더바), .(λ§ˆμΉ¨ν‘œ)λ₯Ό μ œμ™Έν•œλ‹€λŠ” μ˜λ―Έμ΄λ‹€.

 

Test String에 ν•˜μ΄λΌμ΄νŠΈλœ 뢀뢄이 μ œμ™Έλ  문자λ₯Ό 가리킨닀.

 

\wλŠ” 라틴 λ¬Έμžλ‚˜ 숫자, 밑쀄을 ν¬ν•¨ν•˜λŠ” 문자 ν΄λž˜μŠ€μ΄λ‹€.

3단계 new_idμ—μ„œ λ§ˆμΉ¨ν‘œ(.)κ°€ 2번 이상 μ—°μ†λœ 뢀뢄을 ν•˜λ‚˜μ˜ λ§ˆμΉ¨ν‘œ(.)둜 μΉ˜ν™˜ν•΄μ•Ό ν•˜λ―€λ‘œ, μ •κ·œμ‹μ„ 써쀀닀.

id.replace(/[.]{2,}/g, "."); 둜 μ¨μ£Όκ±°λ‚˜, id.replace(/\.+/g, ".")둜 λͺ¨λ“  λ§ˆμΉ¨ν‘œ(.)λ₯Ό λ§ˆμΉ¨ν‘œ ν•˜λ‚˜λ‘œ λ°”κΎΈλŠ” λ°©μ‹μœΌλ‘œ 써쀄 μˆ˜λ„ μžˆκ² λ‹€.

μ§€μ •ν•œ 길이의 λ¬Έμžμ—΄μ„ 찾을 λ•ŒλŠ” μ€‘κ΄„ν˜Έλ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€. {min, max} 즉, μ΅œμ†Œ λ¬Έμžμ—΄ 길이와 μ΅œλŒ€ λ¬Έμžμ—΄ 길이λ₯Ό 각각 λͺ…μ‹œν•  수 있고, μ΅œμ†Œ κΈΈμ΄λ‚˜ μ΅œλŒ€ 길이만 μ§€μ •ν•˜κ³ μž ν•  λ•ŒλŠ” μ™Όμͺ½ 그림처럼 μ‰Όν‘œλ‘œ κ΅¬λΆ„ν•˜κ³  자리λ₯Ό λ‚¨κ²¨λ‘λ©΄λœλ‹€.

λ”°λΌμ„œ μ™Όμͺ½ μ •κ·œμ‹μ€ μ΅œμ†Œ 2개 μ΄μƒμ˜ λ§ˆμΉ¨ν‘œλ₯Ό μ°ΎλŠ”λ‹€.

 

 

λ˜λŠ” {1,}κ³Ό λ™μΌν•œ 역할을 ν•˜λŠ” +(λ”ν•˜κΈ° 기호) quantifierλ₯Ό μ‚¬μš©ν•΄λ„ 같은 κ²°κ³Όλ₯Ό 얻을 수 μžˆλ‹€.

 

4단계 new_idμ—μ„œ λ§ˆμΉ¨ν‘œ(.)κ°€ μ²˜μŒμ΄λ‚˜ 끝에 μœ„μΉ˜ν•œλ‹€λ©΄ μ œκ±°ν•œλ‹€. μ΄λ•Œ λ¬Έμžμ—΄μ΄ 빈 λ¬Έμžμ—΄μΌ 경우λ₯Ό κ°μ•ˆν•΄, κ·Έ κ²½μš°μ—λŠ” λ°”λ‘œ 5λ‹¨κ³„λ‘œ λ„˜μ–΄κ°ˆ 수 μžˆλ„λ‘ 뢄기해쀬닀. λ¬Έμžμ—΄ 길이가 0이상일 경우 id[0] id의 첫 번째 κΈ€μžκ°€ λ§ˆμΉ¨ν‘œμ™€ λ™μΌν•˜λ‹€λ©΄, id.substring(1)으둜, 0번째 인덱슀λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ λΆ€λΆ„ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•œλ‹€. λ§ˆμ°¬κ°€μ§€λ‘œ λ§ˆμ§€λ§‰ κΈ€μžκ°€ λ§ˆμΉ¨ν‘œμ™€ λ™μΌν•˜λ‹€λ©΄, id.slice(0, -1)둜 λ§ˆμ§€λ§‰ 인덱슀λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ λΆ€λΆ„ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν–ˆλ‹€. slice λ©”μ„œλ“œμ˜ 두 번째 인자λ₯Ό -1둜 ν‘œν˜„ν–ˆλŠ”λ° μ΄λŠ”, id.length - 1κ³Ό λ™μΌν•˜λ‹€.

 

κ·Έ ν›„ 5λ‹¨κ²Œμ—μ„œλŠ” 빈 λ¬Έμžμ—΄μΌ 경우 λ¬Έμžμ—΄ "a"λ₯Ό μΆ”κ°€ν•΄μ€€λ‹€. 빈 λ¬Έμžμ—΄μ„ μ •κ·œμ‹μœΌλ‘œ ν‘œν˜„ν•΄λ„ λœλ‹€.

console.log("  ".replace(/^\s+$|^$/gi, "a")); // a
console.log("".replace(/^\s+$|^$/gi, "a")); // a

6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자λ₯Ό μ œμ™Έν•œ λ‚˜λ¨Έμ§€ λ¬Έμžλ“€μ„ λͺ¨λ‘ μ œκ±°ν•©λ‹ˆλ‹€. λ§Œμ•½ 제거 ν›„ λ§ˆμΉ¨ν‘œ(.)κ°€ new_id의 끝에 μœ„μΉ˜ν•œλ‹€λ©΄ 끝에 μœ„μΉ˜ν•œ λ§ˆμΉ¨ν‘œ(.) 문자λ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.

 

λ¬Έμžμ—΄μ΄ 16이상인 κ²½μš°μ—λ§Œ 6단계λ₯Ό μˆ˜ν–‰ν•˜λ„λ‘ λΆ„κΈ°ν•˜κ³ , idλŠ” slice() λ©”μ„œλ“œλ‘œ λ¬Έμžμ—΄ 길이λ₯Ό μ œν•œν•œλ‹€. λ§ˆμ§€λ§‰ κΈ€μžκ°€ λ§ˆμΉ¨ν‘œμΈ κ²½μš°λŠ” 4λ‹¨κ³„μ—μ„œ μ‚¬μš©ν•œ 방법을 λ°˜λ³΅ν•΄ μ‚¬μš©ν•œλ‹€.

 

λ§ˆμ§€λ§‰ λ‹¨κ³„μ—μ„œλŠ” 길이가 2자 μ΄ν•˜λΌλ©΄, new_id의 λ§ˆμ§€λ§‰ 문자λ₯Ό new_id의 길이가 3이 될 λ•ŒκΉŒμ§€ λ°˜λ³΅ν•΄μ„œ 끝에 λΆ™μž…λ‹ˆλ‹€.

 

λ‚˜μ˜ κ²½μš°μ—λŠ” while 반볡문으둜 += μ—°μ‚°μžλ‘œ id의 λ§ˆμ§€λ§‰ κΈ€μžλ₯Ό 이어주도둝 ν–ˆλŠ”λ°, λ‹€λ₯Έ 풀이λ₯Ό λ³΄λ‹ˆ repeat λ©”μ„œλ“œλ‚˜ padEnd λ©”μ„œλ“œλ₯Ό μ‚¬μš©ν•˜λŠ” 방법도 μžˆμ—ˆλ‹€. 

// repeat()
id + id[id.length - 1].repeat(3-id.length);

// padEnd()
id.padEnd(3, id[id.length - 1]);

repeat() λ©”μ„œλ“œλŠ” λ¬Έμžμ—΄μ„ 주어진 횟수만큼 λ°˜λ³΅ν•΄ 뢙인 μƒˆλ‘œμš΄ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•œλ‹€. str.repeat(count) μ—μ„œ count νŒŒλΌλ―Έν„°λŠ” λ¬Έμžμ—΄μ„ λ°˜λ³΅ν•  횟수λ₯Ό μž…λ ₯ν•œλ‹€.

 

padEnd() λ©”μ„œλ“œλŠ” ν˜„μž¬ λ¬Έμžμ—΄μ— λ‹€λ₯Έ λ¬Έμžμ—΄μ„ μ±„μ›Œ 주어진 길이λ₯Ό λ§Œμ‘±ν•˜λŠ” μƒˆλ‘œμš΄ λ¬Έμžμ—΄μ„ λ°˜ν™˜ν•œλ‹€. λŒ€μƒ λ¬Έμžμ—΄μ˜ μš°μΈ‘λΆ€ν„° μ μš©λœλ‹€.