반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 받은 트랙백

글 보관함


지난 월요일 바닷가로 태평양 맛조개를 캐러 갔습니다.

Razor Clam 은 한국의 맛조개랑 비슷한데 크기가 좀 큽니다.

시애틀에서 해변까지는 차로 한 3시간 거리 쯤 됩니다.

이곳 워싱턴 주에서는 1인당 15마리 까지만 잡을 수 있어서 이번에는 30 마리를 잡아 왔습니다. (와이프 와 내꺼 합해서)

 

이번 여행을 유투브 클립으로 만들었습니다.

 

https://youtu.be/RI94L7wFXhk

이번 여행은 총 거리가 왕복 268 마일인데요 킬로미터로 하면 430 km 정도 됩니다.

 

이번에는 테슬라 모델 Y로 다녀 왔는데 계산 해 봤더니 배터리가 딱 100% 소비 됐더라고요.

(중간에 Volta charging station이라고 무료로 충전 할 수 있는 곳에서 24% 정도 충전 했어요.)

 

미국은 가정용 전기가 1kWh 당 16 센트 입니다.

 

이걸로 계산 했더니 총 13 달로 들었고 중간에 무료로 충전한 거 빼면 10 달러로 다녀 온 셈이 되더라고요.

 

430키로미터를 주행 했는데 만 삼천원 정도 썼습니다.

 

구글링 해 보니까 코롤라 연비는 갤런당 33 마일 이더라고요.

 

 

계산해 보면 테슬라는 1 마일 달리는데 4 센트가 들고 코롤라는 같은 거리를 15 센트에 달리더라구요.

 

테슬라가 코롤라 보다 1/4 정도 입니다.

 

참고로 지금은 휘발유 가격이 좀 높은 상태 입니다.

 

그리고 테슬라는 부품이 휘발유 차보다 훨씬 적어서 그 부분에서 유지비가 적게 들 수 있습니다.

 

그리고 테슬라는 다른 휘발유 차보다 가격이 훨씬 높고요.

 

10년 정도를 놓 고 구매 가격과 유지비용을 고려해서 생각하면 테슬라가 휘발유 차 보다 조금 더 돈이 든다고 봐야 겠네요.

 

돈을 제외 하고 보면 저는 테슬라를 타면서 아주 만족하고 있습니다.

운전하는게 재미 있어서 웬만하면 끌고 나가서 드라이브 하고 싶어요.

 

그리고 앞차에서 검은 연기 펑펑 쏟아 내는 걸 보면 나라도 지금 저렇게 공기를 오염 시키지 않아서 다행이다... 라는 생각도 들고요.

 

하여간 이상 테슬라 몰고 바닷가로 조개 잡이를 갔다오면 이야기 였습니다. 

반응형

Comment

Leetcode - 183. Customers Who Never Order - Easy

2022. 10. 20. 02:46 | Posted by 솔웅


 

이번 문제도 지난번 같이 SQL을 만드는 문제 입니다.

 

Customers와 Orders 테이블이 있고 여기서 한번도 주문을 하지 않은 사람만 골라 내는 문제입니다.

 

 

위의 예제에서 보면 Henry와 Max가 한번도 주문을 하지 않았습니다. 이런 고객만 골라서 display 해 주는 SQL문을 만들면 됩니다.

 

이건 간단하게 아래와 같이 풀 수 있습니다.

 

select customers.name as 'Customers'
from customers
where customers.id not in
(
    select customerid from orders
);

 

Where 문 에서 not in 을 사용하면 됩니다.

 

이밖에 LEFT JOIN 을 사용해서 아래와 같이 할 수 있습니다.

 

select Name as 'Customers'
from Customers c
LEFT JOIN Orders o
ON c.Id = o.CustomerId
where o.CustomerId IS NULL;

 

실행 시간은 둘 다 비슷한 것 같은데 첫번째 방법이 좀 더 안정적인 것 같네요.

 

반응형

Comment

Leetcode - 182. Duplicate Emails - MySQL - Easy

