개발자 박가나
[241029 TIL] 본캠프 20일차 ('Medal Tracker 만들기' 프로젝트 1일차) 본문
📌 오늘의 TIL
|
알고리즘 'n^2 배열 자르기' 문제 풀이
/* 런타임 에러 코드 */
function solution(n, left, right) {
let answer = [];
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= n; j++) {
answer.push(i > j ? i : j);
}
}
return answer.slice(left, right + 1);
}
단순하게 n * n 크기의 배열을 만든 뒤 원하는 부분을 자르는 로직으로 코드를 작성했는데 런타임 에러가 발생을 했다. 구글링을 해보니 배열의 크기가 너무 커서 메모리적으로 과부화가 발생하는 것이 런타임 에러가 발생하는 대표적인 원인 중 하나였고, 다음과 같이 로직을 변경하였다.
- n * n 크기의 배열을 만든 후에 필요한 부분만 자르는 것이 아니라, 필요한 부분만을 배열로 만든다.
/* 시간 초과 코드 */
function solution(n, left, right) {
let answer = [];
for (let row = 1; row <= n; row++) {
for (let col = 1; col <= n; col++) {
const index = (row - 1) * n + col - 1;
if (index >= left && index <= right) {
answer.push(row > col ? row : col);
continue;
}
if (index > right) break;
}
}
return answer;
}
그 결과, 런타임 에러는 해결되었는데 이번엔 시간 초과가 발생을 했다. 다시 한 번 원인을 파악해보니 1행 1열부터 순회를 하면서 원하는 구간인지를 판별하는 로직이기 때문에 n의 값이 엄청나게 커지고 원하는 구간 또한 뒤쪽에 있으면 시간 초과가 발생할 수 밖에 없었고, 최종적으로 다음과 같이 해결하였다.
- 1행 1열부터 하나하나 순회를 하는 것이 아니라, 원하는 구간의 시작 좌표를 구한다.
/* 정답 코드 */
function solution(n, left, right) {
let answer = [];
let row = parseInt(left / n) + 1;
let col = (left % n) + 1;
let index = left;
while (index <= right) {
answer.push(row > col ? row : col);
row = col < n ? row : row + 1;
col = col < n ? col + 1 : 1;
index++;
}
return answer;
}
[Madal Tracker] 프로젝트
프로젝트 셋업
vite를 사용해서 프로젝트를 셋업해준다.
yarn create vite [폴더명] --template react
디자인 및 퍼블리싱
styled-components 라이브러리를 이용해서 스타일을 적용시켜 주었다.
/* styled-components 코드 */
import styled from 'styled-components';
const Container = styled.div`
max-width: 1000px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
gap: 20px;
border-radius: 8px;
background-color: #ffffff;
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
padding: 20px;
margin: 40px auto;
`;
const Title = styled.p`
color: #003580;
font-size: 32px;
font-weight: 700;
`;
const Form = styled.form`
display: flex;
align-items: end;
gap: 10px;
`;
const InputContainer = styled.div`
text-align: center;
`;
const InputTitle = styled.p`
color: #000000;
font-size: 16px;
font-weight: 700;
margin-bottom: 10px;
`;
const Input = styled.input`
width: 170px;
height: 40px;
border: 1px solid #dddddd;
border-radius: 4px;
color: #000000;
font-size: 14px;
padding: 10px;
&:focus {
outline: none;
}
`;
const CreateUpdate = styled.input`
width: 100px;
height: 40px;
border: none;
border-radius: 4px;
background-color: #ffcc00;
color: #000000;
font-size: 14px;
font-weight: 700;
cursor: pointer;
`;
const Message = styled.p`
color: #000000;
font-size: 16px;
text-align: center;
`;
const ListContainer = styled.div`
width: 100%;
border-radius: 8px;
overflow: hidden;
`;
const ListTitleContainer = styled.div`
display: flex;
background-color: #003580;
padding: 15px;
`;
const ListTitle = styled.div`
width: 20%;
color: #ffffff;
font-size: 16px;
font-weight: 700;
text-align: center;
`;
const ListValueContainer = styled.div`
display: flex;
align-items: center;
background-color: #f4f4f9;
padding: 15px;
&:nth-child(2n) {
background-color: #e6e6fa;
}
&:hover {
background-color: #dcdcdc;
}
`;
const ListValue = styled.div`
width: 20%;
color: #000000;
font-size: 14px;
text-align: center;
`;
const Delete = styled.button`
border: none;
border-radius: 4px;
background-color: #ff0000;
color: #ffffff;
font-size: 14px;
font-weight: 700;
padding: 5px 10px;
cursor: pointer;
`;
<!-- JSX 코드 -->
function App() {
const listItems = [
{ country: '대한민국', gold: 15, silver: 10, bronze: 7 },
{ country: '일본', gold: 7, silver: 12, bronze: 5 },
{ country: '중국', gold: 30, silver: 24, bronze: 14 }
];
return (
<Container>
<Title>2024 파리 올림픽</Title>
<Form>
<InputContainer>
<InputTitle>국가명</InputTitle>
<Input type="text" placeholder="국가 입력" />
</InputContainer>
<InputContainer>
<InputTitle>금메달</InputTitle>
<Input type="number" />
</InputContainer>
<InputContainer>
<InputTitle>은메달</InputTitle>
<Input type="number" />
</InputContainer>
<InputContainer>
<InputTitle>동메달</InputTitle>
<Input type="number" />
</InputContainer>
<CreateUpdate type="submit" value="국가 추가" />
<CreateUpdate type="submit" value="업데이트" />
</Form>
<Message>아직 추가된 국가가 없습니다. 메달을 추적하세요!</Message>
<ListContainer>
<ListTitleContainer>
<ListTitle>국가명</ListTitle>
<ListTitle>금메달</ListTitle>
<ListTitle>은메달</ListTitle>
<ListTitle>동메달</ListTitle>
<ListTitle>액션</ListTitle>
</ListTitleContainer>
{listItems.map((item, index) => {
return (
<ListValueContainer key={index}>
<ListValue>{item.country}</ListValue>
<ListValue>{item.gold}</ListValue>
<ListValue>{item.silver}</ListValue>
<ListValue>{item.bronze}</ListValue>
<ListValue>
<Delete type="button">삭제</Delete>
</ListValue>
</ListValueContainer>
);
})}
</ListContainer>
</Container>
);
}
export default App;
초기 상태 설정
useState()와 onSubmit() 등을 이용해서 초기 상태를 설정해준다.
/* JSX 코드 */
function App() {
const [country, setCountry] = useState('');
const [gold, setGold] = useState(0);
const [silver, setSilver] = useState(0);
const [bronze, setBronze] = useState(0);
/* 국가명 값 변경 */
const changeCountry = (e) => setCountry(e.target.value);
/* 금메달 값 변경 */
const changeGold = (e) => setGold(parseInt(e.target.value) < 0 ? 0 : parseInt(e.target.value));
/* 은메달 값 변경 */
const changeSilver = (e) => setSilver(parseInt(e.target.value) < 0 ? 0 : parseInt(e.target.value));
/* 동메달 값 변경 */
const changeBronze = (e) => setBronze(parseInt(e.target.value) < 0 ? 0 : parseInt(e.target.value));
/* 추가 및 업데이트 이벤트 */
const handleSubmit = (e) => {
e.preventDefault();
window.alert('버튼 클릭');
setCountry('');
setGold(0);
setSilver(0);
setBronze(0);
};
/* 삭제 이벤트 */
const handleDelete = () => {
window.alert('버튼 클릭');
};
return (
<Container>
...
<Form onSubmit={(e) => handleSubmit(e)}>
<InputContainer>
<InputTitle>국가명</InputTitle>
<Input type="text" placeholder="국가 입력" value={country} onChange={changeCountry} />
</InputContainer>
<InputContainer>
<InputTitle>금메달</InputTitle>
<Input type="number" value={gold} onChange={changeGold} />
</InputContainer>
<InputContainer>
<InputTitle>은메달</InputTitle>
<Input type="number" value={silver} onChange={changeSilver} />
</InputContainer>
<InputContainer>
<InputTitle>동메달</InputTitle>
<Input type="number" value={bronze} onChange={changeBronze} />
</InputContainer>
<CreateUpdate type="submit" value="국가 추가" />
<CreateUpdate type="submit" value="업데이트" />
</Form>
...
</Container>
);
}
export default App;
'내일배움캠프' 카테고리의 다른 글
[241031 TIL] 본캠프 22일차 ('Medal Tracker 만들기' 프로젝트 3일차) (0) | 2024.10.31 |
---|---|
[241030 TIL] 본캠프 21일차 ('Medal Tracker 만들기' 프로젝트 2일차) (0) | 2024.10.30 |
[241028 TIL] 본캠프 19일차 (1) | 2024.10.28 |
[241025 TIL] 본캠프 18일차 (1) | 2024.10.25 |
[241024 TIL] 본캠프 17일차 ('영화 사이트 만들기' 프로젝트 피드백) (1) | 2024.10.24 |