Created
September 17, 2018 07:46
-
-
Save Jehong-Ahn/e07e50fdb08f5285fbcda43c717d2cb1 to your computer and use it in GitHub Desktop.
조편성 프로그램
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var sheet = SpreadsheetApp.getActiveSheet(); | |
var room = ""; | |
var token = ""; | |
var sheetUrl = ""; | |
function chatClear() { | |
clear(); | |
chat( | |
"오늘은 런치미팅을 진행합니다.\n" | |
+ "12시 30분까지 아래 시트에 부재사유 및 추가인원을 기입하여 주십시오.\n" | |
+ sheetUrl | |
); | |
} | |
function chatGenerate() { | |
var groups = generate(); | |
var [i, msg] = groups.reduce(function([i, msg], group) { | |
msg += ++i + "조: "; | |
msg += group.map(function(row) { return row[1]; }).join(", ") + "\n"; | |
return [i, msg]; | |
}, [0, "오늘의 런치미팅 조를 발표합니다.\n"]); | |
chat(msg); | |
} | |
function clear() { | |
var range = sheet.getRange(2, 5, sheet.getLastRow()); | |
range.clear(); | |
} | |
function chat(msg) { | |
var res = UrlFetchApp.fetch( | |
'https://api.chatwork.com/v2/rooms/'+room+'/messages', | |
{ | |
method: 'POST', | |
payload: 'body=' + msg, | |
headers: { 'X-ChatWorkToken': token }, | |
} | |
); | |
} | |
function generate() { | |
var rows = sheet.getDataRange().getValues(); | |
var groups = []; | |
function _partition(isValid, assign) { | |
rows = rows.reduce(function(remains, row) { | |
if (isValid(row)) assign(row); | |
else remains.push(row); | |
return remains; | |
}, []); | |
} | |
// 헤더 제거 | |
rows.shift(); | |
// 부재자 제외 | |
rows = rows.filter(function(row) { return row[4]===''; }); | |
var total = rows.length; | |
// 임원, 팀장 기준으로 조 편성 | |
_partition(function(row) { | |
return ( row[0]==="임원" || ["팀장", "수석"].indexOf(row[2])>-1 ); | |
}, function(row) { | |
groups.push([row]); | |
}); | |
// 일본어만 가능한 사람을 배치 | |
_partition(function(row) { | |
return row[3]==="일본어만"; | |
}, function(row) { | |
groups[_getRandomInt(groups.length)].push(row); | |
}); | |
// 일본어 가능한 사람을 배치 | |
_partition(function(row) { | |
return row[3]==="일본어 가능"; | |
}, function(row) { | |
var i = groups.findIndex(function(group) { | |
return group.findIndex(function(row) { return row[3]==="일본어만"; }) > -1 | |
&& group.findIndex(function(row) { return row[3]==="일본어 가능"; }) === -1; | |
}); | |
groups[( i>-1 ? i : _getRandomInt(groups.length))].push(row); | |
}); | |
// 인원수 적은 순서대로 정렬 | |
groups.sort(function(a,b) { | |
return a.length - b.length; | |
}); | |
// 남은 인원을 배치 (인원수 적은 그룹에 우선 배치) | |
// Logger.log(total +' '+ groups.length +' '+ Math.ceil(total/groups.length)); | |
for(var i=1; i<=Math.ceil(total/groups.length); i++) { | |
for(var j=0; j<groups.length; j++) { | |
var group = groups[j]; | |
if (i!==group.length) break; | |
var rand = _getRandomInt(rows.length); | |
group.push(rows[rand]); | |
rows.splice(rand, 1); | |
if (rows.length===0) break; | |
} | |
if (rows.length===0) break; | |
} | |
// groups.forEach(function(group) { Logger.log(group); }) | |
// Logger.log(rows); | |
return groups; | |
} | |
function _getRandomInt(max) { | |
return Math.floor(Math.random() * Math.floor(max)); | |
} | |
// https://tc39.github.io/ecma262/#sec-array.prototype.findIndex | |
if (!Array.prototype.findIndex) { | |
Object.defineProperty(Array.prototype, 'findIndex', { | |
value: function(predicate) { | |
// 1. Let O be ? ToObject(this value). | |
if (this == null) { | |
throw new TypeError('"this" is null or not defined'); | |
} | |
var o = Object(this); | |
// 2. Let len be ? ToLength(? Get(O, "length")). | |
var len = o.length >>> 0; | |
// 3. If IsCallable(predicate) is false, throw a TypeError exception. | |
if (typeof predicate !== 'function') { | |
throw new TypeError('predicate must be a function'); | |
} | |
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined. | |
var thisArg = arguments[1]; | |
// 5. Let k be 0. | |
var k = 0; | |
// 6. Repeat, while k < len | |
while (k < len) { | |
// a. Let Pk be ! ToString(k). | |
// b. Let kValue be ? Get(O, Pk). | |
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)). | |
// d. If testResult is true, return k. | |
var kValue = o[k]; | |
if (predicate.call(thisArg, kValue, k, o)) { | |
return k; | |
} | |
// e. Increase k by 1. | |
k++; | |
} | |
// 7. Return -1. | |
return -1; | |
}, | |
configurable: true, | |
writable: true | |
}); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment