열공스토리

[백준] 15562 - 톱니바퀴2 (JAVA 객체지향적으로 설계해 보기) 본문

백준

[백준] 15562 - 톱니바퀴2 (JAVA 객체지향적으로 설계해 보기)

열쩡열쩡열쩡_ 2023. 11. 17. 15:34
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
import java.util.stream.Collectors;

public class Main {
    private static final int S_POLE = 1;
    private static final int CLOCKWISE = 1;
    private static final int COUNTERCLOCKWISE = -1;

    static class GearGroup {
        private final List<Gear> group;

        GearGroup(List<Gear> group) {
            this.group = group;
        }

        void operateNumberGear(int number, int direction) {
            Gear gear = group.get(number);
            operateLeftGear(number - 1, switchDirection(direction));
            operateRightGear(number + 1, switchDirection(direction));
            decideDirection(gear, direction);
        }

        void operateLeftGear(int number, int direction) {
            if (number < 0) {
                return;
            }
            Gear rightGear = group.get(number + 1);
            Gear gear = group.get(number);
            if (rightGear.getLeftTeeth() != gear.getRightTeeth()) {
                operateLeftGear(number - 1, switchDirection(direction));
                decideDirection(gear, direction);
            }
        }

        void operateRightGear(int number, int direction) {
            if (number >= group.size()) {
                return;
            }
            Gear leftGear = group.get(number - 1);
            Gear gear = group.get(number);
            if (leftGear.getRightTeeth() != gear.getLeftTeeth()) {
                operateRightGear(number + 1, switchDirection(direction));
                decideDirection(gear, direction);
            }
        }

        void decideDirection(Gear gear, int direction) {
            if (direction == CLOCKWISE) {
                gear.translateClockwise();
            }
            if (direction == COUNTERCLOCKWISE) {
                gear.translateCounterclockwise();
            }
        }

        int switchDirection(int direction) {
            if (direction == 1) {
                return -1;
            }
            return 1;
        }

        int getResult() {
            return (int) group.stream()
                    .filter(Gear::is12oClockDirectionSPole)
                    .count();
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            for (Gear gear : group) {
                sb.append(gear + "\\n");
            }
            return sb.toString();
        }
    }

    static class Gear {
        private static final int FIRST_TEETH = 0;
        private static final int THIRD_TEETH = 2;
        private static final int SEVENTH_TEETH = 6;
        private static final int LAST_TEETH = 7;

        private final List<Integer> tooth;

        Gear(List<Integer> tooth) {
            this.tooth = tooth;
        }

        int getLeftTeeth() {
            return tooth.get(SEVENTH_TEETH);
        }

        int getRightTeeth() {
            return tooth.get(THIRD_TEETH);
        }

        void translateClockwise() {
            tooth.add(FIRST_TEETH, tooth.remove(LAST_TEETH));
        }

        void translateCounterclockwise() {
            tooth.add(tooth.remove(FIRST_TEETH));
        }

        boolean is12oClockDirectionSPole() {
            if (tooth.get(FIRST_TEETH) == S_POLE) {
                return true;
            }
            return false;
        }

        @Override
        public String toString() {
            return tooth.toString();
        }
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        int T = Integer.parseInt(br.readLine());
        List<Gear> gears = new ArrayList<>();
        while (T-- > 0) {
            List<Integer> tooth = generateTooth(br.readLine());
            gears.add(new Gear(tooth));
        }
        GearGroup gearGroup = new GearGroup(gears);

        int K = Integer.parseInt(br.readLine());
        while (K-- > 0) {
            StringTokenizer st = new StringTokenizer(br.readLine());
            int number = Integer.parseInt(st.nextToken()) - 1;
            int direction = Integer.parseInt(st.nextToken());
            gearGroup.operateNumberGear(number, direction);
        }
        System.out.println(gearGroup.getResult());
    }

    public static List<Integer> generateTooth(String input) {
        return Arrays.stream(input.split(""))
                .map(Integer::new)
                .collect(Collectors.toList());
    }
}