이전 1000회를 조회해서 분석하면 이렇게 된다.
왼쪽이 숫자, 우측이 당첨 횟수임
실은 독립시행이라 씰데 없는 자료지만 뭐 재미로 하는거니까 ㅋㅋ
@Service
@Slf4j
@RequiredArgsConstructor
@Transactional
public class WinNumberService {
private final WinNumberRepository winNumberRepository;
public HistoryNumber makeHistoryNumber(int count) {
Pageable pageable = PageRequest.of(0, count, Sort.Direction.DESC, "drawNo");
Page<WinNumber> find = winNumberRepository.findLastIndex(pageable);
List<WinNumber> content = find.getContent();
int[] countNumbers = new int[45];
content.stream()
.forEach(e -> {
int winNumber1 = e.getWinNumber1() - 1;
int winNumber2 = e.getWinNumber2() - 1;
int winNumber3 = e.getWinNumber3() - 1;
int winNumber4 = e.getWinNumber4() - 1;
int winNumber5 = e.getWinNumber5() - 1;
int winNumber6 = e.getWinNumber6() - 1;
countNumbers[winNumber1]++;
countNumbers[winNumber2]++;
countNumbers[winNumber3]++;
countNumbers[winNumber4]++;
countNumbers[winNumber5]++;
countNumbers[winNumber6]++;
});
int max = Arrays.stream(countNumbers).max().getAsInt();
int min = Arrays.stream(countNumbers).min().getAsInt();
int[] mostNumbers = Arrays.stream(countNumbers).filter(e -> e == max).toArray();
int[] leastNumbers = Arrays.stream(countNumbers).filter(e -> e == min).toArray();
return new HistoryNumber(mostNumbers, leastNumbers, countNumbers);
}
}
일단 모든 번호 당첨 횟수를 조회하는 걸 목표로 메서드를 만들었다.
그리고 mostNumbers나 leastNumbers를 빼려고 했는데, 저 방법엔 오류가 있음.
배열 index를 번호로 잡아놨기 때문에 (i + 1 번 번호가 X회 당첨)
mostNumbers나 leastNumbers를 저렇게 짜면 그냥 가장 많이 당첨된 횟수, 최소 당첨 횟수만 나오게 된다. fix가 필요함. 걍 map으로 할 걸 그랬나...
하튼 무식하게 저렇게 6개의 번호를 때려서 countNumbers를 HistoryNumber라는 객체에 빼준다.
@Slf4j
@Data
@NoArgsConstructor
@AllArgsConstructor
public class HistoryNumber {
int[] mostNumbers;
int[] leastNumbers;
int[] allNumbers;
}
생성자를 굳이 많이 붙일 이유가 없는데 왜 그랬을까
일단 나중에 리팩토링 하면서 지우는거로 ㅋㅋㅋ
어쨋든 변수명도 좀 마음에 안들지만 저런 친구임
@GetMapping("/search")
public String searchLottoCountCondition(Model model) {
model.addAttribute(new WinNumberSearchDto());
return "searchLotto";
}
@PostMapping("/search")
public String searchLottoCount(@Valid WinNumberSearchDto winNumberSearchDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
// 에러 처리
}
HistoryNumber historyNumber = winNumberService.makeHistoryNumber(winNumberSearchDto.getCount());
model.addAttribute("result", historyNumber);
return "winCount";
}
메서드를 활용하기 위한 컨트롤러를 대충 만들어준다.
아직 에러 핸들을 안해놔서 검증 부분이 안된다.
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Lotto Number Maker</title>
<!-- Custom styles for this template -->
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="container" th:object="${result}">
<div class="menu-name">
<h2>로또 당첨 이력 횟수 조회</h2>
</div>
<form action="/search" th:object="${winNumberSearchDto}" method="post" >
<label>최근 회차 기준 몇 회 전까지 분석합니까?</label>
<br>
<input type="text" th:field="*{count}">
<button> 검색 </button>
</form>
</div>
</body>
</html>
<!doctype html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Lotto Number Maker</title>
<!-- Custom styles for this template -->
<link rel="stylesheet" href="/css/style.css">
</head>
<body>
<div class="container" th:object="${result}">
<div class="menu-name">
<h2>로또 단일 회차 당첨 번호 조회</h2>
</div>
<ul th:each="allNumber : ${result.getAllNumbers()}">
<li> <span th:text="${allNumberStat.index} + 1 + ' : ' + ${allNumber} + '회'"> </span> </li>
</ul>
</div>
</body>
</html>
템플릿도 대충 후려갈겨준다.
100을 넣게 되면 최근 회차부터 100회를 거슬러 올라가서
각 번호별로 당첨 횟수를 카운트 해준다.
테스트 코드도 대충 작성
@SpringBootTest
class WinNumberServiceTest {
Logger log = LoggerFactory.getLogger(WinNumberServiceTest.class);
@Autowired
WinNumberRepository winNumberRepository;
@Autowired
WinNumberService winNumberService;
@Test
void makeNumberCountTest() {
//given
List<WinNumber> all = winNumberRepository.findAll();
int[] count = new int[45];
for (WinNumber winNumber : all) {
int winNumber1 = winNumber.getWinNumber1() - 1;
int winNumber2 = winNumber.getWinNumber2() - 1;
int winNumber3 = winNumber.getWinNumber3() - 1;
int winNumber4 = winNumber.getWinNumber4() - 1;
int winNumber5 = winNumber.getWinNumber5() - 1;
int winNumber6 = winNumber.getWinNumber6() - 1;
count[winNumber1]++;
count[winNumber2]++;
count[winNumber3]++;
count[winNumber4]++;
count[winNumber5]++;
count[winNumber6]++;
}
int size = all.size();
//when
HistoryNumber historyNumber = winNumberService.makeHistoryNumber(size);
int[] allNumbers = historyNumber.allNumbers;
//then
assertThat(count).isEqualTo(allNumbers);
log.info("result = {}", Arrays.toString(allNumbers));
}
}
음 당첨 많이 된 숫자나, 덜 된 숫자 카운팅은 map으로 바꿔서 보내든 해야겠다. 아님 배열 유지하면서 해둘 좋은 방법이 있는지 고민을 해야 할듯.