반응형

 

반응형

 

 

1. 풍문으로만 듣던 10%의 수익률

여태까지 들어온 바로는 S&P500의 연 수익률이 10%정도 된다고 알고 있었습니다.

제가 예전에 정리했던 글에도 적혀있지만 

 

spy, S&P 500 : 워렌 버핏도 믿고 사는 미국 주식 치트키

안녕하세요. 오늘은 미국 주식의 대표적인 ETF 중 하나인 S&P 500에 대해 알아보려고 합니다. 작년부터 주식에 대한 관심이 많아지면서, 주변에서 주식을 시작하려 할 때, 가장 많이 추천했던 ETF입

fire-programmer.tistory.com

우리의 구글신에게 실제 S&P 500의 연평균 수익률을 물어본 결과는 14%(?) 10%, 8%로 나왔네요

물론 내용을 읽어 봐야 알겠지만.. 제가 알고 있는 8~10%로 얼추 비슷하네요.

 

2. 진실의 방으로!

뭐 일단 어느정도 근거가 있는 얘기라는건 확인했고

그래서 실제로 증권사 사이트에서 1993년도 데이터부터 월봉 차트로 일일이 표로 만들어서 직접 확인해봤습니다.

연도별 1월 시작가/ 12월 종료가를 넣어서 (엑셀이) 직접 계산해봤습니다.

연도 1월 시작가 12월 종료가 수익률 (1월 기준) 수익률(12월 기준)
1993 43.97 46.59    
1994 46.59 45.56 5.95 -2.21
1995 45.7 61.48 -1.91 34.94
1996 60.98 73.84 33.43 20.1
1997 74.38 96.22 21.97 30.3
1998 98.31 123.31 32.17 28.15
1999 123.38 146.88 25.5 19.11
2000 148.25 131.19 20.15 -10.68
2001 132 114.3 -10.96 -12.87
2002 115.11 88.23 -12.79 -22.8
2003 88.85 111.28 -22.81 26.12
2004 111.74 120.87 25.76 8.61
2005 121.56 124.51 8.78 3.01
2006 125.19 138.94 2.98 11.58
2007 142.25 146.21 13.62 5.23
2008 146.53 90.24 3 -38.28
2009 90.44 111.44 -38.27 23.49
2010 112.37 125.75 24.24 12.84
2011 126.71 125.5 12.76 -0.19
2012 127.76 124.41 0.82 -0.86
2013 145.11 184.69 13.58 48.45
2014 183.98 205.54 26.78 11.28
2015 206.38 203.87 12.17 -0.81
2016 200.49 223.53 -2.85 9.64
2017 225.04 266.86 12.24 19.38
2018 267.84 249.92 19.01 -6.34
2019 245.98 321.86 -8.16 28.78
2020 323.73 323.54 31.6 0.52
2021 375.31 461.64 15.93 42.68
2022 476.3   26.9  

3. 위 내용을 보고 느낀점

일단 결론은 바로 아래 나오겠지만.. 수익률은 10%정도 비슷

1월기준이든, 12월 기준이든, 그래프를 보면 추이는 거의 비슷하네요

  • 2021의 위엄 : 코로나로 양적완화를 진행한 결과 42%라는 어마무시한 결과가.. 덕분에 지금 무시무시한 후폭풍이..
  • 2년 연속 마이너스인 적은 없다(?) : 제가 알고 있는 이 말은 사실이 아닌것 같네요. 2000년도에는 무려 3년 연속 마이너스를 기록한적이 있습니다. 모두가 아시다시피 2008년도 금융위기는 1년만에 극복하긴 했네요
  • 후폭풍의 올해? : 살짝, 결과론적인 얘기지만.. 평균값이 10%인데 작년 42%, 재작년0%, 그 전해28%이면... 평균이 유지되려면 어느정도 역성장이 예상되긴 합니다.. 이미... 많이 내려왔죠..

 

4. 결론

1월 기준 / 12월 기준이냐에 따라 조금 차이는 있지만

