diff --git a/README.md b/README.md index 1d88ddd56d..e1ee5ed959 100644 --- a/README.md +++ b/README.md @@ -14,3 +14,7 @@ * 사람 이름을 5자 기준으로 출력하기 때문에 사다리 폭도 넓어져야 한다. * 사다리 타기가 정상적으로 동작하려면 라인이 겹치지 않도록 해야 한다. * |-----|-----| 모양과 같이 가로 라인이 겹치는 경우 어느 방향으로 이동할지 결정할 수 없다. + +# 프로그래밍 요구사항 +* 자바 8의 스트림과 람다를 적용해 프로그래밍한다. +* 규칙 6: 모든 엔티티를 작게 유지한다. diff --git a/src/main/java/nextstep/LadderApplication.java b/src/main/java/nextstep/LadderApplication.java new file mode 100644 index 0000000000..6508780ec3 --- /dev/null +++ b/src/main/java/nextstep/LadderApplication.java @@ -0,0 +1,26 @@ +package nextstep; + +import nextstep.domain.Line; +import nextstep.view.InputView; +import nextstep.view.ResultView; + +import java.util.LinkedList; + +public class LadderApplication { + + public static void main(String[] args) { + + String[] names = InputView.inputNames(); + + int ladderHeight = InputView.inputLadderHeight(); + + LinkedList lines = new LinkedList<>(); + lines.add(new Line(ladderHeight)); // 첫번째 라인은 랜덤으로 생성 + + for (int i = 1; i < names.length - 1; i++) { + lines.addLast(new Line(lines.getLast())); + } + + ResultView.printResult(names, ladderHeight, lines); + } +} diff --git a/src/main/java/nextstep/domain/Line.java b/src/main/java/nextstep/domain/Line.java new file mode 100644 index 0000000000..26e44fba43 --- /dev/null +++ b/src/main/java/nextstep/domain/Line.java @@ -0,0 +1,30 @@ +package nextstep.domain; + +import nextstep.util.RandomUtils; + +import java.util.ArrayList; +import java.util.List; + +public class Line { + private List points = new ArrayList<>(); + + public List getPoints() { + return points; + } + + public boolean isPoint(int idx) { + return points.get(idx); + } + + public Line(int height) { + for (int i = 0; i < height; i++) { + points.add(RandomUtils.nextBoolean()); + } + } + + public Line(Line previousLine) { + for (Boolean hasPoint : previousLine.getPoints()) { + points.add(!hasPoint && RandomUtils.nextBoolean()); + } + } +} diff --git a/src/main/java/nextstep/util/RandomUtils.java b/src/main/java/nextstep/util/RandomUtils.java new file mode 100644 index 0000000000..ff5916f338 --- /dev/null +++ b/src/main/java/nextstep/util/RandomUtils.java @@ -0,0 +1,12 @@ +package nextstep.util; + +import java.util.Random; + +public class RandomUtils { + + private static final Random random = new Random(); + + public static boolean nextBoolean() { + return random.nextBoolean(); + } +} diff --git a/src/main/java/nextstep/util/StringUtils.java b/src/main/java/nextstep/util/StringUtils.java new file mode 100644 index 0000000000..504a53e1d4 --- /dev/null +++ b/src/main/java/nextstep/util/StringUtils.java @@ -0,0 +1,19 @@ +package nextstep.util; + +public class StringUtils { + + public static String lpad(String name, int maxLength) { + + int length = name.length(); + + if (length > maxLength) { + throw new IllegalArgumentException("사람 이름을 5자를 넘지 못합니다."); + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i <= maxLength - name.length(); i++) { + sb.append(" "); + } + return sb.toString() + name; + } +} diff --git a/src/main/java/nextstep/view/InputView.java b/src/main/java/nextstep/view/InputView.java new file mode 100644 index 0000000000..45d25b3fd9 --- /dev/null +++ b/src/main/java/nextstep/view/InputView.java @@ -0,0 +1,36 @@ +package nextstep.view; + +import java.util.Scanner; + +public class InputView { + + private static final int MIN_LADDER_HEIGHT = 1; + private static final int MIN_NAME_LENGTH = 2; + + private static final Scanner scanner = new Scanner(System.in); + + + public static String[] inputNames(){ + + System.out.println("참여할 사람 이름을 입력하세요. (이름은 쉼표(,)로 구분하세요)"); + + String[] names = scanner.next().split(","); + + if(names.length < MIN_NAME_LENGTH){ + throw new IllegalArgumentException("최소 2명 이상이어야 합니다."); + } + + return names; + } + + public static int inputLadderHeight() { + + System.out.println("최대 사다리 높이는 몇 개인가요?"); + int ladderHeight = scanner.nextInt(); + + if(ladderHeight < MIN_LADDER_HEIGHT){ + throw new IllegalArgumentException("높이는 1 이상이여야 합니다."); + } + return ladderHeight; + } +} diff --git a/src/main/java/nextstep/view/ResultView.java b/src/main/java/nextstep/view/ResultView.java new file mode 100644 index 0000000000..477b77aa1c --- /dev/null +++ b/src/main/java/nextstep/view/ResultView.java @@ -0,0 +1,46 @@ +package nextstep.view; + +import nextstep.domain.Line; +import nextstep.util.StringUtils; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.stream.IntStream; + +public class ResultView { + + public static final String EMPTY_LADDER = " "; + public static final String FULL_LADDER = "-----"; + public static final String PIPE = "|"; + public static final int MAX_NAME_LENGTH = 5; + public static final String NL = System.lineSeparator(); + + + public static void printResult(String[] names, int ladderHeight, LinkedList lines) { + + StringBuilder sb = new StringBuilder(); + + sb.append("실행 결과") + .append(NL) + .append(Arrays.stream(names) + .map(name -> StringUtils.lpad(name, MAX_NAME_LENGTH)) + .reduce("", String::concat)) + .append(NL); + + IntStream.range(0, ladderHeight) + .forEach(idx -> { + sb.append(EMPTY_LADDER) + .append(lines.stream() + .map(line -> draw(line.isPoint(idx))) + .reduce("", String::concat)) + .append(PIPE) + .append(NL); + }); + + System.out.println(sb.toString()); + } + + private static String draw(boolean point) { + return PIPE.concat(point ? FULL_LADDER : EMPTY_LADDER); + } +}