반응형


카카오 신입 공채 1차 코딩 테스트에 있는 알고리즘 문제를 풀어봅니다.

비밀 지도(난이도: 하) 알고리즘 문제


1. 2진수 변환 객채를 만듭니다.

package kakao.secret_map;

public class BinaryString {

    private String binaryValue;

    private final static String BLINK_STRING = " ";
    private final static String WALL_STRING = "#";

    public BinaryString(int decimal) {
        this.binaryValue = Integer.toBinaryString(decimal)
                .replaceAll("0", BLINK_STRING)
                .replaceAll("1", WALL_STRING);
    }

    @Override
    public String toString() {
        return binaryValue;
    }
}

1. 10진수를 2진로 변환.
2. 2진수를 원하는 글자로 변환.

객체 지향인 만큼 최대한 객체에게 일을 위임합니다.


2. 비밀 지도의 숫자가 들어있는 Number 객체를 만듭니다.

package kakao.secret_map;

public class Number {

    private Integer decimal;

    public Number(Integer decimal) {
        if (decimal == null) throw new IllegalArgumentException();
        this.decimal = decimal;
    }

    public BinaryString toBinary() {
        return new BinaryString(decimal);
    }

    public Number orWise(Number number) {
        return new Number(decimal | number.decimal);
    }

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

Integer의 toBinaryString() 메쏘드와 비트 연산자인 |을 활용하는 문제였네요.

1. 2진수 변환
2. 비트연산

두 가지만 알면 되니 너무 쉽죠!?
하지만 저런 기능을 모르셨던 분들은 for문 돌리고, reverseOrder하고, 문자 비교하는등 
여러가지 복잡한 연산을 하셨던 분들도 계셨을 거에요!

실은 저도 그렇게 가려다가 ㅠㅠ Integer에 이런기능이 없을까 하고 클래스를 찾아보니 있더군요!

역시 사람은 조오금은 게으름을 피우는게... ㅎㅎㅎ

여기서 제일 핵심 비지니스 로직은 orWise() 입니다.
상태값이 변경된 객체가 아닌 새로운 객체를 반환하는것이죠.

꼭!!! 다른값이 아닌 새로운 객체로 반환한 이유를 고민해보세요~


3. 이제 여러개의 객체를 담을 수 있는 일급 클래스를 만듭니다.

package kakao.secret_map;

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

public class Numbers {
    private List<Number> numbers;

    public Numbers(Integer... numberArr) {
        numbers = Arrays.asList(Optional.of(numberArr).orElseThrow(IllegalArgumentException::new))
                .stream()
                .map(Number::new)
                .collect(Collectors.toList());
    }

    public Numbers(List<Number> numbers) {
        this.numbers = numbers;
    }

    public Numbers orWise(Numbers numbers) {
        if (this.numbers.size() != numbers.numbers.size()) throw new IllegalArgumentException();
        List<Number> _temp = new ArrayList();
        
        for (int i = 0; i < this.numbers.size(); i++) {
            _temp.add(this.numbers.get(i).orWise(numbers.numbers.get(i)));
        }
        return new Numbers(_temp);
    }

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

핵심 비지니스 로직이였던 orWise를 다시 사용하는 것이 전부 입니다.


실제로 작동하는지 확인해 볼까요?

package kakao.secret_map;

import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class NumberTest {

    @Test
    public void 진수_변환() {

        assertEquals("#  #", new BinaryString(9).toString());

        assertEquals("#### ", new Number(30).toString());

        assertEquals("#####", new Number(30).orWise(new Number(9)).toString());
    }

    @Test
    public void 여러개의_진수_변환() {
        Numbers numbers = new Numbers(10, 20, 30, 40, 50);
        System.out.println(numbers);

        System.out.println(new Numbers(9, 20, 28, 18, 11).orWise(new Numbers(30, 1, 21, 17, 28)));
    }
}

테스트 코드로 작성하였습니다.

객체를 객체답게 사용하기위해

규칙 2: else 예약어를 쓰지 않는다.
규칙 3: 모든 원시값과 문자열을 포장한다.
규칙 7: 2개 이상의 인스턴스 변수를 가진 클래스를 쓰지 않는다.
규칙 8: 일급 콜렉션을 쓴다.
규칙 9: 게터/세터/프로퍼티를 쓰지 않는다.

출처 : 효과적으로 TDD, 리팩토링, OOP를 연습하는 방법

파일 다운로드

 

반응형

+ Recent posts