9.45%와 10.32%가 나왔습니다.

이로써 S&P 500의 연 평균 수익률은 10% 내외라는 결론!

연평균 수익률 (1월) 9.45
연평균 수익률 (12월) 10.32

 

끝!

반응형
반응형

문제 설명

자연수 n이 매개변수로 주어집니다. n을 x로 나눈 나머지가 1이 되도록 하는 가장 작은 자연수 x를 return 하도록 solution 함수를 완성해주세요. 답이 항상 존재함은 증명될 수 있습니다.

문제

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

 

나의 풀이

import java.util.stream.IntStream;

public class NumberOfRemainingOne {

    public static void main(String[] args) {
        int n = 12;
        solution(n);
    }

    public static int solution(int n) {
        int answer = 0;
        while(true){
            if(n % ++answer == 1) break;
        }
        return answer;
    }
}

접근

별 다른 로직이 필요 없어 보이고, 역시 가장 단순하지만 기본적인 접근으로 시작 (시작과 끝 숫자를 잘못 정했지만..)

문제 풀이 컨셉은 다들 비슷했고, 나는 끝을 알수 없기에 while문을 적었으나, answer < n 으로 조건을 걸고, 시작은 2부터 했으면 더욱 깔끔한 코드일듯 하다

다른 사람의 풀이

    // Stream 을 활용한 다른사람의 풀이
    public static int solution(int n) {
        return IntStream.range(2,n).filter(i -> n % i == 1).findFirst().orElse(0);
    }

오늘도 Stream 한스푼! 일단 성능은 차치하고, 쓰는 법이나 익힐겸 적어보았다.
IntStream으로 2부터n까지 범위를 주되, filter로 조건을 걸어서 나머지가 1인 숫자, 그중에 첫번째를 찾는 로직

느낀점

  • 이번 문제는 딱히...없는듯
반응형
반응형

문제 설명

0부터 9까지의 숫자 중 일부가 들어있는 정수 배열 numbers가 매개변수로 주어집니다. numbers에서 찾을 수 없는 0부터 9까지의 숫자를 모두 찾아 더한 수를 return 하도록 solution 함수를 완성해주세요.

문제 보러 가기

 

나의 풀이

import java.util.ArrayList;

public class AddingSomeNumbers {

    public static void main(String[] args) {
        int[] numbers = {1,2,3,4,6,7,8,0};
        solution(numbers);
    }

    public static int solution(int[] numbers) {
        int answer = 0;
        ArrayList<Integer> numbersList = new ArrayList<>();

        for (int number : numbers) {
            numbersList.add(number);
        }
        for(int i = 0; i < 10; i++){
            if(!numbersList.contains(i))
                answer += i;
        }

        return answer;
    }
}

접근

나의 풀이 방법 - Count는 ArrayList의 contains를 활용

그렇다면, 풀어야 할 문제는 2가지 : Array(int[])를 ArrayList로 어떻게 바꿀것인가?

다른 사람의 풀이

// 1 - for 사용하지만, 문제에 대한 깊은 이해로 인해 모두 더한 수를 생각해 냄
class Solution {
    public int solution(int[] numbers) {
        int sum = 45;
        for (int i : numbers) {
            sum -= i;
        }
        return sum;
    }
}

// 2 - 45(모두 더한 수)와 stram 객체를 활용한 방법으로, Stream을 익히는게 좋을듯 
import java.util.Arrays;

class Solution {
    public int solution(int[] numbers) {
        return 45-Arrays.stream(numbers).sum();
    }
}

오랜만에 풀어서 그런지 45를 생각해내지 못했다

게다가 Stream도 익숙지 않아서 생각하지 못해 아쉽다

느낀점

  • Count할 방법을 미리 정해놓으니까, 문제의 접근 방식이 제한돼서 오히려 돌아서 푼 느낌
 
반응형
반응형

Java에서 Array를 List로 바꾸는 방법은 많겠지만, 가장 간단한 방법들을 몇 개 소개해드리겠습니다.

1. Arrays 사용 

