JJuOn

Implement problem recommendation algorithm

......@@ -3,5 +3,6 @@ const session = new Router();
const sessionCtrl = require('./session.ctrl');
session.post("/createproblem/:how",sessionCtrl.createProblem);
session.get("/status",sessionCtrl.status);
module.exports = session;
\ No newline at end of file
......
const axios = require("axios");
const Participation = require("../../models/participation");
const Session = require("../../models/session");
const Group = require("../../models/group");
const User = require("../../models/user");
const Challenge = require("../../models/challenge");
const Problem = require("../../models/problem");
const mongoose = require("mongoose");
const {ObjectId} = mongoose.Types;
/* POST /api/session/createproblem/:how
{
sessionId: ObjectId,
groupId: ObjectId,
problemList:[Number],
sessionId: ObjectId or String,
groupId: ObjectId or String,
problemList:[Number], (optional)
}
*/
exports.createProblem = async (ctx)=>{
......@@ -25,15 +28,20 @@ exports.createProblem = async (ctx)=>{
if(typeof(problemList)==='string'){
problemList=JSON.parse(problemList);
}
const session = await Session.findById(sessionId);
const challengeId = session['challengeId'];
const challenge = await Challenge.findById(challengeId);
const goalPerSession = challenge['goalPerSession'];
const participation = await Participation.findOne({sessionId:sessionId,groupId:groupId});
const group = await Group.findById(groupId);
const how=ctx.params.how;
if(how==='self'){
if(problemList.length!==goalPerSession){
ctx.throw(400,'문제 수가 맞지 않습니다.');
}
let check = true;
for(let i=0;i<group.members.length;i++){
const user = await User.findById(group.members[i]);
console.log(user);
console.log(typeof(user.solvedBJ_date.solvedBJbyDATE));
let userProblemList = [];
for(let key in user.solvedBJ_date.solvedBJbyDATE){
userProblemList.push(user.solvedBJ_date.solvedBJbyDATE[key]);
......@@ -47,7 +55,7 @@ exports.createProblem = async (ctx)=>{
}
}
if(!check){
ctx.throw('그룹원이 이미 푼 문제는 등록할 수 없습니다.');
ctx.throw(400,'그룹원이 이미 푼 문제는 등록할 수 없습니다.');
return;
}
else{
......@@ -56,10 +64,72 @@ exports.createProblem = async (ctx)=>{
}
}
else if(how==='recommend'){
//TODO
let groupProblemList=[];
let selectedProblemList=[];
for(let i=0;i<group.members.length;i++){
const user = await User.findById(group.members[i]);
for(let key in user.solvedBJ_date.solvedBJbyDATE){
groupProblemList.push(user.solvedBJ_date.solvedBJbyDATE[key]);
}
}
groupProblemList=groupProblemList.flat().sort((a,b)=>new Date(b.solvedDate)-new Date(a.solvedDate)).map(elem=>elem.problem_number);
groupProblemList=groupProblemList.filter((x,i)=>groupProblemList.indexOf(x)===i);
console.log(groupProblemList);
const problems=await Problem.find({}).sort({count:-1});
console.log(problems);
console.log(goalPerSession);
for(let i=0;i<problems.length;i++){
if(!groupProblemList.includes(String(problems[i].problemNum))){
selectedProblemList.push(String(problems[i].problemNum));
}
if(selectedProblemList.length===goalPerSession || i/problems.length >= 0.75){
break;
}
}
for(let i=0; i<groupProblemList.length && selectedProblemList.length < goalPerSession; i++){
const p = await Problem.findOne({problemNum:groupProblemList[i]});
if( Number(p.solvedacLevel)< 1 || Number(p.solvedacLevel)>30 ){
continue;
}
const body = await axios.get(`https://api.solved.ac/v2/search/problems.json?query=solvable:true+tier:${p.solvedacLevel}&page=1&sort=solved&sort_direction=desc`);
let data = body.data;
if(typeof(data)==='string'){
data=JSON.parse(data);
}
for(let j=0;j<data.result.problems.length;j++){
if(!groupProblemList.includes(data.result.problems[j].id)){
selectedProblemList.push(data.result.problems[j].id.toString());
break;
}
}
}
selectedProblemList.map(async problemNum=>await participation.addProblem({problemNum:problemNum,isSolved:false}));
ctx.body=participation.serialize();
}
}
catch(e){
console.error(e);
ctx.throw(500,e);
}
};
// GET /api/session/status?sessionId&groupId
exports.status=async (ctx)=>{
try{
let {sessionId,groupId}=ctx.request.query;
if(typeof(sessionId)==='string'){
sessionId=new ObjectId(sessionId);
}
if(typeof(groupId)==='string'){
groupId=new ObjectId(groupId);
}
const participation=await Participation.findOne({sessionId:sessionId,groupId:groupId});
const group = await Group.findById(groupId);
}
catch(e){
ctx.throw(500,e);
}
}
\ No newline at end of file
......