2022. 10. 18. 07:16 | Posted by 솔웅



오늘은 SQL쿼리를 만들어야 하는 문제 입니다.

Person이라는 테이블에 id 와 email이라는 컬럼이 있는데,
이 중에서 이메일이 두개 이상 되는 것을 찾아 내는 겁니다.

쉽게 생각하면 Group By와 Having을 사용해서 만들면 됩니다.

select Email
from Person
group by Email
having count(Email) > 1;

Email로 그룹바이 한 다음에 email count가 1을 넘는 Email을 표시하는 겁니다.

두 번째 방법으로는 Email과 Email count를 select 한 다음에 이 중에서 email count가 1 보다 큰 것만 표시하도록 하는 방법이 있습니다.

select Email from
(
    select Email, count(Email) as num
    from Person
    group by Email
) as statistics
where num > 1;

저는 이 방법 보다는 위에 첫번째 방법이 익숙한데…. 이렇게 해도 되겠네요.

그리고 이렇게 해도 됩니다.

select distinct p1.Email
from Person p1, Person p2
where p1.Email = p2.Email and p1.id != p2.id;



실행 결과 역시 첫번째 방법이 가장 빠른 것 같네요.

그냥 직관적으로 Group By와 Having을 사용하는게 제일 좋은 것 같습니다.

반응형

Comment


오늘 문제는 바로 이전 글에서 다룬 Climb Stairs와 기본적으로 같은 문제 입니다.

피보나치 수 입니다.

https://ko.wikipedia.org/wiki/피보나치_수

 

피보나치 수 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 피보나치 수를 이용한 사각형 채우기 수학에서 피보나치 수(영어: Fibonacci numbers)는 첫째 및 둘째 항이 1이며 그 뒤의 모든 항은 바로 앞 두 항의 합인 수열이다.

ko.wikipedia.org

자바로 이것을 구현 하는 방법은 여러가지가 있습니다.

이전 글에서도 몇가지 살펴 보았고 이번 글에서도 몇가지 예를 배울 계획입니다.

이전 글 https://coronasdk.tistory.com/1185

 

Leetcode - 70. Climbing Stairs (Easy)

이번 문제는 꽤 유명한 문제 입니다. 계단을 오르는 데 한번에 한 칸을 올라가거나 혹은 두칸을 올라갈 수 있습니다. 계단의 숫자를 입력값으로 받은 후 그 계단을 올라 갈 수 있는 방법은 몇가

coronasdk.tistory.com

그 중에 하나가 Recursion Function 인데요. 오늘은 이 방법을 이해해 보고 그 다음 예들을 간단히 살펴 보겠습니다.

피보나치 수에 대한 정의는 아래와 같습니다.

피보나치 수(영어: Fibonacci numbers)는 첫째 및 둘째 항이 1이며 그 뒤의 모든 항은 바로 앞 두 항의 합인 수열이다.

공식은 F(n) = F(n-1) + F(n-2) 입니다.

 

코드는 아래와 같습니다.

 

class Solution {
    public int fib(int n) {
        if(n<=1) return n;
        return fib(n-1) + fib(n-2);
    }
}

 

여기서 Recursion Function이 사용 됩니다.

 

return fib(n-1) + fib(n-2) 는 아래와 같이 작동합니다.

 

 

 

자 그럼 이 Recursion Function을 이용한 코드를 보겠습니다.

 

class Solution {
    public int fib(int n) {
        if(n<=1) return n;
        return fib(n-1) + fib(n-2);
    }
}

 

위 그림을 이해했다면 이 코드는 쉽게 이해 할 수 있을 겁니다.

 

이제 다른 방법을 알아 볼까요?

 

class Solution {
    public int fib(int N) {
        if (N <= 1) {
            return N;
        }
                  
        int[] cache = new int[N + 1];
        cache[1] = 1;
        for (int i = 2; i <= N; i++) {
            cache[i] = cache[i - 1] + cache[i - 2];
        }
    
        return cache[N];
    }
}

 