복사하려는 array의 type이 기본형이라면 가장 간편한 방법으로, 기본 함수 사용
(단,  Integer가 아닌 int형이라면 사용이 불가능)

2. Collection 사용

Collections를 사용하여 array를 복사하는 방법, 하지만 복사하려는 array의 type이 기본형이 아니라면 사용 불가능

3. for 사용

가장 기본적인 방법으로 for/stream등을 이용해서 array를 하나씩 읽어서 list에 새로 넣는 방법
번거로워 보이지만, 형변등 처리가 가능하므로 int형을 Integer로 바꿔서 처리할 수 있다.

      // 1 - Arrays 활용
      List<Integer> list = Arrays.asList(array);          

      // 2 - Collection 활용
      List<Integer> list = new ArrayList<Integer>();
      Collections.addAll(list, array);

      // 3 - for each 활용
      List<Integer> list = new ArrayList<Integer>();
      for(Integer text:array) {
         list.add(text);
      }

 

 

 

 

 

java array to list

how to convert array to list

반응형
반응형

문제 설명

수포자는 수학을 포기한 사람의 준말입니다. 수포자 삼인방은 모의고사에 수학 문제를 전부 찍으려 합니다. 수포자는 1번 문제부터 마지막 문제까지 다음과 같이 찍습니다.

1번 수포자가 찍는 방식: 1, 2, 3, 4, 5, 1, 2, 3, 4, 5, ...
2번 수포자가 찍는 방식: 2, 1, 2, 3, 2, 4, 2, 5, 2, 1, 2, 3, 2, 4, 2, 5, ...
3번 수포자가 찍는 방식: 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, 3, 3, 1, 1, 2, 2, 4, 4, 5, 5, ...

1번 문제부터 마지막 문제까지의 정답이 순서대로 들은 배열 answers가 주어졌을 때, 가장 많은 문제를 맞힌 사람이 누구인지 배열에 담아 return 하도록 solution 함수를 작성해주세요.

문제 보러 가기

 

나의 풀이

import java.util.ArrayList;
import java.util.List;

class Solution {
    
    public static List<Integer> solution(int[] answers) {
        List<Integer> answer = new ArrayList();
        int[] personA = {1, 2, 3, 4, 5}; // length:5
        int[] personB = {2, 1, 2, 3, 2, 4, 2, 5}; // length:8
        int[] personC = {3, 3, 1, 1, 2, 2, 4, 4, 5, 5}; // length:10

        int[] hits = {0,0,0};

        for (int i = 0; i <answers.length; i++) {
            if(answers[i] == personA[i%personA.length]) hits[0]++;
            if(answers[i] == personB[i%personB.length]) hits[1]++;
            if(answers[i] == personC[i%personC.length]) hits[2]++;
        }

        int max = 0;
        for (int i = 0; i < hits.length; i++) {
            if(max < hits[i]){
                max = hits[i];
                answer =  new ArrayList();
                answer.add(i+1);
            } else if(max == hits[i]){
                answer.add(i+1);
            }
        }

        return answer;
    }
}

접근

풀어야 할 문제는 2가지 : 맞힌 문제 수 구하기 & 가장 많이 맞힌 사람 구하기

  • 맞힌 문제 수 구하기
    의외로 이 문제는 조건절 + %(나머지 연산자)를 사용하면 어렵지 않게 구할 수 있다 (= hits)
  • 가장 많이 맞힌 사람 구하기
    이게 관건인데, 
    확장성있게 리팩토링한 후에 좀 맘에 들게 바뀌었는데.. (첫 정답으로 자동 제출되는걸 몰라서 아쉽,,)
    최대 맞힌 수를 저장하는 max와 hits를 하나씩 비교하면서 비교하면서 결과를 도출하는 것이 주효했다.
    • 핵심 풀이
      최대 맞힌 개수보다 크면, 최대 맞힌 개수를 갱신하고, 결과용 리스트를 초기화 + 현재 값을 추가
      최대 맞힌 개수와 같으면, 현재 값만 추가

