feat(prototype): 중1~고3 샘플 ebook 6권 + PS 제거 + 복습캘린더 + 태그 삭제
### 샘플 ebook (대회 시연용 B2B 데모) - /exams 카탈로그: API 호출/필터 제거, EBOOK_LIST 기반 6카드 정적 렌더 - /exams/sample-ebook/[id] 동적 라우트: 중1~고3 수학 6권 × 30문항 + 해설 - 교육과정별 단원 커버 (중1: 정수·일차방정식 ~ 고3: 극한·벡터) ### PS (Solved.ac) 도메인 제거 - backend: PsModule/PsService/PsController/SolvedAcClient 전체 삭제, app.module 정리 - frontend: /ps 라우트, PsTabs, SideNav/BottomNav PS 항목, api.ts PS 타입 전부 제거 - onboarding: ps.sync() 호출 제거 ### 복습큐 → 복습캘린더 - backend: GET /reviews/calendar?year&month, GET /reviews/day?date API 추가 - frontend: 대시보드 "오늘 복습 큐" 카드 → ReviewCalendar 위젯 교체 - 월간 7열 그리드, 날짜 클릭 시 해당일 복습 목록 인라인 패널 - 밀린 날 warning / 완료 날 success / 오늘 하이라이트 - 0건이면 "쉬어가자" 안내 ### 태그 삭제 기능 - subjects/page.tsx: 태그 행 × 아이콘 → ConfirmDialog (danger) → DELETE /tags/:id - 낙관적 업데이트 + 실패 시 롤백 backend tsc + frontend tsc 클린.
This commit is contained in:
@@ -1,20 +1,14 @@
|
||||
'use client';
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
import styled from 'styled-components';
|
||||
import AppShell from '@/components/layout/AppShell';
|
||||
import { Icon } from '@/components/ui/Icon';
|
||||
import Select from '@/components/ui/Select';
|
||||
import { Badge, Button, Card, Label, PageHeader } from '@/components/ui/primitives';
|
||||
import { api, type ProblemSetSummary } from '@/lib/api';
|
||||
import { Badge, Button, Card, PageHeader } from '@/components/ui/primitives';
|
||||
import { theme } from '@/styles/theme';
|
||||
|
||||
const YEAR_FILTERS = [2026, 2025] as const;
|
||||
const SUBJECT_FILTERS = ['전체', '수학'] as const;
|
||||
|
||||
type YearFilter = number | 'all';
|
||||
type SubjectFilter = (typeof SUBJECT_FILTERS)[number];
|
||||
import { EBOOK_LIST } from './sample-ebook/data/index';
|
||||
import type { EbookMeta } from './sample-ebook/data/index';
|
||||
|
||||
export default function ExamsPage() {
|
||||
return (
|
||||
@@ -26,40 +20,6 @@ export default function ExamsPage() {
|
||||
|
||||
function ExamsBody() {
|
||||
const router = useRouter();
|
||||
const [problemSets, setProblemSets] = useState<ProblemSetSummary[] | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [selectedYear, setSelectedYear] = useState<YearFilter>('all');
|
||||
const [selectedSubject, setSelectedSubject] = useState<SubjectFilter>('전체');
|
||||
const [reloadKey, setReloadKey] = useState(0);
|
||||
|
||||
const loadProblemSets = useCallback(() => {
|
||||
let active = true;
|
||||
|
||||
setProblemSets(null);
|
||||
setError(null);
|
||||
|
||||
api
|
||||
.get<ProblemSetSummary[]>('/problem-sets', {
|
||||
params: {
|
||||
year: selectedYear === 'all' ? undefined : selectedYear,
|
||||
subjectName: selectedSubject === '전체' ? undefined : selectedSubject,
|
||||
},
|
||||
})
|
||||
.then((response) => {
|
||||
if (!active) return;
|
||||
setProblemSets(response.data);
|
||||
})
|
||||
.catch(() => {
|
||||
if (!active) return;
|
||||
setError('문제집 목록을 불러오지 못했어. 다시 시도해줘.');
|
||||
});
|
||||
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [selectedSubject, selectedYear]);
|
||||
|
||||
useEffect(() => loadProblemSets(), [loadProblemSets, reloadKey]);
|
||||
|
||||
return (
|
||||
<Wrap>
|
||||
@@ -67,126 +27,61 @@ function ExamsBody() {
|
||||
<PageHeader
|
||||
eyebrow="Exams"
|
||||
title="모의고사 문제집"
|
||||
subtitle="기출 문제집을 선택해 실전처럼 풀어봐"
|
||||
subtitle="학년별 샘플 ebook을 선택해 문제를 풀어봐"
|
||||
/>
|
||||
</HeaderCard>
|
||||
|
||||
<FilterCard>
|
||||
<FilterRow>
|
||||
<FilterField>
|
||||
<Label>연도</Label>
|
||||
<FieldSelect
|
||||
value={selectedYear}
|
||||
onChange={(value) => setSelectedYear(value as YearFilter)}
|
||||
options={[
|
||||
{ label: '전체', value: 'all' as const },
|
||||
...YEAR_FILTERS.map((year) => ({ label: String(year), value: year })),
|
||||
]}
|
||||
aria-label="연도 필터"
|
||||
/>
|
||||
</FilterField>
|
||||
|
||||
<FilterField>
|
||||
<Label>과목</Label>
|
||||
<FieldSelect
|
||||
value={selectedSubject}
|
||||
onChange={(value) => setSelectedSubject(value as SubjectFilter)}
|
||||
options={SUBJECT_FILTERS.map((subject) => ({
|
||||
label: subject,
|
||||
value: subject,
|
||||
}))}
|
||||
aria-label="과목 필터"
|
||||
/>
|
||||
</FilterField>
|
||||
</FilterRow>
|
||||
</FilterCard>
|
||||
|
||||
{error ? (
|
||||
<>
|
||||
<Grid>
|
||||
<SampleEbookCard router={router} />
|
||||
</Grid>
|
||||
<StateCard role="alert">
|
||||
<StateIcon>
|
||||
<Icon name="info" size={24} />
|
||||
</StateIcon>
|
||||
<StateTitle>불러오기에 실패했어</StateTitle>
|
||||
<StateText>{error}</StateText>
|
||||
<Button type="button" $variant="secondary" onClick={() => setReloadKey((prev) => prev + 1)}>
|
||||
다시 시도
|
||||
</Button>
|
||||
</StateCard>
|
||||
</>
|
||||
) : problemSets === null ? (
|
||||
<>
|
||||
<Grid>
|
||||
<SampleEbookCard router={router} />
|
||||
</Grid>
|
||||
<StateCard>
|
||||
<StateIcon>
|
||||
<Icon name="clock" size={24} />
|
||||
</StateIcon>
|
||||
<StateTitle>문제집을 준비하는 중</StateTitle>
|
||||
<StateText>필터에 맞는 평가원 문제집을 불러오고 있어.</StateText>
|
||||
</StateCard>
|
||||
</>
|
||||
) : problemSets.length === 0 ? (
|
||||
<>
|
||||
<Grid>
|
||||
<SampleEbookCard router={router} />
|
||||
</Grid>
|
||||
<StateCard>
|
||||
<StateIcon>
|
||||
<Icon name="book-open-text" size={24} />
|
||||
</StateIcon>
|
||||
<StateTitle>조건에 맞는 문제집이 아직 없어</StateTitle>
|
||||
<StateText>연도나 과목 필터를 바꿔서 다시 찾아봐.</StateText>
|
||||
</StateCard>
|
||||
</>
|
||||
) : (
|
||||
<Grid>
|
||||
<SampleEbookCard router={router} />
|
||||
{problemSets.map((problemSet) => {
|
||||
const isAutoGradeUnavailable =
|
||||
(problemSet.problems?.length ?? 0) > 0 &&
|
||||
problemSet.problems?.every((problem) => problem.needsReview);
|
||||
|
||||
return (
|
||||
<ExamCard key={problemSet.id}>
|
||||
<CardHeader>
|
||||
<CardTitle>{problemSet.title}</CardTitle>
|
||||
{isAutoGradeUnavailable ? (
|
||||
<MutedBadge $variant="default">정답 자동 채점 미지원</MutedBadge>
|
||||
) : null}
|
||||
</CardHeader>
|
||||
|
||||
<CardMeta>
|
||||
{problemSet.year} · {problemSet.subjectName} ·{' '}
|
||||
{(problemSet._count?.problems ?? 0).toLocaleString()}문항
|
||||
</CardMeta>
|
||||
|
||||
<CardFooter>
|
||||
<InfoLine>
|
||||
<Icon name="clock" size={16} />
|
||||
실전 타이머 포함
|
||||
</InfoLine>
|
||||
<Button
|
||||
type="button"
|
||||
$variant="secondary"
|
||||
onClick={() => router.push(`/study/exam/${problemSet.id}`)}
|
||||
>
|
||||
시작
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</ExamCard>
|
||||
);
|
||||
})}
|
||||
</Grid>
|
||||
)}
|
||||
<Grid>
|
||||
{EBOOK_LIST.map((ebook) => (
|
||||
<SampleEbookCard key={ebook.id} ebook={ebook} router={router} />
|
||||
))}
|
||||
</Grid>
|
||||
</Wrap>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── 샘플 ebook 카드 ─────────────────────────────────────────────────────────
|
||||
|
||||
function SampleEbookCard({
|
||||
ebook,
|
||||
router,
|
||||
}: {
|
||||
ebook: EbookMeta;
|
||||
router: ReturnType<typeof useRouter>;
|
||||
}) {
|
||||
return (
|
||||
<SampleCard>
|
||||
<SampleCardHeader>
|
||||
<CardTitle>{ebook.title}</CardTitle>
|
||||
<SampleBadge $variant="default">
|
||||
<Icon name="book-open-text" size={11} />
|
||||
샘플 · 미리보기
|
||||
</SampleBadge>
|
||||
</SampleCardHeader>
|
||||
|
||||
<CardMeta>
|
||||
{ebook.grade} · {ebook.subtitle.split(' ').slice(2).join(' ')} · {ebook.problemCount}문항
|
||||
</CardMeta>
|
||||
|
||||
<CardFooter>
|
||||
<InfoLine>
|
||||
<Icon name="book-open-text" size={16} />
|
||||
종이책처럼 넘겨보기
|
||||
</InfoLine>
|
||||
<Button
|
||||
type="button"
|
||||
$variant="primary"
|
||||
onClick={() => router.push(`/exams/sample-ebook/${ebook.id}`)}
|
||||
>
|
||||
열어보기
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</SampleCard>
|
||||
);
|
||||
}
|
||||
|
||||
// ─── 스타일 ──────────────────────────────────────────────────────────────────
|
||||
|
||||
const Wrap = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -200,33 +95,6 @@ const HeaderCard = styled(Card)`
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
|
||||
const FilterCard = styled(Card)`
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
|
||||
const FilterRow = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 240px));
|
||||
gap: 16px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.tablet}) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
`;
|
||||
|
||||
const FilterField = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
`;
|
||||
|
||||
const FieldSelect = styled(Select)`
|
||||
width: 100%;
|
||||
background: rgba(255, 255, 255, 0.03);
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
|
||||
const Grid = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
@@ -237,131 +105,6 @@ const Grid = styled.div`
|
||||
}
|
||||
`;
|
||||
|
||||
const ExamCard = styled(Card)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
min-height: 220px;
|
||||
justify-content: space-between;
|
||||
background:
|
||||
radial-gradient(circle at top right, rgba(79, 70, 229, 0.12), transparent 30%),
|
||||
rgba(255, 255, 255, 0.02);
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
|
||||
const CardHeader = styled.div`
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const CardTitle = styled.h2`
|
||||
font-size: 20px;
|
||||
line-height: 1.45;
|
||||
color: ${theme.color.textBright};
|
||||
`;
|
||||
|
||||
const MutedBadge = styled(Badge)`
|
||||
color: ${theme.color.textSub};
|
||||
background: rgba(255, 255, 255, 0.06);
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
|
||||
const CardMeta = styled.p`
|
||||
color: ${theme.color.textSub};
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
`;
|
||||
|
||||
const CardFooter = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: auto;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
`;
|
||||
|
||||
const InfoLine = styled.span`
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: ${theme.color.textSub};
|
||||
font-size: 13px;
|
||||
`;
|
||||
|
||||
const StateCard = styled(Card)`
|
||||
min-height: 260px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 12px;
|
||||
text-align: center;
|
||||
background: rgba(255, 255, 255, 0.02);
|
||||
border-color: ${theme.color.borderSoftAlpha};
|
||||
`;
|
||||
|
||||
const StateIcon = styled.div`
|
||||
width: 52px;
|
||||
height: 52px;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
border-radius: 16px;
|
||||
background: rgba(79, 70, 229, 0.12);
|
||||
color: ${theme.color.textBright};
|
||||
`;
|
||||
|
||||
const StateTitle = styled.h2`
|
||||
font-size: 20px;
|
||||
color: ${theme.color.textBright};
|
||||
`;
|
||||
|
||||
const StateText = styled.p`
|
||||
color: ${theme.color.textSub};
|
||||
`;
|
||||
|
||||
// ─── 샘플 ebook 카드 ─────────────────────────────────────────────────────────
|
||||
|
||||
function SampleEbookCard({ router }: { router: ReturnType<typeof useRouter> }) {
|
||||
return (
|
||||
<SampleCard>
|
||||
<SampleCardHeader>
|
||||
<CardTitle>[샘플] 수능 수학 미리보기 ebook</CardTitle>
|
||||
<SampleBadge $variant="default">
|
||||
<Icon name="book-open-text" size={11} />
|
||||
샘플 · 미리보기
|
||||
</SampleBadge>
|
||||
</SampleCardHeader>
|
||||
|
||||
<CardMeta>2026 · 수학 · 5문항</CardMeta>
|
||||
|
||||
<CardFooter>
|
||||
<InfoLine>
|
||||
<Icon name="book-open-text" size={16} />
|
||||
종이책처럼 넘겨보기
|
||||
</InfoLine>
|
||||
<Button
|
||||
type="button"
|
||||
$variant="primary"
|
||||
onClick={() => router.push('/exams/sample-ebook')}
|
||||
>
|
||||
열어보기
|
||||
</Button>
|
||||
</CardFooter>
|
||||
</SampleCard>
|
||||
);
|
||||
}
|
||||
|
||||
const SampleCard = styled(Card)`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -389,14 +132,54 @@ const SampleCard = styled(Card)`
|
||||
}
|
||||
`;
|
||||
|
||||
const SampleCardHeader = styled(CardHeader)`
|
||||
const SampleCardHeader = styled.div`
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
flex-direction: column;
|
||||
}
|
||||
`;
|
||||
|
||||
const SampleBadge = styled(MutedBadge)`
|
||||
const CardTitle = styled.h2`
|
||||
font-size: 20px;
|
||||
line-height: 1.45;
|
||||
color: ${theme.color.textBright};
|
||||
`;
|
||||
|
||||
const SampleBadge = styled(Badge)`
|
||||
background: rgba(124, 58, 237, 0.18);
|
||||
border-color: rgba(124, 58, 237, 0.4);
|
||||
color: ${theme.color.accent2};
|
||||
white-space: nowrap;
|
||||
flex-shrink: 0;
|
||||
`;
|
||||
|
||||
const CardMeta = styled.p`
|
||||
color: ${theme.color.textSub};
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
`;
|
||||
|
||||
const CardFooter = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 12px;
|
||||
margin-top: auto;
|
||||
|
||||
@media (max-width: ${theme.breakpoint.mobile}) {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
`;
|
||||
|
||||
const InfoLine = styled.span`
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: ${theme.color.textSub};
|
||||
font-size: 13px;
|
||||
`;
|
||||
|
||||
@@ -1,89 +1,53 @@
|
||||
'use client';
|
||||
|
||||
import React, { useCallback, useEffect, useState } from 'react';
|
||||
import { useParams } from 'next/navigation';
|
||||
import Link from 'next/link';
|
||||
import { notFound } from 'next/navigation';
|
||||
import styled, { css, keyframes } from 'styled-components';
|
||||
import AppShell from '@/components/layout/AppShell';
|
||||
import { Icon } from '@/components/ui/Icon';
|
||||
import { Badge, Button, Card } from '@/components/ui/primitives';
|
||||
import { theme } from '@/styles/theme';
|
||||
|
||||
// ─── 샘플 문제 데이터 ──────────────────────────────────────────────────────────
|
||||
|
||||
interface Problem {
|
||||
number: number;
|
||||
question: string;
|
||||
choices: string[];
|
||||
answer: number; // 1-based
|
||||
explanation: string;
|
||||
}
|
||||
|
||||
const SAMPLE_PROBLEMS: Problem[] = [
|
||||
{
|
||||
number: 1,
|
||||
question:
|
||||
'함수 f(x) = x² − 4x + 3 의 최솟값을 구하시오.',
|
||||
choices: ['−3', '−2', '−1', '0', '1'],
|
||||
answer: 3,
|
||||
explanation:
|
||||
'꼭짓점 공식: f(x) = (x − 2)² − 1. 꼭짓점 x = 2 에서 최솟값 f(2) = 4 − 8 + 3 = −1.',
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
question:
|
||||
'등차수열 {aₙ} 에서 a₁ = 3, 공차 d = 4 일 때, a₁₀ 의 값은?',
|
||||
choices: ['35', '38', '39', '40', '43'],
|
||||
answer: 3,
|
||||
explanation:
|
||||
'aₙ = a₁ + (n − 1)d. a₁₀ = 3 + 9 × 4 = 3 + 36 = 39.',
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
question:
|
||||
'lim(x→2) (x² − 4) / (x − 2) 의 값은?',
|
||||
choices: ['0', '2', '4', '6', '수렴하지 않음'],
|
||||
answer: 3,
|
||||
explanation:
|
||||
'분자를 인수분해: (x² − 4) = (x − 2)(x + 2). 약분하면 lim(x→2) (x + 2) = 4.',
|
||||
},
|
||||
{
|
||||
number: 4,
|
||||
question:
|
||||
'주머니 속에 빨간 공 3개, 파란 공 2개가 있다. 한 개를 꺼낼 때 빨간 공일 확률은?',
|
||||
choices: ['1/5', '2/5', '3/5', '4/5', '1'],
|
||||
answer: 3,
|
||||
explanation:
|
||||
'전체 5개 중 빨간 공 3개. 확률 = 3/5.',
|
||||
},
|
||||
{
|
||||
number: 5,
|
||||
question:
|
||||
'∫₀² (2x + 1) dx 의 값은?',
|
||||
choices: ['4', '5', '6', '7', '8'],
|
||||
answer: 3,
|
||||
explanation:
|
||||
'∫(2x + 1) dx = x² + x + C. [x² + x]₀² = (4 + 2) − 0 = 6.',
|
||||
},
|
||||
];
|
||||
import { EBOOK_MAP } from '../data/index';
|
||||
import type { SampleProblem } from '../data/types';
|
||||
|
||||
// ─── 페이지 컴포넌트 ────────────────────────────────────────────────────────────
|
||||
|
||||
export default function SampleEbookPage() {
|
||||
export default function SampleEbookDynamicPage() {
|
||||
const params = useParams();
|
||||
const id = typeof params.id === 'string' ? params.id : '';
|
||||
const ebook = EBOOK_MAP[id];
|
||||
|
||||
if (!ebook) {
|
||||
notFound();
|
||||
}
|
||||
|
||||
return (
|
||||
<AppShell>
|
||||
<EbookViewer />
|
||||
<EbookViewer
|
||||
title={ebook.title}
|
||||
problems={ebook.problems}
|
||||
/>
|
||||
</AppShell>
|
||||
);
|
||||
}
|
||||
|
||||
function EbookViewer() {
|
||||
// ─── 뷰어 ─────────────────────────────────────────────────────────────────────
|
||||
|
||||
interface EbookViewerProps {
|
||||
title: string;
|
||||
problems: SampleProblem[];
|
||||
}
|
||||
|
||||
function EbookViewer({ title, problems }: EbookViewerProps) {
|
||||
const [pageIndex, setPageIndex] = useState(0);
|
||||
const [selectedAnswers, setSelectedAnswers] = useState<Record<number, number>>({});
|
||||
const [revealed, setRevealed] = useState<Record<number, boolean>>({});
|
||||
const [fading, setFading] = useState(false);
|
||||
|
||||
const total = SAMPLE_PROBLEMS.length;
|
||||
const problem = SAMPLE_PROBLEMS[pageIndex];
|
||||
const total = problems.length;
|
||||
const problem = problems[pageIndex];
|
||||
|
||||
const goTo = useCallback(
|
||||
(index: number) => {
|
||||
@@ -109,7 +73,6 @@ function EbookViewer() {
|
||||
|
||||
const selectAnswer = (choiceIndex: number) => {
|
||||
setSelectedAnswers((prev) => ({ ...prev, [problem.number]: choiceIndex }));
|
||||
// 답 바꾸면 해설 숨김
|
||||
setRevealed((prev) => ({ ...prev, [problem.number]: false }));
|
||||
};
|
||||
|
||||
@@ -117,7 +80,7 @@ function EbookViewer() {
|
||||
setRevealed((prev) => ({ ...prev, [problem.number]: true }));
|
||||
};
|
||||
|
||||
const chosen = selectedAnswers[problem.number]; // undefined | number (1-based)
|
||||
const chosen = selectedAnswers[problem.number];
|
||||
const isRevealed = revealed[problem.number] ?? false;
|
||||
const isCorrect = chosen !== undefined && chosen === problem.answer;
|
||||
|
||||
@@ -137,7 +100,7 @@ function EbookViewer() {
|
||||
</HeaderRight>
|
||||
</ViewerHeader>
|
||||
|
||||
<ViewerTitle>[샘플] 수능 수학 미리보기 ebook</ViewerTitle>
|
||||
<ViewerTitle>{title}</ViewerTitle>
|
||||
<ViewerDivider />
|
||||
|
||||
{/* 책 펼침 영역 */}
|
||||
@@ -156,7 +119,7 @@ function EbookViewer() {
|
||||
<PageLabel>선택지</PageLabel>
|
||||
<ChoiceList>
|
||||
{problem.choices.map((choice, idx) => {
|
||||
const choiceNum = idx + 1; // 1-based
|
||||
const choiceNum = idx + 1;
|
||||
const isSelected = chosen === choiceNum;
|
||||
const isAnswerChoice = problem.answer === choiceNum;
|
||||
|
||||
@@ -346,7 +309,6 @@ const ViewerDivider = styled.hr`
|
||||
margin: 0;
|
||||
`;
|
||||
|
||||
// 책 펼침 레이아웃
|
||||
const BookSpread = styled.div<{ $fading: boolean }>`
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 2px 1fr;
|
||||
@@ -373,7 +335,6 @@ const BookPage = styled(Card)<{ $side: 'left' | 'right' }>`
|
||||
padding: ${theme.space.xl};
|
||||
min-height: 380px;
|
||||
|
||||
/* cream tint */
|
||||
background: linear-gradient(
|
||||
160deg,
|
||||
rgba(20, 18, 40, 0.98) 0%,
|
||||
@@ -434,7 +395,6 @@ const QuestionText = styled.p`
|
||||
flex: 1;
|
||||
`;
|
||||
|
||||
// 선택지
|
||||
const ChoiceList = styled.div`
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -527,7 +487,6 @@ const CorrectMark = styled.span`
|
||||
animation: ${fadeIn} 0.2s ease;
|
||||
`;
|
||||
|
||||
// 답 선택 상태
|
||||
const AnswerStatusRow = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -541,7 +500,6 @@ const AnswerChosen = styled.span<{ $muted?: boolean }>`
|
||||
color: ${({ $muted }) => ($muted ? theme.color.textMute : theme.color.textSub)};
|
||||
`;
|
||||
|
||||
// 해설 박스
|
||||
const ExplanationBox = styled.div<{ $correct: boolean }>`
|
||||
padding: ${theme.space.md};
|
||||
border-radius: ${theme.radius.md};
|
||||
@@ -568,7 +526,6 @@ const ExplanationText = styled.p`
|
||||
color: ${theme.color.textSub};
|
||||
`;
|
||||
|
||||
// 페이지 네비게이션
|
||||
const PageNav = styled.div`
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -588,7 +545,6 @@ const PageIndicator = styled.span`
|
||||
text-align: center;
|
||||
`;
|
||||
|
||||
// B2B 안내 박스
|
||||
const InfoBox = styled(Card)`
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
265
frontend/src/app/exams/sample-ebook/data/high-1.ts
Normal file
265
frontend/src/app/exams/sample-ebook/data/high-1.ts
Normal file
@@ -0,0 +1,265 @@
|
||||
import type { SampleProblem } from './types';
|
||||
|
||||
export const PROBLEMS: SampleProblem[] = [
|
||||
// ── 다항식 (1~6) ──────────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 1,
|
||||
question: '(x + 2)³ 를 전개하면?',
|
||||
choices: [
|
||||
'x³ + 6x² + 12x + 8',
|
||||
'x³ + 3x² + 3x + 8',
|
||||
'x³ + 8',
|
||||
'x³ + 6x + 8',
|
||||
'x³ + 2x² + 4x + 8',
|
||||
],
|
||||
answer: 1,
|
||||
explanation: '(a+b)³ = a³ + 3a²b + 3ab² + b³. a=x, b=2 대입: x³ + 3·x²·2 + 3·x·4 + 8 = x³ + 6x² + 12x + 8.',
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
question: '다항식 f(x) = 2x³ − 3x² + x − 5 를 (x − 2) 로 나눌 때 나머지는?',
|
||||
choices: ['−3', '−1', '1', '3', '5'],
|
||||
answer: 3,
|
||||
explanation: '나머지 정리: f(2) = 2·8 − 3·4 + 2 − 5 = 16 − 12 + 2 − 5 = 1.',
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
question: '(a + b)(a − b) 를 전개하면?',
|
||||
choices: ['a² + b²', 'a² − b²', 'a² + 2ab + b²', 'a² − 2ab + b²', '2a² − 2b²'],
|
||||
answer: 2,
|
||||
explanation: '합차 공식: (a+b)(a−b) = a² − b².',
|
||||
},
|
||||
{
|
||||
number: 4,
|
||||
question: 'x³ − 8 을 인수분해하면?',
|
||||
choices: [
|
||||
'(x−2)(x²+2x+4)',
|
||||
'(x−2)(x²−2x+4)',
|
||||
'(x+2)(x²−2x+4)',
|
||||
'(x−2)³',
|
||||
'(x−2)(x+2)²',
|
||||
],
|
||||
answer: 1,
|
||||
explanation: 'a³ − b³ = (a−b)(a²+ab+b²). x³−8 = x³−2³ = (x−2)(x²+2x+4).',
|
||||
},
|
||||
{
|
||||
number: 5,
|
||||
question: '다항식 x³ − 3x² + 3x − 1 을 인수분해하면?',
|
||||
choices: ['(x−1)³', '(x+1)³', '(x−1)(x²+x+1)', '(x+1)(x²−x+1)', '(x−1)²(x+1)'],
|
||||
answer: 1,
|
||||
explanation: '(a−b)³ = a³ − 3a²b + 3ab² − b³. a=x, b=1 대입하면 (x−1)³.',
|
||||
},
|
||||
{
|
||||
number: 6,
|
||||
question: 'f(x) = x³ − x + 2 를 (x + 1) 로 나눌 때 나머지는?',
|
||||
choices: [
|
||||
'0',
|
||||
'1',
|
||||
'2',
|
||||
'−1',
|
||||
'4',
|
||||
],
|
||||
answer: 3,
|
||||
explanation: '나머지 정리: f(−1) = (−1)³ − (−1) + 2 = −1 + 1 + 2 = 2. 나머지 = 2.',
|
||||
},
|
||||
|
||||
// ── 방정식과 부등식 (7~12) ───────────────────────────────────────────────────
|
||||
{
|
||||
number: 7,
|
||||
question: '이차부등식 x² − 3x + 2 ≤ 0 의 해는?',
|
||||
choices: ['x ≤ 1 또는 x ≥ 2', '1 ≤ x ≤ 2', 'x ≤ −1 또는 x ≥ −2', '−2 ≤ x ≤ −1', 'x < 0'],
|
||||
answer: 2,
|
||||
explanation: '(x−1)(x−2) ≤ 0. 두 근 사이에서 성립: 1 ≤ x ≤ 2.',
|
||||
},
|
||||
{
|
||||
number: 8,
|
||||
question: '연립부등식 { 2x + 1 > 5, x − 3 < 4 } 의 해는?',
|
||||
choices: ['2 < x < 7', 'x > 2', 'x < 7', 'x ≥ 2', '2 ≤ x ≤ 7'],
|
||||
answer: 1,
|
||||
explanation: '첫 부등식: 2x > 4 → x > 2. 둘째: x < 7. 교집합: 2 < x < 7.',
|
||||
},
|
||||
{
|
||||
number: 9,
|
||||
question: '이차방정식 x² − 5x + k = 0 이 중근을 가지려면 k의 값은?',
|
||||
choices: ['5/4', '25/4', '5', '25', '−25/4'],
|
||||
answer: 2,
|
||||
explanation: '중근 조건: 판별식 D = 0. D = 25 − 4k = 0 → k = 25/4.',
|
||||
},
|
||||
{
|
||||
number: 10,
|
||||
question: '방정식 x² + 2x + 5 = 0 의 두 근의 곱은?',
|
||||
choices: ['−5', '−2', '2', '5', '10'],
|
||||
answer: 4,
|
||||
explanation: '비에타 공식: 두 근의 곱 = c/a = 5/1 = 5.',
|
||||
},
|
||||
{
|
||||
number: 11,
|
||||
question: '부등식 |2x − 3| < 5 의 해는?',
|
||||
choices: ['−1 < x < 4', 'x > −1', 'x < 4', '−2 < x < 4', '1 < x < 4'],
|
||||
answer: 1,
|
||||
explanation: '−5 < 2x − 3 < 5 → −2 < 2x < 8 → −1 < x < 4.',
|
||||
},
|
||||
{
|
||||
number: 12,
|
||||
question: '이차부등식 x² − x − 6 > 0 의 해는?',
|
||||
choices: ['−2 < x < 3', 'x < −2 또는 x > 3', 'x > 3', 'x < −2', '−3 < x < 2'],
|
||||
answer: 2,
|
||||
explanation: '(x−3)(x+2) > 0. 두 근 바깥쪽: x < −2 또는 x > 3.',
|
||||
},
|
||||
|
||||
// ── 집합과 명제 (13~18) ──────────────────────────────────────────────────────
|
||||
{
|
||||
number: 13,
|
||||
question: 'A = {1, 2, 3, 4}, B = {3, 4, 5} 일 때 A ∪ B 의 원소 개수는?',
|
||||
choices: ['2', '4', '5', '7', '8'],
|
||||
answer: 3,
|
||||
explanation: 'A ∪ B = {1, 2, 3, 4, 5}. 원소 개수 = 5.',
|
||||
},
|
||||
{
|
||||
number: 14,
|
||||
question: 'A = {1, 2, 3, 4}, B = {3, 4, 5} 일 때 A ∩ B 의 원소 개수는?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 2,
|
||||
explanation: 'A ∩ B = {3, 4}. 원소 개수 = 2.',
|
||||
},
|
||||
{
|
||||
number: 15,
|
||||
question: '"p이면 q이다"의 대우는?',
|
||||
choices: ['p이면 ¬q이다', '¬p이면 q이다', '¬q이면 ¬p이다', 'q이면 p이다', '¬p이면 ¬q이다'],
|
||||
answer: 3,
|
||||
explanation: '명제 p→q의 대우는 ¬q→¬p. 대우는 원명제와 동치.',
|
||||
},
|
||||
{
|
||||
number: 16,
|
||||
question: '명제 "소수이면 홀수이다"의 반례는?',
|
||||
choices: ['3', '5', '7', '2', '11'],
|
||||
answer: 4,
|
||||
explanation: '2는 소수이지만 짝수. 따라서 반례 = 2.',
|
||||
},
|
||||
{
|
||||
number: 17,
|
||||
question: '전체집합 U = {1,2,3,4,5}, A = {1,3,5}일 때 Aᶜ(A의 여집합)는?',
|
||||
choices: ['{1,3,5}', '{2,4}', '{1,2,3,4,5}', '∅', '{2,3,4}'],
|
||||
answer: 2,
|
||||
explanation: 'Aᶜ = U − A = {1,2,3,4,5} − {1,3,5} = {2,4}.',
|
||||
},
|
||||
{
|
||||
number: 18,
|
||||
question: '다음 중 동치인 것끼리 묶은 것은?',
|
||||
choices: [
|
||||
'원명제와 역',
|
||||
'역과 이',
|
||||
'이와 대우',
|
||||
'원명제와 대우',
|
||||
'역과 대우',
|
||||
],
|
||||
answer: 4,
|
||||
explanation: '원명제와 대우는 항상 진릿값이 같다(동치). 역과 이도 서로 동치.',
|
||||
},
|
||||
|
||||
// ── 함수 (19~24) ─────────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 19,
|
||||
question: 'f(x) = 2x + 3 일 때 f(−1) 의 값은?',
|
||||
choices: ['−1', '0', '1', '2', '5'],
|
||||
answer: 3,
|
||||
explanation: 'f(−1) = 2 × (−1) + 3 = −2 + 3 = 1.',
|
||||
},
|
||||
{
|
||||
number: 20,
|
||||
question: '함수 f: A → B 가 일대일대응(전단사)이 되려면?',
|
||||
choices: [
|
||||
'단사이기만 하면 된다',
|
||||
'전사이기만 하면 된다',
|
||||
'단사이고 전사이어야 한다',
|
||||
'f(a) = f(b)이면 a = b',
|
||||
'공역과 치역이 달라야 한다',
|
||||
],
|
||||
answer: 3,
|
||||
explanation: '전단사 = 단사(일대일) AND 전사(onto). 두 조건을 동시에 만족해야 한다.',
|
||||
},
|
||||
{
|
||||
number: 21,
|
||||
question: 'f(x) = x², g(x) = 2x + 1 일 때 (g∘f)(3) 의 값은?',
|
||||
choices: ['13', '17', '18', '19', '22'],
|
||||
answer: 4,
|
||||
explanation: '(g∘f)(3) = g(f(3)) = g(9) = 2·9 + 1 = 19.',
|
||||
},
|
||||
{
|
||||
number: 22,
|
||||
question: 'f(x) = 3x − 2 의 역함수 f⁻¹(x) 는?',
|
||||
choices: [
|
||||
'(x + 2) / 3',
|
||||
'(x − 2) / 3',
|
||||
'3x + 2',
|
||||
'(2 − x) / 3',
|
||||
'3 / (x − 2)',
|
||||
],
|
||||
answer: 1,
|
||||
explanation: 'y = 3x − 2 → 3x = y + 2 → x = (y+2)/3. x와 y를 바꾸면 f⁻¹(x) = (x+2)/3.',
|
||||
},
|
||||
{
|
||||
number: 23,
|
||||
question: '유리함수 y = 1/x 의 그래프의 점근선은?',
|
||||
choices: [
|
||||
'x = 1, y = 1',
|
||||
'x = 0, y = 1',
|
||||
'x = 0, y = 0 (x축·y축)',
|
||||
'x = 1, y = 0',
|
||||
'점근선 없음',
|
||||
],
|
||||
answer: 3,
|
||||
explanation: 'y = 1/x는 x→0에서 y→±∞, y→0에서 x→±∞. 점근선은 x축(y=0)과 y축(x=0).',
|
||||
},
|
||||
{
|
||||
number: 24,
|
||||
question: '무리함수 y = √(x − 1) 의 정의역은?',
|
||||
choices: ['x ≥ 0', 'x > 0', 'x ≥ 1', 'x > 1', '모든 실수'],
|
||||
answer: 3,
|
||||
explanation: '루트 안이 0 이상이어야 한다. x − 1 ≥ 0 → x ≥ 1.',
|
||||
},
|
||||
|
||||
// ── 경우의 수 (25~30) ─────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 25,
|
||||
question: '5명 중 2명을 선택해 순서 있게 배열하는 경우의 수는?',
|
||||
choices: ['10', '15', '20', '25', '30'],
|
||||
answer: 3,
|
||||
explanation: '순열: P(5,2) = 5 × 4 = 20.',
|
||||
},
|
||||
{
|
||||
number: 26,
|
||||
question: '5명 중 2명을 선택하는(순서 무관) 경우의 수는?',
|
||||
choices: ['5', '8', '10', '15', '20'],
|
||||
answer: 3,
|
||||
explanation: '조합: C(5,2) = 5!/(2!3!) = (5×4)/(2×1) = 10.',
|
||||
},
|
||||
{
|
||||
number: 27,
|
||||
question: '서로 다른 6권의 책을 일렬로 나열하는 경우의 수는?',
|
||||
choices: ['120', '360', '480', '720', '1440'],
|
||||
answer: 4,
|
||||
explanation: '6! = 6 × 5 × 4 × 3 × 2 × 1 = 720.',
|
||||
},
|
||||
{
|
||||
number: 28,
|
||||
question: '4개의 자리에 A, B, C, D를 배열할 때 A가 맨 앞에 오는 경우의 수는?',
|
||||
choices: ['4', '6', '8', '12', '24'],
|
||||
answer: 2,
|
||||
explanation: 'A가 고정되면 나머지 B, C, D를 3자리에 배열: 3! = 6.',
|
||||
},
|
||||
{
|
||||
number: 29,
|
||||
question: '동전 3개를 던질 때 나올 수 있는 전체 경우의 수는?',
|
||||
choices: ['3', '4', '6', '8', '12'],
|
||||
answer: 4,
|
||||
explanation: '각 동전이 2가지(앞/뒤). 2³ = 8.',
|
||||
},
|
||||
{
|
||||
number: 30,
|
||||
question: 'C(10, 3) 의 값은?',
|
||||
choices: ['60', '90', '120', '180', '720'],
|
||||
answer: 3,
|
||||
explanation: 'C(10,3) = 10!/(3!·7!) = (10×9×8)/(3×2×1) = 720/6 = 120.',
|
||||
},
|
||||
];
|
||||
223
frontend/src/app/exams/sample-ebook/data/high-2.ts
Normal file
223
frontend/src/app/exams/sample-ebook/data/high-2.ts
Normal file
@@ -0,0 +1,223 @@
|
||||
import type { SampleProblem } from './types';
|
||||
|
||||
export const PROBLEMS: SampleProblem[] = [
|
||||
// ── 지수/로그 (1~6) ───────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 1,
|
||||
question: '2³ × 2⁴ 의 값은?',
|
||||
choices: ['2⁷', '2¹²', '4⁷', '8⁷', '2⁻¹'],
|
||||
answer: 1,
|
||||
explanation: '지수 법칙: aᵐ × aⁿ = aᵐ⁺ⁿ. 2³ × 2⁴ = 2⁷ = 128.',
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
question: 'log₂ 8 의 값은?',
|
||||
choices: ['1', '2', '3', '4', '8'],
|
||||
answer: 3,
|
||||
explanation: 'log₂ 8 = log₂ 2³ = 3.',
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
question: 'log₁₀ 100 + log₁₀ 10 의 값은?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 3,
|
||||
explanation: 'log₁₀ 100 = 2, log₁₀ 10 = 1. 합 = 3. (로그의 덧셈 = log(곱): log(1000) = 3)',
|
||||
},
|
||||
{
|
||||
number: 4,
|
||||
question: 'log 2 ≈ 0.3010 일 때 log 8 의 값은?',
|
||||
choices: ['0.6020', '0.7525', '0.9030', '1.2040', '1.5050'],
|
||||
answer: 3,
|
||||
explanation: 'log 8 = log 2³ = 3 log 2 = 3 × 0.3010 = 0.9030.',
|
||||
},
|
||||
{
|
||||
number: 5,
|
||||
question: '지수함수 y = 2ˣ 에서 x = −2일 때 y의 값은?',
|
||||
choices: ['−4', '−1/4', '1/4', '4', '8'],
|
||||
answer: 3,
|
||||
explanation: 'y = 2⁻² = 1/2² = 1/4.',
|
||||
},
|
||||
{
|
||||
number: 6,
|
||||
question: '자연로그 ln e 의 값은? (e는 자연상수)',
|
||||
choices: ['0', '1', 'e', '1/e', '2'],
|
||||
answer: 2,
|
||||
explanation: 'lnₑ e = log_e e = 1. 로그의 정의에 의해 eˣ = e이면 x = 1.',
|
||||
},
|
||||
|
||||
// ── 삼각함수 (7~12) ──────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 7,
|
||||
question: 'sin²θ + cos²θ 의 값은?',
|
||||
choices: ['0', '1/2', '1', '2', 'θ'],
|
||||
answer: 3,
|
||||
explanation: '피타고라스 항등식: sin²θ + cos²θ = 1 (항상 성립).',
|
||||
},
|
||||
{
|
||||
number: 8,
|
||||
question: 'sin 90° 의 값은?',
|
||||
choices: ['−1', '0', '1/2', '√2/2', '1'],
|
||||
answer: 5,
|
||||
explanation: '단위원 정의: 90°일 때 y 좌표 = 1. sin 90° = 1.',
|
||||
},
|
||||
{
|
||||
number: 9,
|
||||
question: 'cos(−θ) = ? (코사인의 대칭성)',
|
||||
choices: ['−cos θ', 'cos θ', 'sin θ', '−sin θ', '1/cos θ'],
|
||||
answer: 2,
|
||||
explanation: '코사인은 우함수: cos(−θ) = cos θ.',
|
||||
},
|
||||
{
|
||||
number: 10,
|
||||
question: '각도 π/6 (라디안)을 도(°)로 변환하면?',
|
||||
choices: ['15°', '30°', '45°', '60°', '90°'],
|
||||
answer: 2,
|
||||
explanation: 'π 라디안 = 180°. π/6 × (180/π) = 30°.',
|
||||
},
|
||||
{
|
||||
number: 11,
|
||||
question: 'y = sin x 의 주기는?',
|
||||
choices: ['π/2', 'π', '2π', '4π', '1'],
|
||||
answer: 3,
|
||||
explanation: 'sin 함수의 주기 = 2π. y = sin(bx)의 주기는 2π/b.',
|
||||
},
|
||||
{
|
||||
number: 12,
|
||||
question: 'tan θ = sin θ / cos θ 에서 sin θ = 3/5, cos θ = 4/5일 때 tan θ는?',
|
||||
choices: ['3/4', '4/3', '3/5', '5/3', '5/4'],
|
||||
answer: 1,
|
||||
explanation: 'tan θ = (3/5) ÷ (4/5) = (3/5) × (5/4) = 3/4.',
|
||||
},
|
||||
|
||||
// ── 수열 (13~18) ─────────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 13,
|
||||
question: '등차수열 2, 5, 8, 11, … 의 공차는?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 3,
|
||||
explanation: '연속하는 항의 차: 5 − 2 = 3. 공차 d = 3.',
|
||||
},
|
||||
{
|
||||
number: 14,
|
||||
question: '등차수열의 첫째 항이 1, 공차가 3일 때 제10항은?',
|
||||
choices: ['25', '27', '28', '29', '31'],
|
||||
answer: 3,
|
||||
explanation: 'aₙ = a₁ + (n−1)d. a₁₀ = 1 + 9 × 3 = 1 + 27 = 28.',
|
||||
},
|
||||
{
|
||||
number: 15,
|
||||
question: '등비수열 3, 6, 12, 24, … 의 공비는?',
|
||||
choices: ['1', '2', '3', '4', '6'],
|
||||
answer: 2,
|
||||
explanation: '연속하는 항의 비: 6/3 = 2. 공비 r = 2.',
|
||||
},
|
||||
{
|
||||
number: 16,
|
||||
question: '등비수열 첫째 항 2, 공비 3일 때 제4항은?',
|
||||
choices: ['18', '27', '54', '81', '162'],
|
||||
answer: 3,
|
||||
explanation: 'aₙ = a₁ × r^(n−1). a₄ = 2 × 3³ = 2 × 27 = 54.',
|
||||
},
|
||||
{
|
||||
number: 17,
|
||||
question: 'Σ(k=1 to 5) k 의 값은?',
|
||||
choices: ['10', '12', '15', '18', '20'],
|
||||
answer: 3,
|
||||
explanation: '1 + 2 + 3 + 4 + 5 = 15. 공식: n(n+1)/2 = 5×6/2 = 15.',
|
||||
},
|
||||
{
|
||||
number: 18,
|
||||
question: '수열 {aₙ}에서 S₅ = 20, S₄ = 14이면 a₅는?',
|
||||
choices: ['4', '5', '6', '7', '8'],
|
||||
answer: 3,
|
||||
explanation: 'aₙ = Sₙ − S(n−1). a₅ = S₅ − S₄ = 20 − 14 = 6.',
|
||||
},
|
||||
|
||||
// ── 미분 (도함수) (19~24) ────────────────────────────────────────────────────
|
||||
{
|
||||
number: 19,
|
||||
question: 'f(x) = x³ 를 미분하면?',
|
||||
choices: ['x²', '2x²', '3x²', '3x³', '4x³'],
|
||||
answer: 3,
|
||||
explanation: '멱함수 미분: (x^n)의 도함수 = n*x^(n-1). (x³)의 도함수 = 3x².',
|
||||
},
|
||||
{
|
||||
number: 20,
|
||||
question: 'f(x) = 2x² − 3x + 1 의 도함수 f´(x) 는?',
|
||||
choices: ['2x − 3', '4x − 3', '4x + 3', '2x + 3', 'x² − 3'],
|
||||
answer: 2,
|
||||
explanation: '각 항을 미분: (2x²)의 도함수 = 4x, (−3x)의 도함수 = −3, (1)의 도함수 = 0. f´(x) = 4x − 3.',
|
||||
},
|
||||
{
|
||||
number: 21,
|
||||
question: 'f(x) = x³ − 3x 에서 x=1에서의 미분계수 값은?',
|
||||
choices: ['−3', '−2', '0', '2', '3'],
|
||||
answer: 3,
|
||||
explanation: 'f´(x) = 3x² − 3. f´(1) = 3 × 1 − 3 = 0.',
|
||||
},
|
||||
{
|
||||
number: 22,
|
||||
question: 'y = 5 (상수)의 도함수는?',
|
||||
choices: ['5x', '5', '1', '0', '−5'],
|
||||
answer: 4,
|
||||
explanation: '상수의 도함수는 0. 상수 c를 미분하면 항상 0.',
|
||||
},
|
||||
{
|
||||
number: 23,
|
||||
question: 'f(x) = x³ − 3x² + 2 가 극소가 되는 x의 값은?',
|
||||
choices: ['−2', '−1', '0', '2', '3'],
|
||||
answer: 4,
|
||||
explanation: 'f´(x) = 3x² − 6x = 3x(x−2) = 0 → x = 0 또는 x = 2. x = 0은 극대, x = 2는 극소.',
|
||||
},
|
||||
{
|
||||
number: 24,
|
||||
question: '함수 f(x) = x² − 4x + 3 의 x = 1에서의 접선의 기울기는?',
|
||||
choices: ['−4', '−3', '−2', '0', '2'],
|
||||
answer: 3,
|
||||
explanation: 'f´(x) = 2x − 4. x = 1: f´(1) = 2 − 4 = −2.',
|
||||
},
|
||||
|
||||
// ── 적분 (부정/정적분) (25~30) ───────────────────────────────────────────────
|
||||
{
|
||||
number: 25,
|
||||
question: '∫ 3x² dx 의 값은?',
|
||||
choices: ['x² + C', 'x³ + C', '6x + C', '3x³ + C', 'x³/3 + C'],
|
||||
answer: 2,
|
||||
explanation: '∫ x^n dx = x^(n+1)/(n+1) + C. ∫ 3x² dx = 3 × x³/3 + C = x³ + C.',
|
||||
},
|
||||
{
|
||||
number: 26,
|
||||
question: '∫₀² 2x dx 의 값은?',
|
||||
choices: ['1', '2', '3', '4', '6'],
|
||||
answer: 4,
|
||||
explanation: '[x²]₀² = 4 − 0 = 4.',
|
||||
},
|
||||
{
|
||||
number: 27,
|
||||
question: '∫₁³ (2x − 1) dx 의 값은?',
|
||||
choices: ['4', '5', '6', '7', '8'],
|
||||
answer: 3,
|
||||
explanation: '[x² − x]₁³ = (9 − 3) − (1 − 1) = 6 − 0 = 6.',
|
||||
},
|
||||
{
|
||||
number: 28,
|
||||
question: '∫ (x + 1)² dx = ?',
|
||||
choices: ['(x+1)³/3 + C', '2(x+1) + C', '(x+1)² + C', '(x+1)³ + C', 'x²/2 + x + C'],
|
||||
answer: 1,
|
||||
explanation: '∫ (x+1)² dx. t = x+1로 치환하면 ∫t² dt = t³/3 + C = (x+1)³/3 + C.',
|
||||
},
|
||||
{
|
||||
number: 29,
|
||||
question: '∫₀¹ x² dx 의 값은?',
|
||||
choices: ['1/4', '1/3', '1/2', '1', '2'],
|
||||
answer: 2,
|
||||
explanation: '[x³/3]₀¹ = 1/3 − 0 = 1/3.',
|
||||
},
|
||||
{
|
||||
number: 30,
|
||||
question: 'y = x² 와 y = x 로 둘러싸인 넓이는?',
|
||||
choices: ['1/6', '1/4', '1/3', '1/2', '1'],
|
||||
answer: 1,
|
||||
explanation: '교점: x² = x → x = 0, 1. 넓이 = ∫₀¹ (x − x²) dx = [x²/2 − x³/3]₀¹ = 1/2 − 1/3 = 1/6.',
|
||||
},
|
||||
];
|
||||
229
frontend/src/app/exams/sample-ebook/data/high-3.ts
Normal file
229
frontend/src/app/exams/sample-ebook/data/high-3.ts
Normal file
@@ -0,0 +1,229 @@
|
||||
import type { SampleProblem } from './types';
|
||||
|
||||
export const PROBLEMS: SampleProblem[] = [
|
||||
// ── 극한 (1~5) ────────────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 1,
|
||||
question: 'lim(x→2) (x² − 4) / (x − 2) 의 값은?',
|
||||
choices: ['0', '2', '4', '6', '수렴하지 않음'],
|
||||
answer: 3,
|
||||
explanation: '분자 인수분해: (x−2)(x+2). 약분 후 lim(x→2) (x+2) = 2 + 2 = 4.',
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
question: 'lim(x→∞) (3x² + 2x) / (x² − 1) 의 값은?',
|
||||
choices: ['0', '1', '2', '3', '∞'],
|
||||
answer: 4,
|
||||
explanation: '분자 분모를 최고차항 x²으로 나누면 lim = (3 + 2/x) / (1 − 1/x²) → 3/1 = 3.',
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
question: 'lim(x→0) sin x / x 의 값은?',
|
||||
choices: ['0', '1', 'π', '∞', '존재하지 않음'],
|
||||
answer: 2,
|
||||
explanation: '기본 극한: lim(x→0) sin x / x = 1 (중요 표준 극한).',
|
||||
},
|
||||
{
|
||||
number: 4,
|
||||
question: 'lim(n→∞) (1 + 1/n)^n 의 값은?',
|
||||
choices: ['1', '2', '3', 'e', 'π'],
|
||||
answer: 4,
|
||||
explanation: '자연상수 e의 정의: e = lim(n→∞) (1 + 1/n)^n ≈ 2.718…',
|
||||
},
|
||||
{
|
||||
number: 5,
|
||||
question: 'f(x) = x² 에서 x = 1에서의 미분계수 lim(h→0) [f(1+h)−f(1)]/h 의 값은?',
|
||||
choices: ['0', '1', '2', '3', '4'],
|
||||
answer: 3,
|
||||
explanation: 'f(1+h) = (1+h)² = 1 + 2h + h². [f(1+h)−f(1)]/h = (2h + h²)/h = 2 + h → h→0이면 2.',
|
||||
},
|
||||
|
||||
// ── 미분법 심화 (6~11) ────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 6,
|
||||
question: 'f(x) = e^x 의 도함수는?',
|
||||
choices: ['e^(x−1)', 'x·e^x', 'e^x', '1/e^x', 'e'],
|
||||
answer: 3,
|
||||
explanation: '지수함수의 미분: e^x의 도함수 = e^x. 자기 자신이 도함수.',
|
||||
},
|
||||
{
|
||||
number: 7,
|
||||
question: 'f(x) = ln x 의 도함수는? (x > 0)',
|
||||
choices: ['ln x', '1/x', 'x', 'e^x', '1/(x ln x)'],
|
||||
answer: 2,
|
||||
explanation: '자연로그 미분: ln x의 도함수 = 1/x.',
|
||||
},
|
||||
{
|
||||
number: 8,
|
||||
question: 'f(x) = sin x 의 도함수는?',
|
||||
choices: ['−sin x', 'sin x', '−cos x', 'cos x', 'tan x'],
|
||||
answer: 4,
|
||||
explanation: '삼각함수 미분: sin x의 도함수 = cos x.',
|
||||
},
|
||||
{
|
||||
number: 9,
|
||||
question: 'f(x) = x² · sin x 의 도함수는? (곱의 미분)',
|
||||
choices: [
|
||||
'2x · cos x',
|
||||
'2x · sin x + x² · cos x',
|
||||
'x² · cos x',
|
||||
'2x · sin x − x² · cos x',
|
||||
'x² · sin x + 2x',
|
||||
],
|
||||
answer: 2,
|
||||
explanation: '곱의 미분: (uv)의 도함수 = u´v + uv´. u = x², u´ = 2x; v = sin x, v´ = cos x. 결과: 2x sin x + x² cos x.',
|
||||
},
|
||||
{
|
||||
number: 10,
|
||||
question: '합성함수 f(x) = (2x + 1)³ 의 도함수는?',
|
||||
choices: ['3(2x+1)²', '6(2x+1)²', '3(2x+1)', '6(2x+1)', '2(2x+1)³'],
|
||||
answer: 2,
|
||||
explanation: '연쇄 법칙: (u³)의 도함수 = 3u² × u´. u = 2x+1, u´ = 2. 결과: 3(2x+1)² × 2 = 6(2x+1)².',
|
||||
},
|
||||
{
|
||||
number: 11,
|
||||
question: 'f(x) = x³ − 6x² + 9x 의 극대값은?',
|
||||
choices: ['0', '2', '4', '6', '9'],
|
||||
answer: 3,
|
||||
explanation: 'f´(x) = 3x² − 12x + 9 = 3(x−1)(x−3) = 0 → x = 1(극대), x = 3(극소). f(1) = 1 − 6 + 9 = 4.',
|
||||
},
|
||||
|
||||
// ── 적분법 심화 (12~17) ───────────────────────────────────────────────────────
|
||||
{
|
||||
number: 12,
|
||||
question: '∫ e^x dx = ?',
|
||||
choices: ['e^(x+1) + C', 'e^x + C', 'x·e^x + C', '1/e^x + C', 'e^x/x + C'],
|
||||
answer: 2,
|
||||
explanation: '∫ e^x dx = e^x + C. e^x는 자신이 미분/적분의 고유함수.',
|
||||
},
|
||||
{
|
||||
number: 13,
|
||||
question: '∫ 1/x dx = ? (x > 0)',
|
||||
choices: ['1/x² + C', 'x + C', 'ln x + C', '1/(x+1) + C', 'e^x + C'],
|
||||
answer: 3,
|
||||
explanation: '∫ (1/x) dx = ln |x| + C. x > 0이면 ln x + C.',
|
||||
},
|
||||
{
|
||||
number: 14,
|
||||
question: '∫ cos x dx = ?',
|
||||
choices: ['−sin x + C', 'sin x + C', '−cos x + C', 'cos x + C', 'tan x + C'],
|
||||
answer: 2,
|
||||
explanation: '∫ cos x dx = sin x + C. sin x의 도함수가 cos x이므로 역연산.',
|
||||
},
|
||||
{
|
||||
number: 15,
|
||||
question: '∫₀^π sin x dx 의 값은?',
|
||||
choices: ['0', '1', '2', 'π', '−2'],
|
||||
answer: 3,
|
||||
explanation: '[−cos x]₀^π = −cos π − (−cos 0) = −(−1) − (−1) = 1 + 1 = 2.',
|
||||
},
|
||||
{
|
||||
number: 16,
|
||||
question: '부분적분을 이용해 ∫ x·e^x dx 를 구하면?',
|
||||
choices: ['x·e^x + C', 'x·e^x − e^x + C', 'e^x + C', 'x²·e^x/2 + C', '(x−1)·e^x + C'],
|
||||
answer: 2,
|
||||
explanation: '부분적분: u=x, dv=e^x dx → du=dx, v=e^x. ∫x·e^x dx = x·e^x − ∫e^x dx = x·e^x − e^x + C.',
|
||||
},
|
||||
{
|
||||
number: 17,
|
||||
question: 'y = x³ − x 와 x 축으로 둘러싸인 넓이는? (−1 ≤ x ≤ 1 구간)',
|
||||
choices: ['0', '1/2', '1', '3/2', '2'],
|
||||
answer: 2,
|
||||
explanation: '|∫₋₁⁰ (x³−x) dx| + |∫₀¹ (x³−x) dx| = 1/4 + 1/4 = 1/2. 대칭 활용.',
|
||||
},
|
||||
|
||||
// ── 확률과 통계 (18~24) ───────────────────────────────────────────────────────
|
||||
{
|
||||
number: 18,
|
||||
question: '5명을 일렬로 세울 때 특정 2명이 항상 이웃하는 경우의 수는?',
|
||||
choices: ['24', '36', '48', '60', '72'],
|
||||
answer: 3,
|
||||
explanation: '2명을 묶어 1명으로 보면 4명 배열: 4! = 24. 묶음 내부 순서: 2! = 2. 24 × 2 = 48.',
|
||||
},
|
||||
{
|
||||
number: 19,
|
||||
question: 'C(6, 2) 의 값은?',
|
||||
choices: ['10', '12', '15', '18', '30'],
|
||||
answer: 3,
|
||||
explanation: 'C(6,2) = 6!/(2!·4!) = (6×5)/2 = 15.',
|
||||
},
|
||||
{
|
||||
number: 20,
|
||||
question: '이항분포 B(10, 0.5)의 평균은?',
|
||||
choices: ['2', '4', '5', '6', '10'],
|
||||
answer: 3,
|
||||
explanation: '이항분포 B(n,p)의 평균 = np = 10 × 0.5 = 5.',
|
||||
},
|
||||
{
|
||||
number: 21,
|
||||
question: '정규분포 N(50, 10²)에서 P(40 ≤ X ≤ 60)은? (표준정규표준: P(0≤Z≤1) = 0.3413)',
|
||||
choices: ['0.3413', '0.5', '0.6826', '0.9544', '1'],
|
||||
answer: 3,
|
||||
explanation: 'Z = (X−50)/10. P(40≤X≤60) = P(−1≤Z≤1) = 2×P(0≤Z≤1) = 2×0.3413 = 0.6826.',
|
||||
},
|
||||
{
|
||||
number: 22,
|
||||
question: '두 사건 A, B가 독립이고 P(A) = 0.4, P(B) = 0.5이면 P(A∩B)는?',
|
||||
choices: ['0.1', '0.2', '0.4', '0.5', '0.9'],
|
||||
answer: 2,
|
||||
explanation: '독립사건: P(A∩B) = P(A) × P(B) = 0.4 × 0.5 = 0.2.',
|
||||
},
|
||||
{
|
||||
number: 23,
|
||||
question: '조건부 확률 P(A|B) = P(A∩B)/P(B) 에서 P(A∩B) = 0.12, P(B) = 0.4이면 P(A|B)는?',
|
||||
choices: ['0.2', '0.3', '0.4', '0.5', '0.6'],
|
||||
answer: 2,
|
||||
explanation: 'P(A|B) = 0.12 / 0.4 = 0.3.',
|
||||
},
|
||||
{
|
||||
number: 24,
|
||||
question: '표본 크기 n = 100, 표본 평균 x̄ = 75, 모표준편차 σ = 10일 때 모평균의 95% 신뢰구간 폭은? (z₀.₀₂₅ ≈ 1.96)',
|
||||
choices: ['1.96', '2.96', '3.92', '4.90', '19.6'],
|
||||
answer: 3,
|
||||
explanation: '신뢰구간 폭 = 2 × z × σ/√n = 2 × 1.96 × 10/10 = 2 × 1.96 = 3.92.',
|
||||
},
|
||||
|
||||
// ── 벡터/공간좌표 (25~30) ─────────────────────────────────────────────────────
|
||||
{
|
||||
number: 25,
|
||||
question: '벡터 a→ = (3, 4) 의 크기 |a→|는?',
|
||||
choices: ['5', '6', '7', '12', '25'],
|
||||
answer: 1,
|
||||
explanation: '|a→| = √(3² + 4²) = √(9+16) = √25 = 5.',
|
||||
},
|
||||
{
|
||||
number: 26,
|
||||
question: 'a→ = (1, 2), b→ = (3, −1) 일 때 a→ + b→ 의 y 성분은?',
|
||||
choices: ['−1', '0', '1', '2', '3'],
|
||||
answer: 3,
|
||||
explanation: 'a→ + b→ = (1+3, 2+(−1)) = (4, 1). y 성분 = 1.',
|
||||
},
|
||||
{
|
||||
number: 27,
|
||||
question: 'a→ = (2, 1), b→ = (1, 3) 일 때 내적 a→·b→ 는?',
|
||||
choices: ['3', '4', '5', '6', '7'],
|
||||
answer: 3,
|
||||
explanation: 'a→·b→ = 2×1 + 1×3 = 2 + 3 = 5.',
|
||||
},
|
||||
{
|
||||
number: 28,
|
||||
question: '두 벡터 a→ = (1, 0), b→ = (0, 1) 의 내적은?',
|
||||
choices: ['−1', '0', '1', '√2', '2'],
|
||||
answer: 2,
|
||||
explanation: 'a→·b→ = 1×0 + 0×1 = 0. 수직(직교)이면 내적 = 0.',
|
||||
},
|
||||
{
|
||||
number: 29,
|
||||
question: '점 A(1, 2, 3), B(4, 6, 3) 사이의 거리는?',
|
||||
choices: ['3', '4', '5', '6', '7'],
|
||||
answer: 3,
|
||||
explanation: 'd = √((4−1)² + (6−2)² + (3−3)²) = √(9+16+0) = √25 = 5.',
|
||||
},
|
||||
{
|
||||
number: 30,
|
||||
question: '공간에서 직선 x/1 = y/2 = z/3 의 방향벡터는?',
|
||||
choices: ['(1,1,1)', '(1,2,3)', '(3,2,1)', '(2,3,1)', '(0,0,0)'],
|
||||
answer: 2,
|
||||
explanation: '대칭형 방정식 x/a = y/b = z/c에서 방향벡터 = (a, b, c) = (1, 2, 3).',
|
||||
},
|
||||
];
|
||||
71
frontend/src/app/exams/sample-ebook/data/index.ts
Normal file
71
frontend/src/app/exams/sample-ebook/data/index.ts
Normal file
@@ -0,0 +1,71 @@
|
||||
import type { SampleProblem } from './types';
|
||||
import { PROBLEMS as MIDDLE1_PROBLEMS } from './middle-1';
|
||||
import { PROBLEMS as MIDDLE2_PROBLEMS } from './middle-2';
|
||||
import { PROBLEMS as MIDDLE3_PROBLEMS } from './middle-3';
|
||||
import { PROBLEMS as HIGH1_PROBLEMS } from './high-1';
|
||||
import { PROBLEMS as HIGH2_PROBLEMS } from './high-2';
|
||||
import { PROBLEMS as HIGH3_PROBLEMS } from './high-3';
|
||||
|
||||
export type { SampleProblem };
|
||||
|
||||
export interface EbookMeta {
|
||||
id: string;
|
||||
title: string;
|
||||
grade: string;
|
||||
subtitle: string;
|
||||
problemCount: number;
|
||||
problems: SampleProblem[];
|
||||
}
|
||||
|
||||
export const EBOOK_MAP: Record<string, EbookMeta> = {
|
||||
'middle-1': {
|
||||
id: 'middle-1',
|
||||
title: '[샘플] 중1 수학 문제집',
|
||||
grade: '중1',
|
||||
subtitle: '중학교 1학년 수학 교과과정',
|
||||
problemCount: 30,
|
||||
problems: MIDDLE1_PROBLEMS,
|
||||
},
|
||||
'middle-2': {
|
||||
id: 'middle-2',
|
||||
title: '[샘플] 중2 수학 문제집',
|
||||
grade: '중2',
|
||||
subtitle: '중학교 2학년 수학 교과과정',
|
||||
problemCount: 30,
|
||||
problems: MIDDLE2_PROBLEMS,
|
||||
},
|
||||
'middle-3': {
|
||||
id: 'middle-3',
|
||||
title: '[샘플] 중3 수학 문제집',
|
||||
grade: '중3',
|
||||
subtitle: '중학교 3학년 수학 교과과정',
|
||||
problemCount: 30,
|
||||
problems: MIDDLE3_PROBLEMS,
|
||||
},
|
||||
'high-1': {
|
||||
id: 'high-1',
|
||||
title: '[샘플] 고1 수학 문제집',
|
||||
grade: '고1',
|
||||
subtitle: '고등학교 1학년 수학 교과과정',
|
||||
problemCount: 30,
|
||||
problems: HIGH1_PROBLEMS,
|
||||
},
|
||||
'high-2': {
|
||||
id: 'high-2',
|
||||
title: '[샘플] 고2 수학 문제집',
|
||||
grade: '고2',
|
||||
subtitle: '고등학교 2학년 수학 교과과정',
|
||||
problemCount: 30,
|
||||
problems: HIGH2_PROBLEMS,
|
||||
},
|
||||
'high-3': {
|
||||
id: 'high-3',
|
||||
title: '[샘플] 고3 수학 문제집',
|
||||
grade: '고3',
|
||||
subtitle: '고등학교 3학년 수학 교과과정',
|
||||
problemCount: 30,
|
||||
problems: HIGH3_PROBLEMS,
|
||||
},
|
||||
};
|
||||
|
||||
export const EBOOK_LIST: EbookMeta[] = Object.values(EBOOK_MAP);
|
||||
223
frontend/src/app/exams/sample-ebook/data/middle-1.ts
Normal file
223
frontend/src/app/exams/sample-ebook/data/middle-1.ts
Normal file
@@ -0,0 +1,223 @@
|
||||
import type { SampleProblem } from './types';
|
||||
|
||||
export const PROBLEMS: SampleProblem[] = [
|
||||
// ── 자연수와 정수 (1~6) ──────────────────────────────────────────────────────
|
||||
{
|
||||
number: 1,
|
||||
question: '절댓값 |−7| 의 값은?',
|
||||
choices: ['−7', '−1', '0', '1', '7'],
|
||||
answer: 5,
|
||||
explanation: '절댓값은 수직선에서 원점까지의 거리이므로 음수 기호를 제거한다. |−7| = 7.',
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
question: '다음 중 가장 작은 수는?\n−3, 2, −5, 0, 4',
|
||||
choices: ['−3', '2', '−5', '0', '4'],
|
||||
answer: 3,
|
||||
explanation: '수직선에서 왼쪽에 있을수록 작다. −5 < −3 < 0 < 2 < 4 이므로 −5가 가장 작다.',
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
question: '(−3) + (−8) 의 값은?',
|
||||
choices: ['−11', '−5', '5', '11', '24'],
|
||||
answer: 1,
|
||||
explanation: '부호가 같은 두 음수의 합은 절댓값의 합에 음수 부호를 붙인다. (−3) + (−8) = −11.',
|
||||
},
|
||||
{
|
||||
number: 4,
|
||||
question: '(−4) × (−6) 의 값은?',
|
||||
choices: ['−24', '−10', '10', '24', '48'],
|
||||
answer: 4,
|
||||
explanation: '음수 × 음수 = 양수. 4 × 6 = 24이므로 (−4) × (−6) = 24.',
|
||||
},
|
||||
{
|
||||
number: 5,
|
||||
question: '(+5) ÷ (−1/2) 의 값은?',
|
||||
choices: ['−10', '−5/2', '5/2', '5', '10'],
|
||||
answer: 1,
|
||||
explanation: '÷ (−1/2) = × (−2). 5 × (−2) = −10. 양수 ÷ 음수이므로 결과는 음수.',
|
||||
},
|
||||
{
|
||||
number: 6,
|
||||
question: '−2³ + (−1)⁴ 의 값은?',
|
||||
choices: ['−9', '−7', '−6', '7', '9'],
|
||||
answer: 2,
|
||||
explanation: '−2³ = −8, (−1)⁴ = 1. 따라서 −8 + 1 = −7.',
|
||||
},
|
||||
|
||||
// ── 일차방정식 (7~12) ────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 7,
|
||||
question: '방정식 2x − 3 = 7 의 해는?',
|
||||
choices: ['2', '4', '5', '7', '10'],
|
||||
answer: 3,
|
||||
explanation: '2x = 7 + 3 = 10. x = 10 ÷ 2 = 5.',
|
||||
},
|
||||
{
|
||||
number: 8,
|
||||
question: '방정식 3(x + 1) = 12 의 해는?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 3,
|
||||
explanation: '3x + 3 = 12. 3x = 9. x = 3.',
|
||||
},
|
||||
{
|
||||
number: 9,
|
||||
question: '방정식 x/2 + 1 = 4 의 해는?',
|
||||
choices: ['2', '3', '5', '6', '8'],
|
||||
answer: 4,
|
||||
explanation: 'x/2 = 4 − 1 = 3. 양변에 2를 곱하면 x = 6.',
|
||||
},
|
||||
{
|
||||
number: 10,
|
||||
question: '방정식 5x − 4 = 2x + 8 의 해는?',
|
||||
choices: ['2', '3', '4', '5', '6'],
|
||||
answer: 3,
|
||||
explanation: '5x − 2x = 8 + 4. 3x = 12. x = 4.',
|
||||
},
|
||||
{
|
||||
number: 11,
|
||||
question: '어떤 수의 3배에서 5를 빼면 16이다. 이 어떤 수는?',
|
||||
choices: ['5', '6', '7', '8', '9'],
|
||||
answer: 3,
|
||||
explanation: '3x − 5 = 16. 3x = 21. x = 7.',
|
||||
},
|
||||
{
|
||||
number: 12,
|
||||
question: '방정식 2(x − 3) = x + 1 의 해는?',
|
||||
choices: ['5', '6', '7', '8', '9'],
|
||||
answer: 3,
|
||||
explanation: '2x − 6 = x + 1. 2x − x = 1 + 6. x = 7.',
|
||||
},
|
||||
|
||||
// ── 좌표평면과 그래프 (13~18) ────────────────────────────────────────────────
|
||||
{
|
||||
number: 13,
|
||||
question: '점 (−3, 2) 는 몇 사분면에 위치하는가?',
|
||||
choices: ['제1사분면', '제2사분면', '제3사분면', '제4사분면', '어느 사분면도 아님'],
|
||||
answer: 2,
|
||||
explanation: 'x < 0, y > 0 이면 제2사분면. (−3, 2)는 x = −3 < 0, y = 2 > 0이므로 제2사분면.',
|
||||
},
|
||||
{
|
||||
number: 14,
|
||||
question: '두 점 A(1, 3), B(4, 7) 사이의 x 좌표 차이는?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 3,
|
||||
explanation: '4 − 1 = 3. x 좌표끼리의 차이를 구한다.',
|
||||
},
|
||||
{
|
||||
number: 15,
|
||||
question: 'y = 2x + 1 에서 x = 3일 때 y의 값은?',
|
||||
choices: ['5', '6', '7', '8', '9'],
|
||||
answer: 3,
|
||||
explanation: 'y = 2 × 3 + 1 = 6 + 1 = 7.',
|
||||
},
|
||||
{
|
||||
number: 16,
|
||||
question: 'y = −x + 4 의 그래프가 지나는 점은?',
|
||||
choices: ['(0, −4)', '(2, 2)', '(4, 0)', '(−1, 3)', '(3, 0)'],
|
||||
answer: 2,
|
||||
explanation: 'x = 2일 때 y = −2 + 4 = 2. 따라서 점 (2, 2)를 지난다.',
|
||||
},
|
||||
{
|
||||
number: 17,
|
||||
question: '좌표축 위의 점 (5, 0) 이 위치하는 곳은?',
|
||||
choices: ['제1사분면', '제2사분면', 'x 축', 'y 축', '원점'],
|
||||
answer: 3,
|
||||
explanation: 'y = 0인 점은 x 축 위에 있다. (5, 0)은 x 축 위의 점.',
|
||||
},
|
||||
{
|
||||
number: 18,
|
||||
question: 'y = 3x 그래프의 기울기는?',
|
||||
choices: ['−3', '0', '1', '3', '9'],
|
||||
answer: 4,
|
||||
explanation: 'y = mx 형태에서 m이 기울기. y = 3x에서 기울기는 3.',
|
||||
},
|
||||
|
||||
// ── 기본 도형 (19~24) ────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 19,
|
||||
question: '삼각형 세 내각의 합은?',
|
||||
choices: ['90°', '120°', '180°', '270°', '360°'],
|
||||
answer: 3,
|
||||
explanation: '삼각형 세 내각의 합은 항상 180°이다.',
|
||||
},
|
||||
{
|
||||
number: 20,
|
||||
question: '정삼각형 한 각의 크기는?',
|
||||
choices: ['45°', '60°', '90°', '108°', '120°'],
|
||||
answer: 2,
|
||||
explanation: '정삼각형은 세 각이 모두 같고 합이 180°. 180° ÷ 3 = 60°.',
|
||||
},
|
||||
{
|
||||
number: 21,
|
||||
question: '반지름이 4 cm인 원의 둘레는? (π 사용)',
|
||||
choices: ['4π cm', '8π cm', '12π cm', '16π cm', '32π cm'],
|
||||
answer: 2,
|
||||
explanation: '원의 둘레 = 2πr. 2 × π × 4 = 8π cm.',
|
||||
},
|
||||
{
|
||||
number: 22,
|
||||
question: '직각삼각형에서 한 예각이 35°이면 다른 예각은?',
|
||||
choices: ['35°', '45°', '55°', '65°', '90°'],
|
||||
answer: 3,
|
||||
explanation: '세 각의 합 = 180°. 90° + 35° + ? = 180°. 나머지 각 = 55°.',
|
||||
},
|
||||
{
|
||||
number: 23,
|
||||
question: '평행사변형의 두 대각선은 서로 어떤 관계인가?',
|
||||
choices: ['수직이등분', '수직', '서로 이등분', '같은 길이', '평행'],
|
||||
answer: 3,
|
||||
explanation: '평행사변형에서 두 대각선은 서로 이등분(교점에서 각각 반으로 나뉨)한다.',
|
||||
},
|
||||
{
|
||||
number: 24,
|
||||
question: '밑변 6 cm, 높이 4 cm인 삼각형의 넓이는?',
|
||||
choices: ['10 cm²', '12 cm²', '18 cm²', '24 cm²', '48 cm²'],
|
||||
answer: 2,
|
||||
explanation: '삼각형 넓이 = (밑변 × 높이) ÷ 2 = (6 × 4) ÷ 2 = 12 cm².',
|
||||
},
|
||||
|
||||
// ── 비례/반비례 (25~30) ──────────────────────────────────────────────────────
|
||||
{
|
||||
number: 25,
|
||||
question: 'y 가 x 에 정비례하고 x = 3일 때 y = 12이다. x = 5일 때 y는?',
|
||||
choices: ['15', '18', '20', '24', '30'],
|
||||
answer: 3,
|
||||
explanation: '정비례: y = kx. 12 = k × 3 → k = 4. y = 4 × 5 = 20.',
|
||||
},
|
||||
{
|
||||
number: 26,
|
||||
question: 'y 가 x 에 반비례하고 x = 2일 때 y = 6이다. x = 4일 때 y는?',
|
||||
choices: ['2', '3', '4', '6', '12'],
|
||||
answer: 2,
|
||||
explanation: '반비례: xy = k. 2 × 6 = 12 = k. x = 4이면 y = 12/4 = 3.',
|
||||
},
|
||||
{
|
||||
number: 27,
|
||||
question: 'y = 6/x 에서 x = 2일 때 y의 값은?',
|
||||
choices: ['1', '2', '3', '6', '12'],
|
||||
answer: 3,
|
||||
explanation: 'y = 6/2 = 3.',
|
||||
},
|
||||
{
|
||||
number: 28,
|
||||
question: '시속 60 km로 달리는 자동차가 3시간 동안 이동하는 거리는?',
|
||||
choices: ['120 km', '150 km', '180 km', '200 km', '240 km'],
|
||||
answer: 3,
|
||||
explanation: '거리 = 속력 × 시간. 60 × 3 = 180 km.',
|
||||
},
|
||||
{
|
||||
number: 29,
|
||||
question: '비 3:4에서 전체를 70으로 할 때, 3에 해당하는 양은?',
|
||||
choices: ['21', '28', '30', '35', '42'],
|
||||
answer: 3,
|
||||
explanation: '전체 비율 3 + 4 = 7. 3에 해당하는 양 = 70 × (3/7) = 30.',
|
||||
},
|
||||
{
|
||||
number: 30,
|
||||
question: '가로 세로 비가 3:5인 직사각형에서 가로가 9 cm이면 세로는?',
|
||||
choices: ['12 cm', '13 cm', '14 cm', '15 cm', '18 cm'],
|
||||
answer: 4,
|
||||
explanation: '3:5 = 9:x. 3x = 45. x = 15 cm.',
|
||||
},
|
||||
];
|
||||
241
frontend/src/app/exams/sample-ebook/data/middle-2.ts
Normal file
241
frontend/src/app/exams/sample-ebook/data/middle-2.ts
Normal file
@@ -0,0 +1,241 @@
|
||||
import type { SampleProblem } from './types';
|
||||
|
||||
export const PROBLEMS: SampleProblem[] = [
|
||||
// ── 유리수/무리수 (1~6) ───────────────────────────────────────────────────────
|
||||
{
|
||||
number: 1,
|
||||
question: '다음 중 무리수인 것은?',
|
||||
choices: ['√4', '0.333…', '−5/3', '√7', '1.25'],
|
||||
answer: 4,
|
||||
explanation: '√4 = 2(유리수), 0.333… = 1/3(유리수), −5/3(유리수), 1.25(유리수). √7은 유한소수나 순환소수로 나타낼 수 없으므로 무리수.',
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
question: '√18 을 가장 간단한 꼴로 나타내면?',
|
||||
choices: ['3√2', '2√3', '3√6', '6√2', '9√2'],
|
||||
answer: 1,
|
||||
explanation: '√18 = √(9 × 2) = √9 × √2 = 3√2.',
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
question: '√2 × √8 의 값은?',
|
||||
choices: ['2', '4', '√10', '2√4', '8'],
|
||||
answer: 2,
|
||||
explanation: '√2 × √8 = √(2 × 8) = √16 = 4.',
|
||||
},
|
||||
{
|
||||
number: 4,
|
||||
question: '2√3 + 5√3 의 값은?',
|
||||
choices: ['7', '7√3', '10√3', '7√6', '√21'],
|
||||
answer: 2,
|
||||
explanation: '같은 무리수끼리 계수를 더한다. (2 + 5)√3 = 7√3.',
|
||||
},
|
||||
{
|
||||
number: 5,
|
||||
question: '√5 ≈ 2.236 일 때, 3√5 의 근삿값은?',
|
||||
choices: ['5.618', '6.618', '6.708', '7.236', '8.236'],
|
||||
answer: 3,
|
||||
explanation: '3 × 2.236 = 6.708.',
|
||||
},
|
||||
{
|
||||
number: 6,
|
||||
question: '다음 중 유리수와 무리수에 대한 설명으로 옳은 것은?',
|
||||
choices: [
|
||||
'무리수는 음수가 될 수 없다',
|
||||
'유리수와 무리수의 합은 항상 무리수이다',
|
||||
'모든 순환소수는 무리수이다',
|
||||
'√9 는 무리수이다',
|
||||
'두 무리수의 합은 항상 무리수이다',
|
||||
],
|
||||
answer: 2,
|
||||
explanation: '유리수 + 무리수 = 무리수. 예: 1 + √2 = 1 + √2(무리수). 순환소수는 유리수, √9 = 3(유리수).',
|
||||
},
|
||||
|
||||
// ── 연립방정식 (7~12) ────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 7,
|
||||
question: '연립방정식 { x + y = 5, x − y = 1 } 을 풀면 x의 값은?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 3,
|
||||
explanation: '두 식을 더하면 2x = 6. x = 3. (y = 5 − 3 = 2 검증 가능)',
|
||||
},
|
||||
{
|
||||
number: 8,
|
||||
question: '연립방정식 { 2x + y = 7, x + 2y = 8 } 을 풀면 y의 값은?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 3,
|
||||
explanation: '첫 식에서 y = 7 − 2x. 대입하면 x + 2(7 − 2x) = 8 → x + 14 − 4x = 8 → −3x = −6 → x = 2. y = 7 − 4 = 3.',
|
||||
},
|
||||
{
|
||||
number: 9,
|
||||
question: '연립방정식 { x − y = 4, 2x + y = 8 } 을 풀면 x + y의 값은?',
|
||||
choices: ['2', '3', '4', '5', '6'],
|
||||
answer: 3,
|
||||
explanation: '더하면 3x = 12 → x = 4. y = 4 − 4 = 0. x + y = 4.',
|
||||
},
|
||||
{
|
||||
number: 10,
|
||||
question: '연립방정식 { 3x − 2y = 1, x + y = 7 } 에서 x의 값은?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 3,
|
||||
explanation: 'y = 7 − x를 대입: 3x − 2(7 − x) = 1 → 3x − 14 + 2x = 1 → 5x = 15 → x = 3.',
|
||||
},
|
||||
{
|
||||
number: 11,
|
||||
question: '어른 2명과 어린이 3명의 입장료 합이 13,000원, 어른 1명과 어린이 1명의 합이 6,000원일 때 어른 1명의 입장료는?',
|
||||
choices: ['3,000원', '4,000원', '5,000원', '6,000원', '7,000원'],
|
||||
answer: 3,
|
||||
explanation: 'a + c = 6000에서 c = 6000 − a. 2a + 3(6000 − a) = 13000 → 2a + 18000 − 3a = 13000 → −a = −5000 → a = 5,000원.',
|
||||
},
|
||||
{
|
||||
number: 12,
|
||||
question: '연립방정식 { 2x − y = 3, 4x − 2y = 6 } 의 해의 개수는?',
|
||||
choices: ['0개(불능)', '1개', '2개', '무한히 많다(부정)', '판단 불가'],
|
||||
answer: 4,
|
||||
explanation: '두 번째 식은 첫 번째 식에 2를 곱한 것과 같다. 두 식이 일치하므로 해가 무한히 많다(부정).',
|
||||
},
|
||||
|
||||
// ── 일차함수 (13~18) ─────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 13,
|
||||
question: '일차함수 y = 3x − 2 에서 y 절편(x = 0)의 값은?',
|
||||
choices: ['−3', '−2', '0', '2', '3'],
|
||||
answer: 2,
|
||||
explanation: 'x = 0 대입: y = 3 × 0 − 2 = −2. y 절편은 −2.',
|
||||
},
|
||||
{
|
||||
number: 14,
|
||||
question: '일차함수 y = −2x + 5 의 기울기는?',
|
||||
choices: ['−5', '−2', '−1', '2', '5'],
|
||||
answer: 2,
|
||||
explanation: 'y = mx + b 형태에서 m이 기울기. y = −2x + 5에서 기울기 = −2.',
|
||||
},
|
||||
{
|
||||
number: 15,
|
||||
question: '두 점 (1, 3), (3, 7)을 지나는 직선의 기울기는?',
|
||||
choices: ['1', '2', '3', '4', '5'],
|
||||
answer: 2,
|
||||
explanation: '기울기 = (y₂ − y₁) / (x₂ − x₁) = (7 − 3) / (3 − 1) = 4 / 2 = 2.',
|
||||
},
|
||||
{
|
||||
number: 16,
|
||||
question: 'y = ax + b 에서 a > 0, b < 0이면 그래프는?',
|
||||
choices: [
|
||||
'오른쪽 위로 기울고 y 절편이 양수',
|
||||
'오른쪽 아래로 기울고 y 절편이 양수',
|
||||
'오른쪽 위로 기울고 y 절편이 음수',
|
||||
'오른쪽 아래로 기울고 y 절편이 음수',
|
||||
'수평선',
|
||||
],
|
||||
answer: 3,
|
||||
explanation: 'a > 0 이면 오른쪽 위로 증가, b < 0 이면 y 절편이 음수(원점 아래를 지남).',
|
||||
},
|
||||
{
|
||||
number: 17,
|
||||
question: 'y = 2x + 1 과 y = 2x − 3 의 관계는?',
|
||||
choices: ['한 점에서 만난다', '두 점에서 만난다', '평행하다', '일치한다', '수직이다'],
|
||||
answer: 3,
|
||||
explanation: '두 직선의 기울기가 같고 (2 = 2) y 절편이 다르므로 평행하다.',
|
||||
},
|
||||
{
|
||||
number: 18,
|
||||
question: 'y = x + 2 와 y = −x + 4 의 교점의 x 좌표는?',
|
||||
choices: ['0', '1', '2', '3', '4'],
|
||||
answer: 2,
|
||||
explanation: 'x + 2 = −x + 4 → 2x = 2 → x = 1.',
|
||||
},
|
||||
|
||||
// ── 삼각형 성질 (19~24) ──────────────────────────────────────────────────────
|
||||
{
|
||||
number: 19,
|
||||
question: '이등변삼각형에서 꼭짓각이 40°이면 밑각 하나의 크기는?',
|
||||
choices: ['50°', '60°', '70°', '80°', '90°'],
|
||||
answer: 3,
|
||||
explanation: '세 각의 합 = 180°. 두 밑각이 같으므로 2a + 40° = 180° → 2a = 140° → a = 70°.',
|
||||
},
|
||||
{
|
||||
number: 20,
|
||||
question: '삼각형의 외각은 그 이웃하지 않는 두 내각의 합과 어떤 관계인가?',
|
||||
choices: ['같다', '크다', '작다', '두 배이다', '절반이다'],
|
||||
answer: 1,
|
||||
explanation: '삼각형 외각 정리: 한 외각의 크기 = 그 이웃하지 않는 두 내각의 합.',
|
||||
},
|
||||
{
|
||||
number: 21,
|
||||
question: 'SSS 합동 조건이란?',
|
||||
choices: [
|
||||
'두 변과 그 끼인각이 각각 같다',
|
||||
'두 각과 그 끼인변이 각각 같다',
|
||||
'세 변의 길이가 각각 같다',
|
||||
'한 변과 두 각이 같다',
|
||||
'빗변과 한 예각이 같다',
|
||||
],
|
||||
answer: 3,
|
||||
explanation: 'SSS(Side-Side-Side) 합동 조건: 세 쌍의 대응 변의 길이가 모두 같을 때.',
|
||||
},
|
||||
{
|
||||
number: 22,
|
||||
question: '직각삼각형에서 두 직각변이 3, 4일 때 빗변의 길이는?',
|
||||
choices: ['3', '4', '5', '6', '7'],
|
||||
answer: 3,
|
||||
explanation: '피타고라스 정리: 3² + 4² = 9 + 16 = 25 = 5². 빗변 = 5.',
|
||||
},
|
||||
{
|
||||
number: 23,
|
||||
question: '삼각형 내각의 이등분선의 교점을 무엇이라 하는가?',
|
||||
choices: ['외심', '무게중심', '수심', '내심', '꼭짓점'],
|
||||
answer: 4,
|
||||
explanation: '내각의 이등분선 교점 = 내심(내접원의 중심). 외각이등분선 교점은 방심.',
|
||||
},
|
||||
{
|
||||
number: 24,
|
||||
question: '세 중선의 교점(무게중심)은 각 중선을 꼭짓점으로부터 몇 대 몇으로 나누는가?',
|
||||
choices: ['1:1', '1:2', '2:1', '3:1', '1:3'],
|
||||
answer: 3,
|
||||
explanation: '무게중심은 각 중선을 꼭짓점에서부터 2:1로 나눈다.',
|
||||
},
|
||||
|
||||
// ── 확률 (25~30) ─────────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 25,
|
||||
question: '주사위 한 개를 던질 때 짝수가 나올 확률은?',
|
||||
choices: ['1/6', '1/3', '1/2', '2/3', '5/6'],
|
||||
answer: 3,
|
||||
explanation: '짝수의 눈: 2, 4, 6 → 3가지. 전체 6가지. 확률 = 3/6 = 1/2.',
|
||||
},
|
||||
{
|
||||
number: 26,
|
||||
question: '10장의 카드(1~10)에서 한 장을 뽑을 때 3의 배수일 확률은?',
|
||||
choices: ['1/10', '2/10', '3/10', '4/10', '5/10'],
|
||||
answer: 3,
|
||||
explanation: '3의 배수: 3, 6, 9 → 3가지. 확률 = 3/10.',
|
||||
},
|
||||
{
|
||||
number: 27,
|
||||
question: '동전 2개를 동시에 던질 때 둘 다 앞면일 확률은?',
|
||||
choices: ['1/4', '1/2', '3/4', '1/3', '2/3'],
|
||||
answer: 1,
|
||||
explanation: '전체 경우: HH, HT, TH, TT → 4가지. 둘 다 앞면: HH → 1가지. 확률 = 1/4.',
|
||||
},
|
||||
{
|
||||
number: 28,
|
||||
question: 'P(A) = 1/3 일 때, A가 일어나지 않을 확률은?',
|
||||
choices: ['1/6', '1/4', '1/3', '2/3', '5/6'],
|
||||
answer: 4,
|
||||
explanation: '여사건 확률 = 1 − P(A) = 1 − 1/3 = 2/3.',
|
||||
},
|
||||
{
|
||||
number: 29,
|
||||
question: '어떤 사건 A와 B가 서로 배반이고 P(A) = 0.4, P(B) = 0.3이면 P(A 또는 B)는?',
|
||||
choices: ['0.1', '0.3', '0.4', '0.7', '0.12'],
|
||||
answer: 4,
|
||||
explanation: '배반사건이면 P(A ∪ B) = P(A) + P(B) = 0.4 + 0.3 = 0.7.',
|
||||
},
|
||||
{
|
||||
number: 30,
|
||||
question: '빨간 공 4개, 파란 공 6개가 든 주머니에서 공 1개를 꺼낼 때 파란 공일 확률은?',
|
||||
choices: ['2/5', '3/5', '4/10', '1/4', '1/2'],
|
||||
answer: 2,
|
||||
explanation: '파란 공 6개 / 전체 10개 = 6/10 = 3/5.',
|
||||
},
|
||||
];
|
||||
235
frontend/src/app/exams/sample-ebook/data/middle-3.ts
Normal file
235
frontend/src/app/exams/sample-ebook/data/middle-3.ts
Normal file
@@ -0,0 +1,235 @@
|
||||
import type { SampleProblem } from './types';
|
||||
|
||||
export const PROBLEMS: SampleProblem[] = [
|
||||
// ── 인수분해 (1~5) ────────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 1,
|
||||
question: 'x² + 5x + 6 을 인수분해하면?',
|
||||
choices: ['(x+1)(x+6)', '(x+2)(x+3)', '(x−2)(x−3)', '(x+3)(x+2)', '(x−1)(x−6)'],
|
||||
answer: 2,
|
||||
explanation: '두 수의 합 = 5, 곱 = 6인 수: 2와 3. 따라서 (x+2)(x+3). ※ ②와 ④는 동일해서 ②가 정답.',
|
||||
},
|
||||
{
|
||||
number: 2,
|
||||
question: 'x² − 9 를 인수분해하면?',
|
||||
choices: ['(x−3)²', '(x+3)²', '(x−3)(x+3)', '(x−9)(x+1)', '인수분해 불가'],
|
||||
answer: 3,
|
||||
explanation: '합차 공식: a² − b² = (a−b)(a+b). x² − 9 = x² − 3² = (x−3)(x+3).',
|
||||
},
|
||||
{
|
||||
number: 3,
|
||||
question: '2x² + 4x 를 인수분해하면?',
|
||||
choices: ['2(x+2)', '2x(x+2)', 'x(2x+4)', '2(x²+2x)', '(2x+1)(x+2)'],
|
||||
answer: 2,
|
||||
explanation: '공통인수 2x를 묶는다. 2x² + 4x = 2x(x + 2).',
|
||||
},
|
||||
{
|
||||
number: 4,
|
||||
question: 'x² − 6x + 9 를 인수분해하면?',
|
||||
choices: ['(x−3)(x+3)', '(x−3)²', '(x+3)²', '(x−9)(x+1)', '(x−1)(x−9)'],
|
||||
answer: 2,
|
||||
explanation: '완전제곱식: x² − 2·3·x + 3² = (x−3)². 완전제곱 공식 (a−b)² = a²−2ab+b².',
|
||||
},
|
||||
{
|
||||
number: 5,
|
||||
question: '3x² − 12 를 인수분해하면?',
|
||||
choices: ['3(x²−4)', '3(x−2)(x+2)', '(3x−6)(x+2)', '3(x+2)²', '(x−2)(3x+6)'],
|
||||
answer: 2,
|
||||
explanation: '공통인수 3을 묶은 후 합차 공식: 3(x²−4) = 3(x−2)(x+2).',
|
||||
},
|
||||
|
||||
// ── 이차방정식 (6~10) ─────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 6,
|
||||
question: 'x² − 5x + 6 = 0 의 두 근의 합은?',
|
||||
choices: ['−6', '−5', '1', '5', '6'],
|
||||
answer: 4,
|
||||
explanation: '(x−2)(x−3) = 0 → x = 2 또는 x = 3. 두 근의 합 = 2 + 3 = 5. (비에타: −(−5)/1 = 5)',
|
||||
},
|
||||
{
|
||||
number: 7,
|
||||
question: 'x² − 4 = 0 의 해는?',
|
||||
choices: ['x = 2', 'x = −2', 'x = ±2', 'x = 4', 'x = ±4'],
|
||||
answer: 3,
|
||||
explanation: 'x² = 4. x = ±√4 = ±2.',
|
||||
},
|
||||
{
|
||||
number: 8,
|
||||
question: '이차방정식 x² + 2x − 8 = 0 의 두 근 중 큰 값은?',
|
||||
choices: ['−4', '−2', '2', '4', '8'],
|
||||
answer: 3,
|
||||
explanation: '(x+4)(x−2) = 0 → x = −4 또는 x = 2. 큰 값은 2.',
|
||||
},
|
||||
{
|
||||
number: 9,
|
||||
question: '근의 공식을 이용해 2x² − 3x − 2 = 0 을 풀면 해는?',
|
||||
choices: ['x = 2 또는 x = −1/2', 'x = 1 또는 x = −2', 'x = 3 또는 x = −1', 'x = 2 또는 x = 1', 'x = −2 또는 x = 1/2'],
|
||||
answer: 1,
|
||||
explanation: 'x = (3 ± √(9+16)) / 4 = (3 ± 5) / 4. x = 8/4 = 2 또는 x = −2/4 = −1/2.',
|
||||
},
|
||||
{
|
||||
number: 10,
|
||||
question: '판별식 D = b² − 4ac 에서 D > 0이면 이차방정식의 근의 개수는?',
|
||||
choices: ['0개(허수)', '1개(중근)', '2개(서로 다른 실근)', '무한개', '판단 불가'],
|
||||
answer: 3,
|
||||
explanation: 'D > 0이면 서로 다른 두 실근, D = 0이면 중근(1개), D < 0이면 실근 없음.',
|
||||
},
|
||||
|
||||
// ── 이차함수 (11~15) ──────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 11,
|
||||
question: 'y = x² − 4x + 3 의 꼭짓점 좌표는?',
|
||||
choices: ['(2, −1)', '(−2, 1)', '(4, 3)', '(2, 1)', '(−4, 3)'],
|
||||
answer: 1,
|
||||
explanation: 'y = (x−2)² − 1로 변형. 꼭짓점은 (2, −1).',
|
||||
},
|
||||
{
|
||||
number: 12,
|
||||
question: 'y = −(x − 1)² + 4 의 최댓값은?',
|
||||
choices: ['−4', '−1', '1', '4', '5'],
|
||||
answer: 4,
|
||||
explanation: '위로 볼록 포물선. 꼭짓점 (1, 4)에서 최댓값 = 4.',
|
||||
},
|
||||
{
|
||||
number: 13,
|
||||
question: 'y = 2x² 의 그래프의 특징으로 옳은 것은?',
|
||||
choices: [
|
||||
'아래로 볼록, 꼭짓점 (0,0)',
|
||||
'위로 볼록, 꼭짓점 (0,0)',
|
||||
'아래로 볼록, 꼭짓점 (2,0)',
|
||||
'y = x²보다 폭이 넓다',
|
||||
'기울기가 2인 직선',
|
||||
],
|
||||
answer: 1,
|
||||
explanation: 'a = 2 > 0이므로 아래로 볼록, 꼭짓점은 (0, 0). a의 절댓값이 클수록 폭이 좁다.',
|
||||
},
|
||||
{
|
||||
number: 14,
|
||||
question: 'y = x² + 2x − 3 의 x 절편의 개수는?',
|
||||
choices: ['0', '1', '2', '3', '무한'],
|
||||
answer: 3,
|
||||
explanation: 'x² + 2x − 3 = (x+3)(x−1) = 0 → x = −3 또는 x = 1. x 절편 2개.',
|
||||
},
|
||||
{
|
||||
number: 15,
|
||||
question: 'y = a(x−p)² + q 에서 꼭짓점이 (3, −2)이고 a = 1이면 이 함수의 식은?',
|
||||
choices: [
|
||||
'y = (x+3)² − 2',
|
||||
'y = (x−3)² + 2',
|
||||
'y = (x−3)² − 2',
|
||||
'y = (x+3)² + 2',
|
||||
'y = (x−2)² − 3',
|
||||
],
|
||||
answer: 3,
|
||||
explanation: 'y = a(x−p)² + q에 a=1, p=3, q=−2를 대입하면 y = (x−3)² − 2.',
|
||||
},
|
||||
|
||||
// ── 피타고라스 / 삼각비 (16~22) ──────────────────────────────────────────────
|
||||
{
|
||||
number: 16,
|
||||
question: '직각삼각형에서 두 다리가 5, 12일 때 빗변은?',
|
||||
choices: ['10', '11', '13', '14', '15'],
|
||||
answer: 3,
|
||||
explanation: '5² + 12² = 25 + 144 = 169 = 13². 빗변 = 13.',
|
||||
},
|
||||
{
|
||||
number: 17,
|
||||
question: '빗변이 10, 한 다리가 6인 직각삼각형에서 나머지 다리의 길이는?',
|
||||
choices: ['4', '6', '7', '8', '9'],
|
||||
answer: 4,
|
||||
explanation: '6² + b² = 10² → 36 + b² = 100 → b² = 64 → b = 8.',
|
||||
},
|
||||
{
|
||||
number: 18,
|
||||
question: '직각삼각형에서 각 A의 맞은편 변이 3, 빗변이 5이면 sin A는?',
|
||||
choices: ['3/5', '4/5', '3/4', '5/3', '5/4'],
|
||||
answer: 1,
|
||||
explanation: 'sin = (맞은편 변) / (빗변) = 3/5.',
|
||||
},
|
||||
{
|
||||
number: 19,
|
||||
question: '각 B에서 인접변이 4, 빗변이 5이면 cos B는?',
|
||||
choices: ['3/5', '4/5', '3/4', '5/4', '5/3'],
|
||||
answer: 2,
|
||||
explanation: 'cos = (인접변) / (빗변) = 4/5.',
|
||||
},
|
||||
{
|
||||
number: 20,
|
||||
question: 'tan 30° 의 값은?',
|
||||
choices: ['√3', '1/√3 (= √3/3)', '√2/2', '1', '√3/2'],
|
||||
answer: 2,
|
||||
explanation: 'tan 30° = sin 30° / cos 30° = (1/2) / (√3/2) = 1/√3 = √3/3.',
|
||||
},
|
||||
{
|
||||
number: 21,
|
||||
question: 'sin 45° 의 값은?',
|
||||
choices: ['1/2', '√2/2', '√3/2', '1', '√2'],
|
||||
answer: 2,
|
||||
explanation: '45-45-90 삼각형에서 sin 45° = 1/√2 = √2/2.',
|
||||
},
|
||||
{
|
||||
number: 22,
|
||||
question: '각 C = 90°인 직각삼각형에서 tan A = 4/3이면 sin A는? (빗변 = 5 기준)',
|
||||
choices: ['3/5', '4/5', '3/4', '4/3', '5/4'],
|
||||
answer: 2,
|
||||
explanation: 'tan A = 맞은편/인접 = 4/3. 빗변 = √(4²+3²) = 5. sin A = 4/5.',
|
||||
},
|
||||
|
||||
// ── 원의 성질 (23~30) ─────────────────────────────────────────────────────────
|
||||
{
|
||||
number: 23,
|
||||
question: '중심각이 60°인 부채꼴에서 같은 원 위의 원주각의 크기는?',
|
||||
choices: ['15°', '30°', '60°', '90°', '120°'],
|
||||
answer: 2,
|
||||
explanation: '원주각 = 중심각 / 2. 60° / 2 = 30°.',
|
||||
},
|
||||
{
|
||||
number: 24,
|
||||
question: '반지름 6 cm인 원에서 중심각 90°인 부채꼴의 호의 길이는?',
|
||||
choices: ['2π cm', '3π cm', '4π cm', '6π cm', '9π cm'],
|
||||
answer: 2,
|
||||
explanation: '호의 길이 = 2πr × (중심각/360°) = 2π × 6 × (90/360) = 12π × 1/4 = 3π cm.',
|
||||
},
|
||||
{
|
||||
number: 25,
|
||||
question: '원에서 원주각이 같은 호에 대해 원주각의 크기는?',
|
||||
choices: ['호의 길이에 비례', '항상 같다', '중심각의 2배', '중심각과 같다', '호의 길이와 무관'],
|
||||
answer: 2,
|
||||
explanation: '같은 호에 대한 원주각은 모두 같다(원주각의 크기 일정성).',
|
||||
},
|
||||
{
|
||||
number: 26,
|
||||
question: '원에 내접하는 사각형에서 마주보는 두 각의 합은?',
|
||||
choices: ['90°', '120°', '180°', '270°', '360°'],
|
||||
answer: 3,
|
||||
explanation: '원에 내접하는 사각형(원내접 사각형)에서 대각의 합 = 180°.',
|
||||
},
|
||||
{
|
||||
number: 27,
|
||||
question: '원의 접선과 현이 이루는 각(접선-현의 각)의 크기는 그 현에 대한?',
|
||||
choices: ['중심각과 같다', '원주각과 같다', '원주각의 2배', '중심각의 절반', '접선의 길이와 같다'],
|
||||
answer: 2,
|
||||
explanation: '접선과 현의 각(접현각) = 그 현이 대하는 원주각. 접선-현의 각 정리.',
|
||||
},
|
||||
{
|
||||
number: 28,
|
||||
question: '두 원이 외부에서 접할 때 공통 접선의 개수는?',
|
||||
choices: ['1', '2', '3', '4', '0'],
|
||||
answer: 3,
|
||||
explanation: '두 원이 외접(외부에서 접)할 때 공통 접선은 3개(외부 공통 접선 2 + 내부 공통 접선 1).',
|
||||
},
|
||||
{
|
||||
number: 29,
|
||||
question: '원의 중심으로부터 현까지의 수선은 현을 어떻게 나누는가?',
|
||||
choices: ['1:2로', '2:1로', '이등분한다', '황금비로', '나누지 않는다'],
|
||||
answer: 3,
|
||||
explanation: '원의 중심에서 현에 내린 수선은 현을 이등분한다(원과 현의 성질).',
|
||||
},
|
||||
{
|
||||
number: 30,
|
||||
question: '반지름 5 cm인 원에서 반지름에 수직인 현의 길이가 8 cm이면 중심에서 현까지의 거리는?',
|
||||
choices: ['2 cm', '3 cm', '4 cm', '5 cm', '6 cm'],
|
||||
answer: 2,
|
||||
explanation: '현의 절반 = 4 cm. 피타고라스: 5² = 4² + d² → d² = 9 → d = 3 cm.',
|
||||
},
|
||||
];
|
||||
7
frontend/src/app/exams/sample-ebook/data/types.ts
Normal file
7
frontend/src/app/exams/sample-ebook/data/types.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
export interface SampleProblem {
|
||||
number: number;
|
||||
question: string;
|
||||
choices: string[];
|
||||
answer: number; // 1-based
|
||||
explanation: string;
|
||||
}
|
||||
Reference in New Issue
Block a user