이것은 피보나치 식을 재귀 함수를 이용하지 않고 for 루프를 이용해서 코드를 작성한 겁니다.

방법은 같습니다.

 

Runtime은 for loop가 조금 더 빠른 것 같습니다.

 

그 이외에 아래와 같은 방법들이 있습니다.

 

class Solution {
    // Creating a hash map with 0 -> 0 and 1 -> 1 pairs
    private Map<Integer, Integer> cache = new HashMap<>(Map.of(0, 0, 1, 1));

    public int fib(int N) {
        if (cache.containsKey(N)) {
            return cache.get(N);
        }
        cache.put(N, fib(N - 1) + fib(N - 2));
        return cache.get(N);
    }
}

 

-----------

 

class Solution {
    public int fib(int N) {
        if (N <= 1) {
            return N;
        }

        int current = 0;
        int prev1 = 1;
        int prev2 = 0;

        for (int i = 2; i <= N; i++) {
            current = prev1 + prev2;
            prev2 = prev1;
            prev1 = current;
        }
        return current;
    }
}

 

--------------------

 

class Solution {
    int fib(int N) {
        if (N <= 1) {
          return N;
        }
        int[][] A = new int[][]{{1, 1}, {1, 0}};
        matrixPower(A, N - 1);

        return A[0][0];
    }

    void matrixPower(int[][] A, int N) {
        if (N <= 1) {
          return;
        }
        matrixPower(A, N / 2);
        multiply(A, A);

        int[][] B = new int[][]{{1, 1}, {1, 0}};
        if (N % 2 != 0) {
            multiply(A, B);
        }
    }

    void multiply(int[][] A, int[][] B) {
        int x = A[0][0] * B[0][0] + A[0][1] * B[1][0];
        int y = A[0][0] * B[0][1] + A[0][1] * B[1][1];
        int z = A[1][0] * B[0][0] + A[1][1] * B[1][0];
        int w = A[1][0] * B[0][1] + A[1][1] * B[1][1];

        A[0][0] = x;
        A[0][1] = y;
        A[1][0] = z;
        A[1][1] = w;
    }
}

 

--------------

 

수학 공식을 이용하는 방법

 

class Solution {
    public int fib(int N) {
        double goldenRatio = (1 + Math.sqrt(5)) / 2;
        return (int) Math.round(Math.pow(goldenRatio, N) / Math.sqrt(5));
    }
}

 

실행결과 Runtime, Memory는 거의 모두 동일 합니다.

반응형

Comment


이곳 워싱턴 주 Razor Clam 시즌이 얼마 전부터 오픈 됐다.

지난 주에는 너무 늦은 시각이라서 가지 못했다. 집에서 2시간 거리라서...

 

이번주에 마침 밀물 시간이 맞아서 가기로 했다.

 

테슬라를 구입한 후 첫번째 바다 여행이었다.

 

왕복 4시간.

 

중간에 쇼핑하면 잠깐 공짜 충전소 (Volta Charging Stations - 2 시간 공짜)에서 충전해서 여유있게 돌아올 수 있었다.

집에 왔더니 아직 30%가 넘게 남아 있었다.

 

이정도 거리는 중간에 별도로 충전 안 해도 될 듯 했다.

 

레이저 클램은  1인당 15마리가 제한이다.

 

나는 이날 10 마리 밖에 잡지 못했다.

 

Twin Habors beach 와 Long Beach 쪽은 상대적으로 레이저 클램이 적은 듯 했다.

주위에 많은 사람들이 리밋 을 채우지는 못했지만 가끔 채운 사람들도 보였다.

 

아직은 실력이 부족한 듯.

 

다음에 Copalis or Mocrocks beach쪽에 오픈 하면 가 봐야 겠다.

 

그곳에는 나 같은 초보자도 쉽게 리밋 을 채울 수 있다.

 

https://youtu.be/4YYARNwTII4

반응형

Comment

Seattle Art Museum 에서 그림을 그리다.

2022. 10. 8. 14:09 | Posted by 솔웅


