[TIL] 240519 (React My Todo List 타임어택 / 프로그래머스 대충 만든 자판)

·2024년 5월 19일

TIL

목록 보기
46/268
post-thumbnail

🥞 오늘 한 일

  • 스탠다드반 투두 리스트 타임어택 연습 2회차 (21분)
  • 알고리즘 코드카타
    • 대충 만든 자판

스탠다드반 투두 리스트 타임어택 연습 2회차

디자인을 입히지 않고 오로지 기능만을 구현하는데에 21분이 걸렸다. 지난 번 연습 때 29분이 걸린 걸 생각하면 확실히 시간이 줄었다. 내일 실제 타임어택 때 어디까지 구현해야할지, 어떤 변수가 있을지는 모르겠지만 이 정도면 무난하게 할 수 있을 것 같다.
다음은 구현한 컴포넌트들이다.

// App.jsx

const App = () => {
  return (
    <>
      <TodoContainer />
    </>
  );
};
// TodoContainer.jsx

const TodoContainer = () => {
  const [todos, setTodos] = useState([
    {
      id: crypto.randomUUID(),
      title: "todo 1",
      content: "content 1",
      isDone: false,
    },
    {
      id: crypto.randomUUID(),
      title: "todo 2",
      content: "content 2",
      isDone: true,
    },
  ]);
  const workingTodos = todos.filter((todo) => !todo.isDone);
  const doneTodos = todos.filter((todo) => todo.isDone);
  const deleteTodoHandler = (id) => {
    setTodos(
      todos.filter((todo) => {
        return todo.id !== id;
      })
    );
  };
  const toggleTodoHandler = (id) => {
    setTodos(
      todos.map((todo) => {
        return todo.id !== id ? todo : { ...todo, isDone: !todo.isDone };
      })
    );
  };
  return (
    <div>
      <TodoForm setTodos={setTodos} />
      <TodoList
        isDone={false}
        todos={workingTodos}
        deleteTodoHandler={deleteTodoHandler}
        toggleTodoHandler={toggleTodoHandler}
      />
      <TodoList
        isDone={true}
        todos={doneTodos}
        deleteTodoHandler={deleteTodoHandler}
        toggleTodoHandler={toggleTodoHandler}
      />
    </div>
  );
};
// TodoForm.jsx

const TodoForm = ({ setTodos }) => {
  const [title, setTitle] = useState("");
  const [content, setContent] = useState("");
  const addTodoHandler = (e) => {
    if (!title.trim() || !content.trim()) {
      alert("제목과 내용을 모두 입력해주세요.");
      return;
    }
    e.preventDefault();
    const newTodo = {
      id: crypto.randomUUID(),
      title,
      content,
      isDone: false,
    };
    setTodos((prevTodos) => [...prevTodos, newTodo]);
    setTitle("");
    setContent("");
  };
  return (
    <form onSubmit={addTodoHandler}>
      <input
        placeholder="제목을 입력하세요."
        value={title}
        onChange={(e) => {
          setTitle(e.target.value);
        }}
      />
      <input
        value={content}
        placeholder="내용을 입력하세요."
        onChange={(e) => {
          setContent(e.target.value);
        }}
      />
      <button>추가하기</button>
    </form>
  );
};
// TodoList.jsx

const TodoList = ({ todos, isDone, deleteTodoHandler, toggleTodoHandler }) => {
  return (
    <>
      <p>{isDone ? "Done" : "Working"}</p>
      <ul>
        {todos.map((todo) => {
          return (
            <TodoItem
              isDone={isDone}
              key={todo.id}
              todo={todo}
              deleteTodoHandler={deleteTodoHandler}
              toggleTodoHandler={toggleTodoHandler}
            />
          );
        })}
      </ul>
    </>
  );
};
// TodoItem.jsx