다른 사람의 풀이

import java.util.*;

class Solution {
    public static int[] solution(int[] answers) {
        int[][] patterns = {
                {1, 2, 3, 4, 5},
                {2, 1, 2, 3, 2, 4, 2, 5},
                {3, 3, 1, 1, 2, 2, 4, 4, 5, 5}
        };

        int[] hit = new int[3];
        for(int i = 0; i < hit.length; i++) {
            for(int j = 0; j < answers.length; j++) {
                if(patterns[i][j % patterns[i].length] == answers[j]) hit[i]++;
            }
        }

        int max = Math.max(hit[0], Math.max(hit[1], hit[2]));
        List<Integer> list = new ArrayList<>();
        for(int i = 0; i < hit.length; i++)
            if(max == hit[i]) list.add(i + 1);

        int[] answer = new int[list.size()];
        int cnt = 0;
        for(int num : list)
            answer[cnt++] = num;
        return answer;
    }
}

나와 다른 접근은 이중배열을 활용한 방법인데, 최대 개수를 구하는 로직보단,

맞힌 개수를 구할때, 이중 배열을 활용하는 접근법이 새로웠다

느낀점

  • 리팩토링의 중요성
반응형
반응형

문제 설명

임의의 양의 정수 n에 대해, n이 어떤 양의 정수 x의 제곱인지 아닌지 판단하려 합니다.
n이 양의 정수 x의 제곱이라면 x+1의 제곱을 리턴하고, n이 양의 정수 x의 제곱이 아니라면 -1을 리턴하는 함수를 완성하세요.

문제 보러 가기

 

접근

특별한 로직 대신 Math 함수의 제곱근 구하는 메소드(Math.sqrt)를 사용하면 쉽게 구할 수 있겠다는 생각으로 접근

나의 풀이

    public long solution(long n) {
        long answer = 0;

        long x = (long) Math.sqrt(n);
        if(x*x == n) {
            answer = (x+1)*(x+1);
        }else{
            answer = -1;
        }

        System.out.println("### answer : "+answer);
        return answer;
    }

다른 사람의 풀이

  public long solution(long n) {
      if (Math.pow((int)Math.sqrt(n), 2) == n) {
            return (long) Math.pow(Math.sqrt(n) + 1, 2);
        }

        return -1;
  }

 

느낀점

  • 제곱근 보다 오히려 정수인지를 판별하는 로직이 요즘 자주 쓰이니까, 다시 한번 상기!
Math.floor(i) == i
반응형
반응형

 

취업 후 상환 학자금 대출 상환 방법 (의무상환)


"취업 후 상환 학자금 대출 상환 방법(의무상환)"은 크게 2가지 방법이 있습니다.

아래에서 자세히 알아볼까요?

반응형


매월 원천공제 납부

전년도 소득에 대한 의무상환액이 통지가 되면 채무자(대출자)가 소속된 고용주가 급여 지급 시 의무상환액을 원천공제해 납부하게 됩니다. 
즉, 회사에 매월 급여를 줄때, 의무상환액만큼을 공제 한 금액을 주게 됩니다

(예. 월급:200, 월 의무상환액 20이라면, 매월 내 급여는 180씩 들어오게 됩니다)
 


원천공제 미리 납부

국세청에서 고용주에게 원천공제 대상자를 통지하기 전에 

먼저, 채무자가 원천공제 1년분 상환액을 일시 또는 분할하여 미리 납부(상환)할 수 있습니다.

  • 1년분 미리 납부 : 5월 말까지 원천공제 통지액(1년분)을 일시 납부
    => 방법 : 알려준 계좌번호로 5월말까지 통지액을 모두 이체
  • 분할 납부 : 50%는 5월 말까지, 나머지 50%는 11월 말까지 납부
    => 방법 : 알려준 계좌번호로 5월말까지 통지액의 50%만 이체 
    => 자동으로 분할 납부 신청이 되어, 11월까지 기간이 연장
     

