JSFiddle - React, Tailwind, and code Playground

HTML

<script src="https://cdn.jsdelivr.net/lodash/4.13.1/lodash.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<div class="container" ng-app="app" ng-controller="MemberCtrl">
  <h2>
  자, 어디 한번 짝을 정해 볼까요
  </h2>
  <label>구역 목록 (총원 {{total}})</label>
  <div ng-repeat="(i, member) in members track by $index">
    <input class="full" ng-model="members[i]">
  </div>

  <button class="btn btn-info btn-sm pull-right" ng-click="show()">
    보여줘요!</button>
  <br>
  <br>
  <ul>
    <div ng-repeat="pair in pairs">
      <label>{{ $index+1 }}:</label> <span>{{ pair[0] }}, {{ pair[1] }}</span>
    </div>
  </ul>
</div>

CSS

.full {
  width: 100%;
  margin-bottom: 5px;
}

JavaScript

const membersMap = [
  ['유다슬', '황지우', '강형수', '정지민'],	// '안주현', '배주현'
  ['양승희', '고은영', '남궁동'],	// '지민혁', '유서영', '송범수'
  ['김태은', '강재우', '안성은', '송은용'],	// '이지연', '배평곤', '김성준', '임흥섭'
  ['유희준', '류예림', '유재헌', '이승래'], // '지재원', '이윤하', '송현석', '진영지', '최일성'
  ['장현정', '성경민', '서명헌', '김선효', '정혜원'], // '안형률', '소정민', '최지원'
  ['이의경', '신성은', '김선홍', '정지웅'], // '박채은', '우제희', '최성욱'
  ['최다정', '구혜경', '김사강'],	// '정종현', '전상욱', '전소영', '정다움', '천수빈', '김민호', '국혜근'
  ['현정인', '박성일', '김민강', '정은영', '원성현'],	// '조담비', '진연지', '박가람'
  ['강찬희', '현세인', '김세민', '우제헌'], // '유선영', '김소영', '박수빈', '양유진'
  ['신예은', '주영선', '엄영신'], // '배은희', '유지훈', '김대원', '임정섭'
  [ '박성현']
];

function getPairs(mapped) {
	const reduced = mapped.reduce((members, group) => members.concat(group));
  const members = mapped.length > 15 ? mapped : reduced;
  const half = Math.round(members.length / 2);
  // 1. 멤버 전체 섞고
  // 2. 반 이하 멤버가 반+idx 로 선택

  const random = _.shuffle(_.range(members.length)).map(idx => members[idx]);

  let i = 0;
  return _.times(half, () => [random[i], random[half + i++]]);
}

function MemberCtrl($scope) {
  $scope.members = membersMap.map(member => member.join(' '));
  $scope.pairs = getPairs(membersMap);
  $scope.total = _.sumBy(membersMap, _.size);

  $scope.show = function() {
    var dataFromView = $scope.members.join(' ').split(' ');
    var adjusted = _.reject(dataFromView,
      _.partial(_.isEqual, ''));

    $scope.total = adjusted.length;
    $scope.pairs = getPairs(adjusted);
  };
}

angular.module('app', []).controller('MemberCtrl', MemberCtrl);