Skip to content

Instantly share code, notes, and snippets.

@BongJaeChoi
Last active June 19, 2024 18:47
Show Gist options
  • Save BongJaeChoi/abbfdfe14fba2e50588a02117d81159a to your computer and use it in GitHub Desktop.
Save BongJaeChoi/abbfdfe14fba2e50588a02117d81159a to your computer and use it in GitHub Desktop.
카닥 클라이언트 챕터 과제 - 최봉재
function stringToArray(target: string) {
return target.split("\n");
}
/**
* 1-1번 문제
*/
function countValidPassword(ar: string): number {
if (!ar.length) {
return 0;
}
const arr = stringToArray(ar);
//input 데이터 변환
return arr
.map((v) => {
const [num, char, pwd] = v.split(" ");
//유효성 검사를 위한 최소 숫자, 최대 숫자
const [min, max] = num.split("-");
//비교하려는 문자 ':' 제외
const target = char.replace(":", "");
//비교하려는 문자열 개수 추출
const count = [...pwd].filter((pwdValue) => pwdValue === target).length;
return { min, max, count };
})
.filter((v) => {
const { min, max, count } = v;
//최소 카운트보다 많거나 같고 최대 카운트 보다 적거나 같으면 true
return +min <= count && count <= +max;
}).length;
}
function stringToArray(target: string) {
return target.split("\n");
}
/**
* 1-2번 문제
*/
function countValidPasswordWithPosition(ar: string): number {
if (!ar.length) {
return 0;
}
const arr = stringToArray(ar);
//input 데이터 변환
return arr
.map((v) => {
const [num, char, pwd] = v.split(" ");
//포지션은 index가 아닌 자연수이므로 -1해서 사용
const [firstPosition, secondPosition] = num.split("-").map((v) => +v - 1);
//비교하려는 문자 ':' 제외
const target = char.replace(":", "");
return { target, firstPosition, secondPosition, pwd };
})
.filter((v) => {
const { target, firstPosition, secondPosition, pwd } = v;
const pwdArr = [...pwd];
//해당 포지션으로 카운트 조회
let count = 0;
if (pwdArr.at(firstPosition) === target) {
count++;
}
if (pwdArr.at(secondPosition) === target) {
count++;
}
//단 한개만 일치해야함
return count === 1;
}).length;
}
function stringToArray(target: string) {
return target.split("\n");
}
/**
* 2-1번 문제
*/
function countTree(ar: string) {
const arr = stringToArray(ar);
//일치하는 개수
let count = 0;
let col = 0;
//row는 1씩 루프에 의해 자동으로 증가
arr.forEach((v) => {
//col이 계속 증가할 수 있으므로 나머지로 환산하여 계산
//length는 같으므로 첫번째 인덱스 것을 계속 활용
if (v[col % arr[0].length] === "#") {
count += 1;
}
//경사가 3씩 증가
col += 3;
});
return count;
}
/**
* 2-2 문제
*/
function countAllTree(ar: string) {
let result = 1;
//여러개를 구해야하므로 배열생성
const restOfSlopes = [
{ right: 1, down: 1 },
{ right: 3, down: 1 },
{ right: 5, down: 1 },
{ right: 7, down: 1 },
{ right: 1, down: 2 },
];
restOfSlopes.forEach((v) => {
result *= countTreeWithColRow(ar, v.right, v.down);
});
return result;
}
function stringToArray(target: string) {
return target.split("\n");
}
function countTreeWithColRow(ar: string, col: number, row: number) {
const arr = stringToArray(ar);
//일치하는 개수
let result = 0;
let colPosition = 0;
for (let index = 0; index < arr.length; index += row) {
//col이 계속 증가할 수 있으므로 나머지로 환산하여 계산
//length는 같으므로 첫번째 인덱스 것을 계속 활용
if (arr[index][colPosition % arr[0].length] === "#") {
result += 1;
}
//경사 증가
colPosition += col;
}
return result;
}
/**
* 3-1 문제
*/
function processPassport(ar: string) {
//빈 줄바꿈을 기준으로 배열 생성
const passports = ar.split(/\n\s*\n/);
//비교대상 코드
const requireField = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"].sort(); //cid 는 제외
const result = passports
.map((v) => {
// ':' 앞에 있는 코드 추출
const keys = v.match(/[^:\s]+(?=:)/g) ?? [];
//cid 제외 처리
const cidKeyIndex = keys?.findIndex((v) => v === "cid");
if (cidKeyIndex !== -1) {
return keys?.toSpliced(cidKeyIndex, 1).toSorted();
}
//여권 내 cid 없을 경우
return keys.toSorted();
})
.filter((fv) => JSON.stringify(requireField) === JSON.stringify(fv)).length;
return result
}
/**
* 3-2 문제
*/
function processPassportHardValidate(ar: string) {
let result = 0;
//상수 선언
const colors = new Set(["amb", "blu", "brn", "gry", "grn", "hzl", "oth"]); // has 가 필요하여 변경
const keys = ["byr", "iyr", "eyr", "hgt", "hcl", "ecl", "pid"];
//조건식 추출
//초기작성은 정규식 + if 검사로 했으나 너무 복잡하고 hgt 케이스 대응이 어려워 함수로 변경
const validateCondition: Record<string, (input: string) => boolean> = {
byr: (input) => {
const numberValue = +input;
return numberValue >= 1920 && numberValue <= 2002;
},
iyr: (input) => {
const numberValue = +input;
return numberValue >= 2010 && numberValue <= 2020;
},
eyr: (input) => {
const numberValue = +input;
return numberValue >= 2020 && numberValue <= 2030;
},
hgt: (input) => {
if (input.endsWith("cm")) {
const parseCm = parseInt(input.replace("cm", ""), 10);
return parseCm >= 150 && parseCm <= 193;
}
if (input.endsWith("in")) {
const parseIn = parseInt(input.replace("in", ""), 10);
return parseIn >= 59 && parseIn <= 76;
}
return false;
},
hcl: (input) => /^#[0-9a-f]{6}$/.test(input),
ecl: (input) => colors.has(input),
pid: (input) => /^\d{9}$/.test(input),
cid: (_input) => true, // cid 필드예외처리
};
//데이터를 여권단위(배열)로 가공
const passports = ar.split(/\n\n/).map((v) => v.replaceAll("\n", " "));
for (const v of passports) {
const map = new Map();
const element = v.split(" ");
// console.log("element", element);
//여권내 필드만 추출 기준 필드와 비교
element.map((v) => {
const [key, value] = v.split(":");
map.set(key, value);
});
console.log("map", map);
const isAllHasKey = keys.every((v) => map.has(v));
if (!isAllHasKey) {
continue;
}
const isAllFieldValid = [...map.entries()].every(([key, value]) =>
validateCondition[key](value)
);
if (isAllFieldValid) {
result++;
}
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment