한번씩 읽고 가세요.
“ 지연되는 프로젝트에 인력을 더 투입하면 오히려 더 늦어진다. ”
- Frederick Philips Brooks
Mythical Man-Month 저자
1.
1차원의 점들이 주어졌을 때, 그 중 가장 거리가 짧은 것의 쌍을 출력하는 함수를 작성하시오. (단 점들의 배열은 모두 정렬되어있다고 가정한다.)예를들어 S={1, 3, 4, 8, 13, 17, 20} 이 주어졌다면, 결과값은 (3, 4)가 될 것이다.
풀이
s = [1, 3, 4, 8, 13, 17, 20]
index = 0
minim = Infinity
for (let i = 1; i < s.length; i++) {
if (s[i] - s[i-1] < minim) {
index = i
minim = s[i] - s[i-1]
}
}
console.log(s[index], s[index-1])
주어진 배열 s에서 연속된 두 요소 간의 차이가 가장 작은 인덱스를 찾아 그 인덱스와 그 전 인덱스의 값을 출력하는 것입니다.
- 먼저, index 변수를 0으로 초기화하고, minim 변수를 양의 무한대(Infinity)로 초기화합니다.
- 반복문을 통해 i를 1부터 s의 길이까지 증가시킵니다.
- 조건문을 사용하여 s[i] - s[i-1]이 minim보다 작을 경우, index를 i로 업데이트하고 minim을 s[i] - s[i-1]로 업데이트합니다.
- 반복문이 종료되면, s[index]와 s[index-1]의 값을 출력합니다.
따라서, s[index]는 연속된 두 요소 간의 차이가 가장 작은 값을, s[index-1]은 그 전 인덱스의 값을 나타냅니다.
두 번째 코드에서는 다른 방법으로 동일한 결과를 얻으려고 합니다. 코드를 단계별로 해석해보면 다음과 같습니다:
- s 배열에서 첫 번째 요소를 제외한 새로운 배열 ss를 생성합니다. (s.slice(1))
- s 배열의 각 요소와 ss 배열의 동일한 인덱스에 있는 요소를 페어로 매핑합니다. (s.map((v, i) => [v, ss[i]]))
- 매핑된 페어들을 연속된 두 요소의 차이 순으로 정렬합니다. (sort((a, b) => (a[1]-a[0]) - (b[1]-b[0])))
- 정렬된 페어들 중 첫 번째 페어를 선택합니다. ([0])
결과적으로, 두 번째 코드에서는 s 배열에서 연속된 두 요소 간의 차이가 가장 작은 페어를 반환하는 것입니다. 이 페어의 첫 번째 요소는 연속된 두 요소 중 뒷 요소이고, 두 번째 요소는 그 전 인덱스의 요소입니다.
다른 풀이
s = [1, 3, 4, 8, 13, 17, 20]
ss = s.slice(1)
s.map((v, i) => [v, ss[i]])
s.map((v, i) => [v, ss[i]]).sort((a, b) => (a[1]-a[0]) - (b[1]-b[0]))[0]
2.
문자열을 입력받아서, 같은 문자가 연속적으로 반복되는 경우에 그 반복 횟수를 표시하여 문자열을 압축하기.
입력 예시: aaabbcccccca
출력 예시: a3b2c6a1
풀이
const s = 'aaabbcccccca'
let result = s[0]
let count = 0
for (let str of s){
console.log(str)
console.log(result)
if (str == result.slice(-1)){
count += 1
}
else {
result += count + str
count = 1
}
}
result += count
console.log(result)
// ---
const s = "aaabbcccccca";
const reg = /(\w)\1*/g;
[...s.matchAll(reg)]
// ---
var strzip = str => str.replace(/(\D)\1*/g, s => s[0] + s.length);
console.log(strzip("aaabbcccccca"));
console.log(strzip("abcdefg"));
- 문자열 s와 압축 결과를 저장할 변수 result를 선언하고, s의 첫 번째 문자를 result에 할당합니다.
- 개수를 세기 위한 변수 count를 0으로 초기화합니다.
- for...of 루프를 사용하여 문자열 s의 각 문자에 대해 반복합니다.
- 현재 문자 str과 result의 마지막 문자를 비교하여 같을 경우, count를 1 증가시킵니다.
- 다른 문자일 경우, result에 count와 str을 이어붙이고 count를 1로 초기화합니다.
- 반복이 끝나면, 마지막으로 세어지지 않은 연속된 문자열의 개수를 result에 추가합니다.
- result를 출력합니다.
이렇게 하면 result에는 주어진 문자열 s가 연속된 문자들을 세어 압축된 형태로 변환된 결과가 저장됩니다.
두 번째 코드는 정규 표현식을 사용하여 문자열 s에서 연속된 문자열을 매칭하는 것입니다.
- 정규 표현식 /(\w)\1*/g를 사용하여 s에서 연속된 문자열을 매칭합니다.
- matchAll 메서드를 사용하여 정규 표현식에 매칭되는 모든 결과를 가져옵니다.
- 반환된 결과는 이터러블 객체이므로 [... ]를 사용하여 배열로 변환합니다.
이렇게 하면 s에서 연속된 문자열을 매칭하여 배열로 얻을 수 있습니다.
세 번째 코드는 문자열을 압축하는 함수 strzip을 정의하고, 해당 함수를 테스트하는 부분입니다.
- strzip 함수는 주어진 문자열 str을 인자로 받습니다.
- replace 메서드를 사용하여 정규 표현식 /(\D)\1*/g에 매칭되는 부분을 찾아 교체합니다.
- 교체할 문자열은 매칭된 문자열의 첫 번째 문자와 길이로 구성됩니다. (s[0] + s.length)
- strzip 함수를 사용하여 "aaabbcccccca"와 "abcdefg"에 대한 결과를 출력합니다.
따라서, 세 번째 코드는 주어진 문자열을 압축하는 함수를 정의하고 이를 테스트하는 부분으로 구성되어 있습니다.