2026년 9월 7일 월요일

[음악·체육] 다면 제약 기반 모둠 협동학습 & 악기 파트 최적 편성기



사이 안 좋은 친구끼리 모이지 않게 — '다면 제약 조건 기반 모둠 협동학습 & 악기 파트 최적 편성기'

🎵 초등 음악·체육 융합 및 협동학습 — 리코더·단소 앙상블이나 체육 기계체조 모둠 활동 시, 학생들의 연주·신체 역량(상/중/하)을 모둠마다 골고루 1명씩 분배하고, 사이가 좋지 않은 학생은 서로 다른 모둠으로 자동 분리하는 융합 편성 도구입니다. 교사의 주관적 편향 없이 공정하고 균형 잡힌 협동학습 모둠을 1초 만에 만듭니다.

📖 한 줄 정의

심기 모드(데이터 임베딩): API 데이터를 미리 받아 HTML 파일 안 상수로 박아두는 방식(앱 실행 중 외부 통신 0).

학내망 원칙: 학생 개인정보(실명·의견·성적·상담 기록)의 외부 수집·저장·전송 금지(쿼리에 학생 데이터가 담기는 외부 API 호출 포함) — 일반 공개 쿼리의 외부 호출은 허용하며, 학생 배포본은 심기 폴백(EMBED 상수)을 항상 내장한다.

1. 3대 핵심 분석 비교표

무엇이 바뀌었나요? / 영역 초보자를 위한 쉬운 설명 이렇게 한번 써보세요!
역량 상/중/하 균형 배분 연주력이 '상'인 학생, '중'인 학생, '하'인 학생을 각 모둠마다 1명씩 골고루 분배하여 앙상블 역량이 평균화되도록 만듭니다. 연주 역량 분포표를 상수에 넣고 1클릭 자동 배분.
모둠 분리 조건(Separate Constraint) 사이가 좋지 않아 함께하기 어려운 학생 2인을 서로 다른 모둠에 자동 배치합니다. 분리 대상 닉네임 목록을 상수에 넣으면 알고리즘으로 자동 처리.
악기 파트 최적 배분 리코더, 단소, 우치, 타악 4개 파트를 각 모둠에 고르게 분배하여 앙상블 밸런스를 자동 맞춥니다. 파트 정보를 입력하면 학생별 악기 부여가 알고리즘으로 자동 결정.

2. 핵심 아키텍처 해설

① 학생 데이터 및 분리 조건 상수

const STUDENTS = [
  { no: 1, nick: "코알라", skill: "상", part: "리코더" },
  { no: 2, nick: "돌고래", skill: "중", part: "단소" },
  { no: 3, nick: "여우", skill: "하", part: "타악" },
  { no: 4, nick: "토끼", skill: "중", part: "우치" }
];

const SEPARATE_PAIRS = [
  [1, 3], // 번호 1과 3은 서로 다른 모둠으로
  [2, 4]
];

학생별 역량(상/중/하)과 악기 파트 정보, 그리고 분리 대상 조합을 상수로 심어둡니다.

② 조건 만족 배분(Constraint Satisfaction) 알고리즘

function assignGroups(students, separatePairs, groupCount) {
  const groups = [];
  for (let i = 0; i < groupCount; i++) groups.push([]);
  const sorted = students.slice().sort((a, b) => rank(b.skill) - rank(a.skill));

  sorted.forEach(stu => {
    for (let gi = 0; gi < groupCount; gi++) {
      const g = groups[gi];
      const hasSeparate = g.some(m =>
        separatePairs.some(([a, b]) =>
          (a === stu.no && b === m.no) || (b === stu.no && a === m.no)
        )
      );
      if (!hasSeparate && !g.some(m => m.skill === stu.skill)) {
        g.push(stu);
        return;
      }
    }
    // 모든 모둠이 제약에 걸리면 마지막으로 넣음
    groups[sorted.length % groupCount].push(stu);
  });
  return groups;
}

function rank(skill) {
  return { "상": 3, "중": 2, "하": 1 }[skill] || 0;
}

역량이 높은 학생부터 순서대로, 각 모둠에 같은 역량이 없고 분리 조건에 걸리지 않는 모둠을 탐색하여 배정합니다.

③ 편성 결과 시각화 테이블

편성 완료 후 모둠 1~4개 테이블이 색상 라벨 카드로 표시되며, 학생별 닉네임·역량 뱃지·악기 파트가 함께 표시됩니다. 관찰 후 'CSV 내보내기' 버튼으로 결과를 학급 문집에 기록할 수 있습니다.

3. 초보자를 위한 바이브 코딩 실전 사용 예시

  1. 프롬프트 복사 — 아래 '제미나이 전용 에러 제로 프롬프트'를 복사합니다.
  2. 역질문 답변 — 제미나이가 묻는 모둠 수(4개)와 역량 분포에 답합니다.
  3. HTML 파일 실행 — 메모장에 붙여넣고 모둠편성기.html로 저장하여 음악실 태블릿에서 엽니다.

제미나이 전용 에러 제로 프롬프트

[🚨 에러 방지 기본 안전장치]
1. 단일 HTML 파일 완결성: 외부 라이브러리(CDN), 백엔드 서버 없이 순수 바닐라 HTML/CSS/JS로 완성한다.
2. 심기 모드(데이터 임베딩): const STUDENTS = [...] 상수에 학생 닉네임·역량·악기 파트 정보를 내장하고, 별도 fetch 없이 브라우저에서 즉시 실행되도록 한다.
3. 제약 만족 알고리즘: 역량(상/중/하) 균형 배분 + 분리 조건(사이가 나쁜 조합) 자동 분리 + 악기 파트 고르게 분배를 동시에 만족하는 조건 만족(Constraint Satisfaction) 알고리즘을 구현한다.
4. 개인정보 최소 수집: 학생 실명을 사용하지 않고 닉네임과 번호만 취급하며, 브라우저 세션 메모리로만 유지한다.
5. // TODO, /* 생략 */ 등의 미완성 코드는 절대 넣지 말고 끝까지 완성한다.

[❓ 역질문 유도]
코드를 즉시 작성하지 말고, 아래 3가지 질문을 먼저 나에게 던져줘:
1. 모둠은 몇 개로 나눌까요? (4개 기본)
2. 악기 파트는 리코더·단소·우치·타악 4종으로 할까요?
3. 편성 결과를 화면에 색상 라벨 카드로 띄울까요, 아니면 표 형태로 갈까요?

🎯 에디터 한줄평

"'왜 내가 이 모둠인데요?'라는 질문을 소리치던 교실에서, 알고리즘이 내준 결과는 오해가 아니라 논리로 승부합니다. 분리 조건을 코드로 명시하는 순간, 교사는 편향이 아닌 과학적 배려로 학생의 배움 환경을 설계하는 전문가가 됩니다."

📚 기술·교육 참고 링크

  • 교육부 협동학습 모둠 편성 가이드라인 및 초등 음악 앙상블 지도법
  • 교육과정 연계: 초등 3~6학년 음악(합주·기악 연주), 체육(기계체조 협동 활동), 수학(조합 문제)