package yukicoder.level2.no7;
import java.util.Collection;
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
/**
* No.7 プライムナンバーゲーム .
* https://yukicoder.me/problems/25
* あなたと素数を習ったばかりのEveは、素数のゲームを思いついた。
*
* ゲームの内容は以下のとおりです。
* ・まず初めに、先攻のプレイヤーに2以上の自然数Nが与えられます。
* ・その番のプレイヤーはNに対して、「N以下(Nも含む)の素数」のどれかで減算する、
* その数をN′とすると、N′が0または1になってしまったら、そのプレイヤーの負けである。
* ・その後N′を新たなNとし、相手にその数を渡し、以上を繰り返します。
*
*
* まずあなたが先攻となりゲームを始めます。
* この時、どちらも負けないように動くと考える。
* 自然数Nが与えられた時、あなたが勝つことが出来る場合Win、それ以外はLoseを返してください。
*/
public class PrimeNumberGame {
private static final String WIN_DISPLAY = "Win";
private static final String LOSE_DISPLATY = "Lose";
private static final int MIN_PRIME_NUMBER = 2;
public static void main(String[] args) {
new PrimeNumberGame().execute();
}
private void execute() {
int startingNumber = read();
boolean canWin = judgeWinnableNumber(startingNumber);
output(canWin);
}
//数字を順番にカウントアップする
//その数字が勝てるかどうかを判定する
//今まで出てきた素数で引いた数が勝てる場合は、相手が勝ってしまうので負け
//今まで出てきた素数で引いた数が勝てない場合は、相手が負けるので勝ち
//これを与えられた数字になるまで繰り返す
/**
*
* @param startingNumber
* @return
*/
public boolean judgeWinnableNumber(int startingNumber) {
Set winnableNumbers = new HashSet<>();
Set primeNumbers = new HashSet<>();
for (int preprocessingNumber = MIN_PRIME_NUMBER; preprocessingNumber < startingNumber; preprocessingNumber++) {
if(isPrime(preprocessingNumber, primeNumbers)) {
primeNumbers.add(preprocessingNumber);
}
if(isWannable(winnableNumbers, primeNumbers, preprocessingNumber)) {
winnableNumbers.add(preprocessingNumber);
}
}
return isWannable(winnableNumbers, primeNumbers, startingNumber);
}
private boolean isWannable(Set winnableNumbers, Set primeNumbers, int currentNumber) {
for (Integer operationNumber : primeNumbers) {
if(isWinOperation(currentNumber, operationNumber, winnableNumbers)) {
return true;
}
}
return false;
}
private boolean isWinOperation(int currentNumber, Integer operationNumber, Collection winnableNumbers) {
Integer nextOpponentNumber = currentNumber - operationNumber;
if(nextOpponentNumber <= 1) {
return false;
}
if(winnableNumbers.contains(nextOpponentNumber)) {
return false;
}
return true;
}
private boolean isPrime(int selfNumber, Set primeNumbers) {
for (Integer primeNumber : primeNumbers) {
if(selfNumber % primeNumber == 0) {
return false;
}
}
return true;
}
private void output(boolean canWin) {
System.out.println(canWin ? WIN_DISPLAY : LOSE_DISPLATY);
}
private int read() {
@SuppressWarnings("resource")
Scanner sc = new Scanner(System.in);
return sc.nextInt();
}
}