Today's Codekata
import java.util.*;
public class Solution {
public int solution(int n) {
int answer = 0;
ArrayList<Integer> arrNum = new ArrayList<>();
while (n > 0) {
arrNum.add(n % 10);
n /= 10;
}
for (int numbers : arrNum) {
answer += numbers;
}
// [실행] 버튼을 누르면 출력 값을 볼 수 있습니다.
System.out.println("Hell Java"); // 자바 어렵다...
return answer;
}
}
class Solution {
public int solution(int n) {
int answer = 0;
int i = 1;
while (i <= n) {
if (n % i == 0) {
answer += i;
}
i++;
}
return answer;
}
}
위에 처럼 List를 만들어서 담고 꺼내서 계산하려다 import된게 없는 걸 보고 바로바로 누적합하는 방식을 시도
class Solution {
public int solution(int n) {
int answer = 0;
int x = 1;
while (x <= n) {
if (n % x == 1) {
answer = x;
break;
}
x++;
}
return answer;
}
}
리스트에 담아서 최소값을 찾아야하나 한참 생각했는데, 1부터 늘려가며 값을 찾는 것이기에 첫 값이 최소값이었다...
계산기 만들기 마무리
마지막으로 제네릭을 활용해서 결과값이 정수일 때는 정수로 실수일 때는 실수로 출력되도록 만들어보려했는데 해결하지 못했다.
private List<Number> results = new ArrayList<>();
double result = operation.apply(num1, num2);
if (result == (int) result) {
results.add((int) result);
} else {
results.add(result); // 계산된 결과값을 컬렉션 리스트에 담음
}
이런 식으로 List의 반환 타입을 Number로 바꿈으로서 결과값이 List에 담기게는 만들었으나
double result = calculator.calculate(num1, num2, operator);
if (result == (int) result) {
System.out.println("결과: " + (int) result);
} else {
System.out.println("결과: " + result);
}
System.out.println("결과 목록: " + calculator.getResults());
결과: 2.0
결과 목록: [2]
이렇게 결과값은 double로 반환하고 있어서 외부에 또 만들어줘야만 했다.
// 입력값 보다 큰 결과값들 출력 (Stream 활용)
List<Double> filtered = calculator.getResults().stream()
.filter(num -> num > Math.max(num1, num2)) // Math.max 두 숫자 중 큰 값
.toList();
System.out.println("입력값 보다 큰 결과값들만 출력됩니다.: " + filtered);
public List<Number> getResults() { // 게터 메서드
return results; // 컬렉션 리스트를 반환
}
그랬더니 게터 메서드쪽에 double도 Number로 바꿔주어야했고, 그럼으로 이번엔 'num >' 이 부분에서 double을 Number랑 비교연산 할 수 없어서 오류가 발생했다. Stream만 빼면 계산기는 문제없이 돌아가긴 했다...
List<Double> filtered = calculator.getResults().stream()
.map(Number::doubleValue) // Number → double로 바꿔준다.
.filter(num -> num > Math.max(num1, num2))
.toList();
System.out.println("입력값 보다 큰 결과값들만 출력됩니다.: " + filtered);
.map(Number::doublevalue) Number를 double로 바꿔주는 방법을 찾아서 적용했더니 해결됐다. 다만 filtered 리스트에다 또 정수/실수 구분해서 출력을 시키는건 무의미해보여서 정수/실수 출력 관련은 일단 여기서 멈추기로 했다.
// 연산 결과 삭제 기능
System.out.print("결과 목록에서 값을 삭제하시겠습니까? (Y/N): ");
String delete = scanner.next();
if (delete.equalsIgnoreCase("Y")) {
System.out.print("삭제하고 결과의 위치를 입력해주세요.(0부터 시작합니다.): ");
int delNum = scanner.nextInt();
calculator.removeResult(delNum);
}
System.out.println("삭제되었습니다. 현재 목록: " + calculator.getResults()); // 삭제 후 결과 출력
추가로 첫 번째 값이 아니라 선택한 위치에 있는 값을 삭제하도록 만들어봤다. 다만 [1, 2, 3] 이런 결과값이 있을 때 위치는 0, 1, 2 이 되는데, 3 이상의 숫자를 입력하면 에러가 떠버린다. 과제 제출 시간에 도달해서 추후에 수정해봐야겠다.
튜터님 과제 해설을 듣고 ai나 검색찬스 없이 다시 2단계까지 만들어봤다.
package org.lv2;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Calculator cal = new Calculator();
while (true) {
System.out.print("첫 번째 숫자: ");
double first = sc.nextDouble();
if (first < 0) {
System.out.println("양의 정수를 입력하세요.");
continue;
}
System.out.print("두 번째 숫자: ");
double second = sc.nextDouble();
if (second < 0) {
System.out.println("양의 정수를 입력하세요.");
continue;
}
System.out.print("사칙연산 기호를 입력하세요.: ");
char c = sc.next().charAt(0);
double result = cal.calculate(first, second, c);
System.out.println("결과: " + result);
System.out.println("결과 목록: " + cal.getResultList());
System.out.print("결과 목록에 값을 추가하시겠습니까? (Y/N): ");
String y1 = sc.next();
if ("y".equalsIgnoreCase(y1)) {
System.out.print("추가할 값을 입력해주세요.: ");
double addNum = sc.nextDouble();
cal.addResult(addNum);
System.out.println("결과 목록: " + cal.getResultList());
}
System.out.print("첫 번째 계산 결과를 삭제하시겠습니까? (Y/N): ");
String y2 = sc.next();
if ("y".equalsIgnoreCase(y2)) {
cal.removeResult();
System.out.println("결과 목록: " + cal.getResultList());
}
System.out.println("더 계산하시겠습니까? (exit 입력 시 종료)");
String exit = sc.next();
if ("exit".equalsIgnoreCase(exit)) {
break;
}
}
}
}
package org.lv2;
import java.util.ArrayList;
import java.util.List;
public class Calculator {
private final List<Double> resultList = new ArrayList<>();
public double calculate(double first, double second, char c) {
double result = 0;
switch (c) {
case '+':
result = first + second;
break;
case '-':
result = first - second;
break;
case '*':
result = first * second;
break;
case '/':
if (second == 0) {
throw new ArithmeticException("0으로 나눌 수 없습니다.");
}
result = first / second;
break;
default:
throw new IllegalArgumentException("올바른 기호가 아닙니다.");
}
resultList.add(result);
return result;
}
public List<Double> getResultList() {
return resultList;
}
public void addResult(double addNum) {
resultList.add(addNum);
}
public void removeResult() { // 강의 자료 보고 완성
resultList.remove(resultList.get(0));
}
}
다행히 이해하고 있는 부분이 많았으나 removeResult 메서드를 만들 때 컬렉션 리스트에 첫 번째 위치의 값을 특정하는 방법이 기억이 나지 않아서 강의 자료를 보고 완성했다. 잠깐씩 막히는 부분도 있었지만 거의 다 이해는 된 것 같다. 다만 말로서 누군가에게 설명하라고 하면 명확하게 얘기할 수 있을지는 모르겠다.
마치며
코드를 만지다가 어느 것 하나만 건드려도 모든 영역에서 손봐야할 것들이 생겨나는게 개발에 어려운 점이자 매력인 것 같다. 이것저것 시도해보며 성취감을 느끼기도 좌절감을 느끼기도 했지만 모두 배움의 과정이라 생각한다. 이 코드가 왜 이렇게 쓰인 것인지 아는 것이 중요하다는 걸 느꼈다. 대충 느낌은 알겠으나 설명해보라고 하면 벙어리가 될게 틀림없다. 누구에게든 내가 작성한 코드를 설명할 수 있게 말할 수 있는 힘을 기르는 것도 중요하다고 느꼈다. 누군가에게는 한줄이면 될 코드를 10줄 20줄 가까이 적어서라도 어떻게든 구현이 되도록 만들어보는 과정이 지금의 나에게 필요해보인다.