Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public void createAttendance() {
Attendance attendance = Attendance.builder()
.studyMember(studyMember)
.week(lastWeek)
.problemYN(getProblemYN(lastWeek, studyMember, requestCount - solvedWorkbookCount))
.problemYN(getProblemYN(lastWeek, studyMember, requestCount - Math.min(WORKBOOK_MIN_REQUEST_COUNT, solvedWorkbookCount)))
.blogYN(attendanceRequestYn && StringUtils.hasText(optionalAttendanceRequest.get().getBlogUrl()))
.workbookYN(solvedWorkbookCount >= WORKBOOK_MIN_REQUEST_COUNT)
.build();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package org.example.domain.workbook.service;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import java.util.Set;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.example.api_response.exception.GeneralException;
import org.example.api_response.status.ErrorStatus;
Expand Down Expand Up @@ -111,36 +114,91 @@ private List<Problem> createBasicWorkbook(Week week) {
* 코딩테스트 심화반
*/
private List<Problem> createPrepareWorkbook(Week week, Long studyId) {
List<ListAttendanceDto> studyMemberList = listStudyMemberRepository.getStudyMemberList(studyId);
final int MAX_MEMBER_PER_QUERY = 10;
int queryCount = (int) Math.ceil((double) studyMemberList.size() / MAX_MEMBER_PER_QUERY);

// 난이도 설정 쿼리
String silverQuery = "*s4..s1 ";
String goldQuery = "*g ";

// 주차별 알고리즘 유형 설정 쿼리
StringBuilder query = new StringBuilder();
switch (week.getValue()) {
case 1 -> query.append("(#bruteforcing | #backtracking) -#dfs -#bfs");
case 2 -> query.append("#dp");
case 3 -> query.append("(#simulation | #two_pointer)");
case 4 -> query.append("(#binary_search | #prefix_sum)");
case 5 -> query.append("#data_structures");
case 6 -> query.append("(#bfs | #dfs)");
case 7 -> query.append("#dijkstra");
case 8 -> query.append("#greedy");
}
String algorithmQuery = getAlgorithmQuery(week);

// 스터디원이 푼 문제 제외 쿼리
List<ListAttendanceDto> studyMemberList = listStudyMemberRepository.getStudyMemberList(studyId);
studyMemberList.forEach(dto -> query.append(" -s@").append(dto.getHandle()));
List<StringBuilder> queryList = new ArrayList<>();
for (int count = 0; count < queryCount; count++) {
queryList.add(new StringBuilder(algorithmQuery));
for (int i = 0; i < MAX_MEMBER_PER_QUERY; i++) {
int idx = count * MAX_MEMBER_PER_QUERY + i;
if (idx >= studyMemberList.size()) break;

queryList.get(count).append(" -s@").append(studyMemberList.get(idx));
}
}

// solved.ac 요청
ProblemResponse silverProblemResponse = solvedAcClient.searchProblems(1, silverQuery + query, SORT, DIRECTION);
ProblemResponse goldProblemResponse = solvedAcClient.searchProblems(1, goldQuery + query, SORT, DIRECTION);

List<Integer> problemNumberList = Stream.concat(
silverProblemResponse.getProblemList().stream().limit(3),
goldProblemResponse.getProblemList().stream().limit(3)
).map(ProblemDto::getNumber).toList();
return problemRepository.findAllById(problemNumberList);
List<Set<Integer>> silverProblemSetList = new ArrayList<>();
List<Set<Integer>> goldProblemSetList = new ArrayList<>();
for (int count = 0; count < queryCount; count++) {
ProblemResponse silverProblemResponsePage1 = solvedAcClient.searchProblems(1, silverQuery + queryList.get(count), SORT, DIRECTION);
ProblemResponse silverProblemResponsePage2 = solvedAcClient.searchProblems(2, silverQuery + queryList.get(count), SORT, DIRECTION);
ProblemResponse goldProblemResponsePage1 = solvedAcClient.searchProblems(1, goldQuery + queryList.get(count), SORT, DIRECTION);
ProblemResponse goldProblemResponsePage2 = solvedAcClient.searchProblems(2, goldQuery + queryList.get(count), SORT, DIRECTION);

Set<Integer> silverPage1 = silverProblemResponsePage1.getProblemList().stream().map(ProblemDto::getNumber)
.collect(Collectors.toCollection(LinkedHashSet::new));
Set<Integer> silverPage2 = silverProblemResponsePage2.getProblemList().stream().map(ProblemDto::getNumber)
.collect(Collectors.toCollection(LinkedHashSet::new));
Set<Integer> goldPage1 = goldProblemResponsePage1.getProblemList().stream().map(ProblemDto::getNumber)
.collect(Collectors.toCollection(LinkedHashSet::new));
Set<Integer> goldPage2 = goldProblemResponsePage2.getProblemList().stream().map(ProblemDto::getNumber)
.collect(Collectors.toCollection(LinkedHashSet::new));

Set<Integer> silverProblemSet = new LinkedHashSet<>();
silverProblemSet.addAll(silverPage1);
silverProblemSet.addAll(silverPage2);
silverProblemSetList.add(silverProblemSet);

Set<Integer> goldProblemSet = new LinkedHashSet<>();
goldProblemSet.addAll(goldPage1);
goldProblemSet.addAll(goldPage2);
goldProblemSetList.add(goldProblemSet);
}

List<Integer> result = new ArrayList<>();
if (!silverProblemSetList.isEmpty()) {
Set<Integer> silverResultSet = new LinkedHashSet<>(silverProblemSetList.get(0));
for (int i = 1; i < silverProblemSetList.size(); i++) {
silverResultSet.retainAll(silverProblemSetList.get(i));
}
result.addAll(silverResultSet.stream().limit(3).toList());
}

if (!goldProblemSetList.isEmpty()) {
Set<Integer> goldResultSet = new LinkedHashSet<>(goldProblemSetList.get(0));
for (int i = 1; i < goldProblemSetList.size(); i++) {
goldResultSet.retainAll(goldProblemSetList.get(i));
}
result.addAll(goldResultSet.stream().limit(3).toList());
}

return problemRepository.findAllById(result);
}

private String getAlgorithmQuery(Week week) {
String algorithmQuery = "";
switch (week.getValue()) {
case 1 -> algorithmQuery = "(#bruteforcing | #backtracking) -#dfs -#bfs";
case 2 -> algorithmQuery = "#dp";
case 3 -> algorithmQuery = "(#simulation | #two_pointer)";
case 4 -> algorithmQuery = "(#binary_search | #prefix_sum)";
case 5 -> algorithmQuery = "#data_structures";
case 6 -> algorithmQuery = "(#bfs | #dfs)";
case 7 -> algorithmQuery = "#dijkstra";
case 8 -> algorithmQuery = "#greedy";
}
return algorithmQuery;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
package org.example.domain.attendance.service;

import static org.junit.jupiter.api.Assertions.*;

import java.time.Duration;
import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.util.List;
import org.example.util.http_request.Url;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(properties = "spring.profiles.active=test")
class CreateAttendanceServiceTest {

@Autowired
WebDriver webDriver;
@Autowired
Actions actions;

@Test
void 저번주에_푼_문제수() {

// 페이지 랜딩 대기
webDriver.get(Url.BAEKJOON_USER.getBaekjoonUserUrl("engus525"));
new WebDriverWait(webDriver, Duration.ofSeconds(10))
.until(ExpectedConditions.presenceOfElementLocated(By.tagName("rect")));
List<WebElement> rectList = webDriver.findElements(By.tagName("rect"));

// 지난주 범위 계산
LocalDate today = LocalDate.now().minusDays(7);
LocalDate lastYear = today.minusYears(1);
int startRect = today.getDayOfYear()
- LocalDate.now().get(ChronoField.DAY_OF_WEEK) + 1;
if (rectList.size() >= 2 * 365) {
if (lastYear.isLeapYear()) startRect += 365 + 1;
else startRect += 365;
}
int lastRect = startRect + 6;

int count = 0;
for (int i = startRect; i <= lastRect; i++) {
rectList = webDriver.findElements(By.tagName("rect"));
WebElement rect = rectList.get(i);
actions.moveToElement(rect).perform();

try {
Thread.sleep(100);
} catch (InterruptedException e) {
}
// tooltip에 기록된 해당 날짜에 푼 문제 수 추출
WebElement tooltip = webDriver.findElement(By.className("google-visualization-tooltip"));
String text = tooltip.getText();
System.out.println(text);
int colonIndex = text.indexOf(":");
if (colonIndex != -1) {
count += Integer.parseInt(text.substring(colonIndex + 1).strip());
}
}

System.out.println("문제 풀이 수 : " + count);

}


@Test
void 문제집에서_몇개_풀었는지() {

webDriver.get(Url.BAEKJOON_USER.getBaekjoonUserUrl("engus525"));

// 맞힌 문제 개수로 제한
int limitCount = Integer.parseInt(webDriver.findElement(By.id("u-solved")).getText());
List<Integer> problemNumberList = webDriver.findElements(By.cssSelector(".problem-list a"))
.stream()
.map(problemNumber -> Integer.parseInt(problemNumber.getText()))
.limit(limitCount)
.toList();

int solvedCount;
List<Integer> workbookProblemList = List.of(1446, 20168, 5972, 2151, 16118, 2307);
System.out.println(workbookProblemList.stream().filter(problemNumberList::contains).toList());
solvedCount = (int) workbookProblemList.stream().filter(problemNumberList::contains).count();

System.out.println("solvedCount = " + solvedCount);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
package org.example.domain.workbook.service;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.example.schedule.solved_ac.SolvedAcClient;
import org.example.schedule.solved_ac.response.problem.ProblemDto;
import org.example.schedule.solved_ac.response.problem.ProblemResponse;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest(properties = "spring.profiles.active=test")
public class CreateWorkbookServiceTest {

@Autowired
SolvedAcClient solvedAcClient;
private static final String SORT = "solved";
private static final String DIRECTION = "desc";



@Test
void 정규스터디_문제집생성() {

int week = 7;

String[] handle =
{"engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525",
"engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525",
"engus525", "engus525", "engus525", "engus525", "engus525", "engus525", "engus525"};

final int MAX_MEMBER_PER_QUERY = 10;
int queryCount = (int) Math.ceil((double) handle.length / MAX_MEMBER_PER_QUERY);

// 난이도 설정 쿼리
String silverQuery = "*s4..s1 ";
String goldQuery = "*g ";

// 주차별 알고리즘 유형 설정 쿼리
String algorithmQuery = getAlgorithmQuery(week);

// 스터디원이 푼 문제 제외 쿼리
List<StringBuilder> queryList = new ArrayList<>();
for (int count = 0; count < queryCount; count++) {
queryList.add(new StringBuilder(algorithmQuery));
for (int i = 0; i < MAX_MEMBER_PER_QUERY; i++) {
int idx = count * MAX_MEMBER_PER_QUERY + i;
if (idx >= handle.length) break;

queryList.get(count).append(" -s@").append(handle[idx]);
}
}

// solved.ac 요청
List<Set<Integer>> silverProblemSetList = new ArrayList<>();
List<Set<Integer>> goldProblemSetList = new ArrayList<>();
for (int count = 0; count < queryCount; count++) {

System.out.println("silverQuery + queryList.get(count) = " + silverQuery + queryList.get(count));
System.out.println("goldQuery + queryList.get(count) = " + goldQuery + queryList.get(count));
ProblemResponse silverProblemResponsePage1 = solvedAcClient.searchProblems(1, silverQuery + queryList.get(count), SORT, DIRECTION);
ProblemResponse silverProblemResponsePage2 = solvedAcClient.searchProblems(2, silverQuery + queryList.get(count), SORT, DIRECTION);
ProblemResponse goldProblemResponsePage1 = solvedAcClient.searchProblems(1, goldQuery + queryList.get(count), SORT, DIRECTION);
ProblemResponse goldProblemResponsePage2 = solvedAcClient.searchProblems(2, goldQuery + queryList.get(count), SORT, DIRECTION);

System.out.println("goldProblemResponsePage1.getProblemList() = " + goldProblemResponsePage1.getProblemList());
System.out.println("goldProblemResponsePage2.getProblemList() = " + goldProblemResponsePage2.getProblemList());
Set<Integer> silverPage1 = silverProblemResponsePage1.getProblemList().stream().map(ProblemDto::getNumber)
.collect(Collectors.toCollection(LinkedHashSet::new));
Set<Integer> silverPage2 = silverProblemResponsePage2.getProblemList().stream().map(ProblemDto::getNumber)
.collect(Collectors.toCollection(LinkedHashSet::new));
Set<Integer> goldPage1 = goldProblemResponsePage1.getProblemList().stream().map(ProblemDto::getNumber)
.collect(Collectors.toCollection(LinkedHashSet::new));
Set<Integer> goldPage2 = goldProblemResponsePage2.getProblemList().stream().map(ProblemDto::getNumber)
.collect(Collectors.toCollection(LinkedHashSet::new));

Set<Integer> silverProblemSet = new LinkedHashSet<>();
silverProblemSet.addAll(silverPage1);
silverProblemSet.addAll(silverPage2);
System.out.println("silverProblemSet = " + silverProblemSet);
silverProblemSetList.add(silverProblemSet);

Set<Integer> goldProblemSet = new LinkedHashSet<>();
goldProblemSet.addAll(goldPage1);
goldProblemSet.addAll(goldPage2);
goldProblemSetList.add(goldProblemSet);
}

List<Integer> result = new ArrayList<>();
if (!silverProblemSetList.isEmpty()) {
Set<Integer> silverResultSet = new LinkedHashSet<>(silverProblemSetList.get(0));
for (int i = 1; i < silverProblemSetList.size(); i++) {
silverResultSet.retainAll(silverProblemSetList.get(i));
}
System.out.println("silverResultSet = " + silverResultSet);
result.addAll(silverResultSet.stream().limit(3).toList());
}

if (!goldProblemSetList.isEmpty()) {
Set<Integer> goldResultSet = new LinkedHashSet<>(goldProblemSetList.get(0));
for (int i = 1; i < goldProblemSetList.size(); i++) {
goldResultSet.retainAll(goldProblemSetList.get(i));
}
result.addAll(goldResultSet.stream().limit(3).toList());
}

System.out.println(result);

}

private String getAlgorithmQuery(int week) {
String algorithmQuery = "";
switch (week) {
case 1 -> algorithmQuery = "(#bruteforcing | #backtracking) -#dfs -#bfs";
case 2 -> algorithmQuery = "#dp";
case 3 -> algorithmQuery = "(#simulation | #two_pointer)";
case 4 -> algorithmQuery = "(#binary_search | #prefix_sum)";
case 5 -> algorithmQuery = "#data_structures";
case 6 -> algorithmQuery = "(#bfs | #dfs)";
case 7 -> algorithmQuery = "#dijkstra";
case 8 -> algorithmQuery = "#greedy";
}
return algorithmQuery;
}


}
Loading