원천공제 미리 납부 하면, 고용주에게 원천공제 대상자로 통지가 되지 않으니,
회사에 이를 알리고 싶지 않다면, 본인이 미리 납부를 해야합니다.

그리고 매달 원천공제를 통해 의무상환액을 납부하고 있더라도 채무자가 더 이상 원천공제를 원하지 않을 경우에는 이미 납부된 상환액을 차감한 잔여액을 일시 납부할 수도 있습니다.

반응형
반응형

출처 : https://programmers.co.kr/learn/courses/30/lessons/77884?language=java 

 

문제 설명

두 정수 left와 right가 매개변수로 주어집니다. left부터 right까지의 모든 수들 중에서, 약수의 개수가 짝수인 수는 더하고, 약수의 개수가 홀수인 수는 뺀 수를 return 하도록 solution 함수를 완성해주세요.

 

나의 풀이

    public int solution(int left, int right) {
        int answer = 0;

        for(int i=left; i<=right; i++){
            if(Math.ceil(Math.sqrt(i)) == Math.floor(Math.sqrt(i))){
                answer -= i;
            }else{
                answer += i;
            }

        }
        return answer;
    }

접근

(수학적으로 생각해보면) 약수의 개수가 홀수라면 소수이다.

따라서 해당 숫자의 제곱근이 자연수라면, 약수의 개수가 홀수개 이고, 그럴 경우에 값을 빼주고

나머지 숫자는 더하도록 구상

다른 사람의 풀이

    public int solution(int left, int right) {
        int sum = 0;
        for (int i = left; i <= right; i++) {
            sum += i * ((countDenominators(i) % 2 == 0) ? 1 : -1);
        }
        return sum;
    }
    private int countDenominators(int num) {
        int count = 0;
        for (int i = 1; i <= num; i++) if (num % i == 0) count++;
        return count;
    }

오랜만에 나의 풀이가 꽤 좋은 평가를 받는 축이었다.

대부분은 중첩 for문을 사용해서 직접 해당수의 약수를 직접 구해서 판단하는 로직이었다.

느낀점

  • 도메인에 대한 지식의 중요성 : 해당 분야에 대해 알고 있다면, 생각보다 빠르고 쉬운 풀이를 알 수 있다
  • 자연수(정수)를 판단하는게 의외로 잘 생각이 나지 않아 올림/내림을 사용했는데 좋은 방법이 있다
    i % Math.sqrt(i) == 0

 

반응형
반응형

문제 설명

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

 

 

나의 풀이

    /* 힌트보고 재작성 */
    public static String solution(String[] participant, String[] completion) {
        String answer = "";
        Map<String,Integer> participantMap = new HashMap<>();
        
        for (String partName : participant) {
            participantMap.put(partName, participantMap.getOrDefault(partName, 0)+1);
        }
        
        for (String compName : completion) {
            participantMap.put(compName, participantMap.get(compName)-1);
        }

        for(String name : participantMap.keySet()){
            if(participantMap.get(name) == 1){
                answer = name;
            }
        }
        System.out.println("###  answer : "+answer);
        return answer;
    }

    /* ArrayList를 활용 -> 라인은 줄었지만, 성능에서 또 걸림 */
    public static String solutionSecond(String[] participant, String[] completion) {
        String answer = "";
        List<String> participantList = new ArrayList<>();
        for (String person : participant) {
            participantList.add(person);
        }
        for (String comp : completion) {
            participantList.remove(comp);
        }
        answer=participantList.get(0);
        System.out.println("###  answer : "+answer);
        return answer;
    }

접근 방법

처음에 중첩 loop를 사용해서 하나씩 제거하는 방법을 생각했지만, 시간이 오래걸려서 채점에서 CUT
힌트를 보고서야 이 문제가 해시를 이용한 문제라는걸 알았다...
처음엔 Hash Set 을 이용했지만, 중복이 없어지는 Hash의 특성으로 계속 막혀서 결국 힌트를 봤다.

다른 사람의 풀이를 슬쩍 봤는데, 성능을 위해 해시를 쓰되, 중복처리를 위해 맵을 이용해 count를 하는게 인상깊었다