const TodoItem = ({ todo, deleteTodoHandler, toggleTodoHandler, isDone }) => {
  const { id, title, content } = todo;
  return (
    <li>
      <p>{title}</p>
      <p>{content}</p>
      <button
        onClick={() => {
          deleteTodoHandler(id);
        }}
      >
        삭제하기
      </button>
      <button
        onClick={() => {
          toggleTodoHandler(id);
        }}
      >
        {isDone ? "취소" : "완료"}
      </button>
    </li>
  );
};

🍽️ 문제 해결

알고리즘 코드카타

대충 만든 자판

문제

휴대폰의 자판은 컴퓨터 키보드 자판과는 다르게 하나의 키에 여러 개의 문자가 할당될 수 있습니다. 키 하나에 여러 문자가 할당된 경우, 동일한 키를 연속해서 빠르게 누르면 할당된 순서대로 문자가 바뀝니다.

예를 들어, 1번 키에 "A", "B", "C" 순서대로 문자가 할당되어 있다면 1번 키를 한 번 누르면 "A", 두 번 누르면 "B", 세 번 누르면 "C"가 되는 식입니다.

같은 규칙을 적용해 아무렇게나 만든 휴대폰 자판이 있습니다. 이 휴대폰 자판은 키의 개수가 1개부터 최대 100개까지 있을 수 있으며, 특정 키를 눌렀을 때 입력되는 문자들도 무작위로 배열되어 있습니다. 또, 같은 문자가 자판 전체에 여러 번 할당된 경우도 있고, 키 하나에 같은 문자가 여러 번 할당된 경우도 있습니다. 심지어 아예 할당되지 않은 경우도 있습니다. 따라서 몇몇 문자열은 작성할 수 없을 수도 있습니다.

이 휴대폰 자판을 이용해 특정 문자열을 작성할 때, 키를 최소 몇 번 눌러야 그 문자열을 작성할 수 있는지 알아보고자 합니다.

1번 키부터 차례대로 할당된 문자들이 순서대로 담긴 문자열배열 keymap과 입력하려는 문자열들이 담긴 문자열 배열 targets가 주어질 때, 각 문자열을 작성하기 위해 키를 최소 몇 번씩 눌러야 하는지 순서대로 배열에 담아 return 하는 solution 함수를 완성해 주세요.

단, 목표 문자열을 작성할 수 없을 때는 -1을 저장합니다.

내 풀이

function solution(keymap, targets) {
  let result = targets.map((target) => {
    let targetArr = [...target];
    let countSum = 0;
    for (let i = 0; i < targetArr.length; i++) {
      let count = 0;
      for (let j = 0; j < keymap.length; j++) {
        if (keymap[j].includes(target[i])) {
            if (count === 0 || count > keymap[j].indexOf(target[i]) + 1) {
                count = keymap[j].indexOf(target[i]) + 1;
            }
        }
      }
      if (count === 0) {
        return -1;
      } else {
        countSum += count;
      }
    }
    return countSum;
  });
  return result;
}

예상 외로 크게 어렵지 않게 풀 수 있었다. map을 사용해 각 target의 요소마다 반복문을 사용해 keymap 중 더 빠르게 타자를 칠 수 있는 count를 더해주고 해당 숫자를 return 해줌으로써 숫자가 담긴 배열을 제작하고 return하는 방식으로 문제를 풀 수 있었다. 무지성으로 이렇게 하면 되겠지 라고 생각하며 풀어서 테스트 케이스에서 틀리거나 시간 초과의 문제가 생기지는 않을까 걱정했는데 다행히 그런 문제가 없었어서 뿌듯했다.

다른 사람의 풀이

function solution(keymap, targets) {
    const answer = [];
    const map = {}
    for (const items of keymap) {
        items.split('').map((item, index) => map[item] = (map[item] < index+1 ? map[item] : index+1))
    }
    for (const items of targets) {
        answer.push(items.split('').reduce((cur, item) => cur += map[item], 0) || -1)
    }
    return answer;
}

🍳 내일 할 일

  • 리액트 숙련 강의 수강
profile
웹 프론트엔드 개발자

0개의 댓글