몇 달 전 Seattle Art Museum 에서 자코메티전을 한다고 해서 가본 적이 있었다.

그 특별전이 이번주의 끝난다고 해서 마지막으로 한번 더 가서 감상했다.

 

다 보고 나오는데 이젤과 그림 그리는 도구들을 놓 고 방문객들이 자유롭게 그림을 그릴 수 있는 기회를 주는 이벤트가 열렸다.

 

나도 앉아서 한번 그려 봤다.

 

집에서 그림 연습 하던 것과는 또 다른 재미가 있었다.

 

이런 이벤트가 있으면 빠지지 않고 해 봐야지... :)

 

https://youtu.be/h9oyHnX6t68

 

반응형

Comment

Leetcode - 70. Climbing Stairs (Easy)

2022. 10. 5. 08:20 | Posted by 솔웅


이번 문제는 꽤 유명한 문제 입니다.

 

계단을 오르는 데 한번에 한 칸을 올라가거나 혹은 두칸을 올라갈 수 있습니다.

계단의 숫자를 입력값으로 받은 후 그 계단을 올라 갈 수 있는 방법은 몇가지가 있을 지 계산해야 합니다.

 

패턴을 한번 보겠습니다.

 

 

1. 계단이 1개 이면 방법은 1개 입니다.

2. 계단이 2개 이면 방법은 한 칸- 한 칸, 한번에 두칸 이렇게 두가지 방법이 있습니다.

3. 계단이 3개면 방법은 3가지 입니다. 1번 방법과 2번 방법을 더하면 됩니다.

일단 한칸 올라온 다음에 남은 방법은 나머지가 두칸이니까 2번에서 구한 2가 됩니다.

이단으로 두칸 올라온 다음에 남은 방법은 나머지가 한칸이니까 2번에서 구한 1이 됩니다.

그래서 1+2 =3 이 됩니다.

4. 그러면 4 칸 일 때는 3번과 2번을 더한 값인 5가 되겠죠.

일단 한칸 올라간 다음에 남은 방법은 나머지가 3칸이니까 3번에서 구한 3 가지 입니다.

이단으로 두칸 올라간 다음에 남은 방법은 나머지가 2칸 이니까 2번에서 구한 2가 됩니다. 

그러면 3+2인 5가 됩니다.

5. 계단이 5개 이면 당연하 4번 더하기 3번이겠죠. 그러면 5+3이 되서 총 8가지 방법이 있습니다.

 

이렇게 되면 공식을 구할 수 있죠.

 

N(current) = N(previous) + N(previous-1) 이 됩니다.

 

이걸 로직으로 만들어서 코딩을 하면 됩니다.

 

저에게 가장 쉬운 방법은 아래 방법입니다.

 

class Solution {
    public int climbStairs(int n) {
        if(n <=2) return n;
        
        int prev1 = 1;
        int prev2 = 2;
        int cur= prev1 + prev2;
        
        while(n>=3) {
            cur = prev1 + prev2;
            prev1 = prev2;
            prev2 = cur;
            n -= 1;
        }
        return cur;
    }
}

 

실행 결과는 아래와 같습니다.

다른 설명서 보니까 이런 방법도 있던데...

 

class Solution {
    public int climbStairs(int n) {
        return climb_Stairs(0,n);
    }
    
    public int climb_Stairs(int i, int n) {
        if (i > n) {
            return 0;
        }
        
        if(i == n) {
            return 1;
        }
        
        return climb_Stairs(i+1, n) + climb_Stairs(i+2, n);
    }
}

 

이해하기도 어렵고 별로 좋은 방법인 것 같지는 않습니다.

 

Runtime을 조금 더 줄이려면 아래 방법이 있습니다.

 

public class Solution {
    public int climbStairs(int n) {
        int memo[] = new int[n + 1];
        return climb_Stairs(0, n, memo);
    }
    public int climb_Stairs(int i, int n, int memo[]) {
        if (i > n) {
            return 0;
        }
        if (i == n) {
            return 1;
        }
        if (memo[i] > 0) {
            return memo[i];
        }
        memo[i] = climb_Stairs(i + 1, n, memo) + climb_Stairs(i + 2, n, memo);
        return memo[i];
    }
}

 