다른 사람의 풀이

HashMap 사용

import java.util.HashMap;

class Solution {
    public String solution(String[] participant, String[] completion) {
        String answer = "";
        HashMap<String, Integer> hm = new HashMap<>();
        for (String player : participant) hm.put(player, hm.getOrDefault(player, 0) + 1);
        for (String player : completion) hm.put(player, hm.get(player) - 1);

        for (String key : hm.keySet()) {
            if (hm.get(key) != 0){
                answer = key;
            }
        }
        return answer;
    }
}

Sorting 사용

import java.util.*;
class Solution {
    public String solution(String[] participant, String[] completion) {
        Arrays.sort(participant);
        Arrays.sort(completion);
        int i;
        for ( i=0; i<completion.length; i++){

            if (!participant[i].equals(completion[i])){
                return participant[i];
            }
        }
        return participant[i];
    }
}

비록 해시 문제이지만,  개인적으론 풀이법은 아래가 좀 더 멋져보인다

느낀점

일단, 어떤 문제든 일단 중첩 loop로 접근하는 나를 보며, 아쉬웠다

이번에 적절한 자료구조를 찾는게 힘들었다. Hash 까지는 문제를 보며 찾아갔지만, 풀이를 보고서야 HashMap을 쓰는 이유를 알게 되다니..

성능을 위해서 Hash를 사용했고

중복 체크를 위해 Map을 사용했다 

getOrDefault() : map에서 get을 하되 없을때 default 값 지정가능

 

그외의 방법으로는 Array로도 Sorting을 사용하면 시간안에 해결이 가능했지만,

해시에 집착하다보니 Sorting을 더 생각해보지 못해 아쉽다

여러개의 목록에서 중복/여부 체크시 -> Array라면 Sorting 해서 접근하는 방법도 좋을듯하다

 

비슷한 유형

[프로그래머스] 완주하지 못한 선수 (해시 Lv. 1)
[프로그래머스] 전화번호 목록 (해시 Lv. 2)
[프로그래머스] 위장 (해시 Lv. 2)
[프로그래머스] 베스트 앨범 (해시 Lv. 3)  

반응형
반응형

기존에 많이 쓰고(보이던) Try catch finally 아닌
try catch with resources
자원해제 처리 방법에 대해 정리 해보았습니다

 

실제 사용

try ( FileOutputStream out =  new FileOutputStream(file);){

        out.write(content.getBytes(StandardCharsets.UTF_8));

    } catch (FileNotFoundException e) {

        e.printStackTrace();

 }

=>  finally와 그 안에 자원해제 처리를 위한 부가 작업 불필요

 

 

설명

Try 자원객체를 전달하면, try 코드블록이 끝남과 동시에 자동으로 자원을 종료해주는 기능 (JDK 7 부터 사용가능)

=> finally, catch 각각 종료 처리르 걸지 않아도 된다

=> try() 안에 복수의 자원을 전달 있다

, 이때 try 전달 가능한 자원은 autoCloseable 인터페이스의 구현체로 한정

 

장점

Try catch finally 사용시, if, try문을 중복해서 사용하는 번거로움(처리를 위한 처리)

= 비즈니스와 무관한 자원해제 처리를 위한 코드를 줄일 있다

 

사용법 (비교)

// 파일 생성 (try-catch-finally)
public void makeFile(String path, String title, String content){
    FileOutputStream out = null;
    try {
        File file = new File(path+"/"+title);

        if(!file.exists()) { file.createNewFile(); }

        out = new FileOutputStream(file);
        out.write(content.getBytes(StandardCharsets.UTF_8));

    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(out != null){
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}

// 파일 생성 (try-catch-with-resource)
public void makeFile2(String path, String title, String content){

    File file = new File(path+"/"+title);

    try ( FileOutputStream out =  new FileOutputStream(file);){
        out.write(content.getBytes(StandardCharsets.UTF_8));
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}
반응형

+ Recent posts