All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.masahitojp.nineteen.Scanner Maven / Gradle / Ivy

The newest version!
package com.github.masahitojp.nineteen;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class Scanner {

    private int count;
    private final List rule = Arrays.asList(5, 7, 5);
    private final int ruleFullCount = rule.stream().mapToInt(s -> s).sum();
    private final List rulePhraseLengths = IntStream.rangeClosed(1, rule.size())
            .map(i -> rule.subList(0, i).stream().mapToInt(Integer::intValue).sum())
            .boxed()
            .collect(Collectors.toList());

    final List tokens;
    final boolean exactly;

    public Scanner(List tokens, boolean exactly) {
        this.count = 0;
        this.tokens = tokens;
        this.exactly = exactly;
    }

    public List> scan() {
        final List> phrases = new ArrayList<>();
        if (hasValidFirstNode()) {
            for (final Token token : this.tokens) {
                if (consume(token, phrases)) {
                    if (!this.exactly) {
                        if (satisfied(phrases)) {
                            return phrases;
                        }
                    }
                } else {
                    return null;
                }
            }
            if (this.satisfied(phrases)) {
                return phrases;
            }
            return null;
        } else {
            return null;
        }
    }

    private boolean consume(final Token token, final List> phrases) {
        if (token.getPronunciationLength() > maxConsumableLength()) {
            return false;
        } else if (!token.elementOfIkku()) {
            return false;
        } else if (rulePhraseLengths.contains(this.count) && !token.firstOfPhrase()) {
            return false;
        } else if (token.getPronunciationLength() == maxConsumableLength() && !token.lastOfPhrase()) {
            return false;
        } else {
            if (phrases.size() <= this.phraseIndex()) {
                phrases.add(new ArrayList<>());
            }
            phrases.get(this.phraseIndex()).add(token);
            this.count += token.getPronunciationLength();
            return true;
        }
    }

    private int maxConsumableLength() {
        return rule.subList(0, this.phraseIndex() + 1).stream().mapToInt(z -> z).sum() - count;
    }

    private int phraseIndex() {
        int result = rule.size() - 1;
        for (int i = 0; i < rule.size(); i++) {
            if (this.count < rule.subList(0, i + 1).stream().mapToInt(z -> z).sum()) {
                result = i;
                break;
            }
        }

        return result;
    }

    boolean satisfied(final List> phrases) {
        return hasFullCount() && hasValidLastNode(phrases);
    }

    private boolean hasFullCount() {
        return this.count == ruleFullCount;
    }

    private boolean hasValidFirstNode() {
        return this.tokens.size() > 0 && this.tokens.get(0).firstOfIkku();
    }

    private boolean hasValidLastNode(final List> phrases) {
        if (phrases.size() > 0) {
            final int size = Math.max(0, phrases.size() - 1);
            final int last = Math.max(0, phrases.get(size).size() - 1);
            return phrases.get(size).get(last).lastOfIkku();
        } else {
            return false;
        }
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy