알고리즘 day

프로그래머스 크레인 인형뽑기 게임

코딩테스트 연습 - 크레인 인형뽑기 게임

내 코드

public int solution(int[][] board, int[] moves) {
     int answer = 0;
     ArrayList<Integer> box = new ArrayList<>(moves.length);

     // box 생성
     for (int i = 0; i < moves.length; i++) {
         int column = moves[i] - 1;
         for (int j = 0; j < board.length; j++) {
             if (board[j][column] != 0) {
                 box.add(board[j][column]);
                 board[j][column] = 0;
                 break;
             }
         }
      }
     // 바구니 안에서 인형 터지는 동작
     for (int i = 0; i < box.size() - 1; i++) {
         if (box.get(i) == box.get(i + 1)) {
             box.remove(i + 1);
             box.remove(i);
             answer += 2;
             i = -1;
         }
     }
     return answer;
}
  • 예시로 테스트 할 때는 잘 동작 하는데, 채점할 때 1, 2번 테스트케이스에서 자꾸 오류가 났고, 나와 같이 ArrayList로 비슷하게 구현한 사람들의 코드를 찾아보았다.
    • 바구니 안에서 인형 터지는 동작을 구현한 for문 안 if문의 마지막 줄에 i = -1;
    • 통과한 사람들의 답안과 내답안의 차이점은 저 i = -1; 이였다.
    • 프로그래머스에 다른 사람들이 올린 테스트 코드를 실행하고, 디버깅 하는 와중에 무엇이 잘못되었는지 찾았다. 중간에 인형들이 터지면 그 앞 인형과 그 뒤 인형이 같은 경우가 생길 수 있는데 내가 짠 코드로는 그 상황들을 다 counting 하지 못한다.
    • i = -1을 해주면 for문에서 증감값에서 i++를 해주니깐 다시 box의 처음부터 돌 수 있다!

클로저

아래 두 블로그 보고 학습

Java Lambda (7) 람다와 클로저

Java - 자바 클로져(Closure) & 커링(currying)

  • 클로저란 자신을 둘러싼 context내에 접근할 수 있다.
  • 외부 함수 안에 있는 내부함수가 외부함수의 지역변수를 사용할 수 있다.
  • 외부함수가 종료되더라도 내부함수에서 참조하는 외부함수의 context는 유지된다.
    • 그 이유는 클로저가 생성되는 시점에서 함수 자체가 복사되어 따로 context를 유지하기 때문이다.
  • 클로저는 익명클래스에 context를 넘겨주는 것

자바에서 클로저의 동작

내부함수가 사용하는 외부함수의 지역변수를 클로저가 생성되는 시점에 final로 간주된다. 값이 변경될 수 없다. 자바 1.8부터는 final을 명시적으로 붙이지 않아도 컴파일에 의해 final 로 간주된다.

람다와 클로저

  • 람다와 클로저는 모두 익명의 특정 기능 블록이다.
  • 람다와 클로저의 차이점
    • 클로저는 외부 변수를 참조한다.
    • 람다는 자신이 받는 매개변수만 참조한다.
    • 즉, 자바에서 클로저는 외부 변수를 참조하는 익명클래스이고, 람다는 메서드의 매개변수만 참조하는 익명클래스이다.

결론 : 람다는 클로저를 포함하는 더 큰 개념, 람다가 자신의 범위 밖에 있는 변수를 사용하면 그것은 람다인 동시에 클로저이다.

순수함수(pure function)과 고차함수(higher-order function)

아래 블로그 참고해서 학습

Java Functional Programming

순수함수(pure function)

  • 부수 효과(side effect)가 없는 함수 즉, 어떤 함수에 동일한 인자를 주었을 때 항상 같은 값을 리턴하는 함수
  • 반환 값은 오직 함수를 통해 전해받은 파라미터에 의해서만 나온다.
  • 예시
public class ObjectWithPureFunction {
		public int sum(int a, int b) {
				return a + b;
		}
}
  • sum()은 오직 매개변수에 의해서만 반환값이 나온다.

  • side effects가 없다

    → sum()은 함수 바깥의 변수들에 아무런 영향을 주지 않는다.

고차함수(higher-order function)

  • 함수를 인자로 전달받거나 함수를 결과로 반환하는 함수

  • 자바에서는 하나 이상의 람다식을 파라미터로 받는 함수 그리고 다른 람다식을 반환하는 함수가 될 수 있다.

  • 예시

    public class HigherOrderFunctionClass {
    		public <T> IFactory<T> createFactory (IProducer<T> producer, 
    																				IConfigurator<T> configurator) {
    				return () -> {
    						T instance = producer.produce();
    						configurator.configure(instance);
    						return instance;
    				}
    		}
    }
    
    public interface IFactory<T> {
    		T create();
    }
    
    public interface IProducer<T> {
    		T produce();
    }
    
    public interface IConfigurator<T> {
    		void configure(T t);
    }
    • createFactory()가 람다식을 결과로 반환한다.
      • 함수를 리턴하기 때문에 이 함수는 고차 함수가 된다.
    • createFactory()의 매개변수는 함수형 인터페이스의 참조변수이다.
      • 즉, 매개변수로 람다식을 받아서 수행한다.
      • 이 함수는 고차 함수임

객체지향 패러다임과 함수형 패러다임

아래 두 블로그 참고해서 학습

함수형 프로그래밍 기초 (1) 왜 함수형 프로그래밍인가

[JAVA 8] - 함수형 프로그래밍(Functional Programming)

  • 객체 지향 패러다임
    • 명령형 프로그래밍으로 상태와 상태를 변경, 데이터를 어떻게 처리할지 명령을 통해 해결
    • 객체 안에 상태를 저장하고, 상태를 이용해서 제공할 수 있는 기능(메서드)를 추가하고 캡슐화, scoping 등의 기능 이용
  • 함수형 패러다임
    • 선언형 프로그래밍으로 선언적 함수를 통해 무엇을 풀어나갈지 결정
    • 부수효과(side effect)를 없애고 순수 함수를 만들어 모듈화 수준을 높이는 프로그래밍 패러다임
    • 순수함수를 지향한다.

오늘 한 일

  • 프로그래머스 알고리즘 크레인 인형뽑기 게임을 풀었다. 이전에 풀려다가 포기한 문제인데 오늘 겨우 풀었다.
  • 클로저에 대한 개념이 막막했는데 혼자서 학습을 한 뒤에, 조원들과 학습정리에 대한 토론을 하니 개념이 더 이해되는 듯 하다.
  • 클로저란? 자바에서의 클로저? 람다와 클로저의 관계? 순수함수와 고차함수란? 객체지향 프로그래밍과 함수형 프로그래밍의 차이?
  • 오늘은 자바의 정석 진도나가기 대신 스프링입문을 위한 객체지향의 원리와 이해 책을 읽을 것이다.

관심 있을 만한 포스트

0개의 댓글