이런 방법도 있고요.

 

public class Solution {
    public int climbStairs(int n) {
        if (n == 1) {
            return 1;
        }
        int[] dp = new int[n + 1];
        dp[1] = 1;
        dp[2] = 2;
        for (int i = 3; i <= n; i++) {
            dp[i] = dp[i - 1] + dp[i - 2];
        }
        return dp[n];
    }
}

 

Runtime은 모두 비슷하고 바로 위 코드가 메모리를 조금 덜 차지하는 것 같습니다.

 

그 다음에 제가 이해하기 힘든 코드는 아래 두가지가 있습니다.

수학 공식을 사용하던데...

 

 public class Solution {
    public int climbStairs(int n) {
        int[][] q = {{1, 1}, {1, 0}};
        int[][] res = pow(q, n);
        return res[0][0];
    }
    public int[][] pow(int[][] a, int n) {
        int[][] ret = {{1, 0}, {0, 1}};
        while (n > 0) {
            if ((n & 1) == 1) {
                ret = multiply(ret, a);
            }
            n >>= 1;
            a = multiply(a, a);
        }
        return ret;
    }
    public int[][] multiply(int[][] a, int[][] b) {
        int[][] c = new int[2][2];
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j < 2; j++) {
                c[i][j] = a[i][0] * b[0][j] + a[i][1] * b[1][j];
            }
        }
        return c;
    }
}

 

그리고

 

public class Solution {
    public int climbStairs(int n) {
        double sqrt5 = Math.sqrt(5);
        double phi = (1 + sqrt5) / 2;
        double psi = (1 - sqrt5) / 2;
        return (int) ((Math.pow(phi, n + 1) - Math.pow(psi, n + 1)) / sqrt5);
    }

어쩄든 제가 만든 첫번째 스크립트하고 Runtime하고 Memory 결과 값은 비슷하더라구요.

 

첫번째 제가 시도한 방법은 Fibonacci Number라고 합니다.

 

Fibonacci Number에 대해 나중에 한번 살펴 봐야 겠습니다.

오늘은 이만......

 

반응형

Comment


지난달 9월 18 일 일요일에 집 근처 Lake Wilderness에서 철인 3종 경기가 열렸다.

이름은 IRONMAN 70.3 Washington이다.

 

구경하면서 찍은 비디오 클럽들이 있는데 딱히 유투브 영상 만드느라고 시간 들이기 아깝고 귀찮아서 방치해 두고 있었는데...

얼마 전 봤던 iMovie의 Magic Movie기능이 생각 났다.

 

일찍 잠에서 깨서 (나이 들 수록 아침 잠이 없어진다.) 뒤척거리다가 iPad를 켰다.

 

IMovie를 열고 그 때 찍었던 비디오들을 선택한 다음에 매직 무비 를 선택했다.

최근 순서대로 정렬 하는 바람에 일일이 매뉴얼로 다시 역순으로 배치했다.

 

그건 다음 나온 결과는.... 개인적으로 보기에 만족했다.

 

이거 편집 하려면 최소한 하루 온 종일 작업해야 하는데 그냥 순식간에 3분짜리 동영상을 만들어 버렸다.

 

https://youtu.be/w8DFagJ1PuU

 

이렇게 끝내기 아쉬워서 마무리에서 관련된 그림을 넣어 보기로 했다.

 

그림은 인공지능 화가인 DALL-E 2에게 맡겼다.

Description 은

Draw oil paintings of a man and an woman cheering after completing the triathlon at Maple Valley. 

 

메이플 밸리에서 열린 철인 3종경기를 완주하고 환호하는 남자와 여자를 유화로 그리라는 내용이다.

 

결과는

완전 마음에 들었다.

 

이렇게 점점 AI 가내 생활에 들어 오고 있나보다.

반응형

Comment

이전 1 다음