"손코딩뇌컴파일눈디버깅" 모임을 소개합니다.
백문이 불여일런, 트라이얼앤에러(Trial and Error) 식의 몹쓸 교육을 받아 온 개발자들이 코딩하기 전에 신중하고 꼼꼼하게 생각해보기란 쉽지 않습니다.
개발 시간 중 디버깅 시간이 절반 이상을 차지하고 있는 실정에 버그를 줄이기 위해 TDD니 유닛테스트니 많은 방법들이 개발되고 있지만 가장 일차적으로 중요한 것은 개발자들이 꼼꼼히 따져보는 것이 아니겠는지요?
미국의 선진 SW회사들은 이미 화이트보드에 PS문제를 푸는 것을 인터뷰 방식으로 채택하고 있습니다. 이는 이와 같은 풀이 방식이 개발자들의 기본 역량을 측정하기에 알맞은 지표라는 것이고, 개발자들이 기본적으로 갖춰야 할 역량이기도 하다는 것 입니다.
또한 자신의 생각을 명확하게 정리하고 다른 사람이 이해할 수 있도록 전달하는 Communication Skill 도 개발자가 갖춰야 할 역량 중 하나 입니다. 알고리즘을 어떻게 구현할 것인가를 팀원들과 소통하면서 자연스럽게 생각을 정리하고 전달하는 연습도 할 수 있습니다.
컴퓨터에 앉아 코딩하기 전 펜과 종이를 들고 눈과 머리와 손을 굴려 보시는 것은 어떠신지요??
"손코딩뇌컴파일눈디버깅" 모임을 소개합니다.
백문이 불여일런, 트라이얼앤에러(Trial and Error) 식의 몹쓸 교육을 받아 온 개발자들이 코딩하기 전에 신중하고 꼼꼼하게 생각해보기란 쉽지 않습니다.
개발 시간 중 디버깅 시간이 절반 이상을 차지하고 있는 실정에 버그를 줄이기 위해 TDD니 유닛테스트니 많은 방법들이 개발되고 있지만 가장 일차적으로 중요한 것은 개발자들이 꼼꼼히 따져보는 것이 아니겠는지요?
미국의 선진 SW회사들은 이미 화이트보드에 PS문제를 푸는 것을 인터뷰 방식으로 채택하고 있습니다. 이는 이와 같은 풀이 방식이 개발자들의 기본 역량을 측정하기에 알맞은 지표라는 것이고, 개발자들이 기본적으로 갖춰야 할 역량이기도 하다는 것 입니다.
또한 자신의 생각을 명확하게 정리하고 다른 사람이 이해할 수 있도록 전달하는 Communication Skill 도 개발자가 갖춰야 할 역량 중 하나 입니다. 알고리즘을 어떻게 구현할 것인가를 팀원들과 소통하면서 자연스럽게 생각을 정리하고 전달하는 연습도 할 수 있습니다.
컴퓨터에 앉아 코딩하기 전 펜과 종이를 들고 눈과 머리와 손을 굴려 보시는 것은 어떠신지요??
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기Ki-Hwan Kim
PYCON Korea 2015
Python은 과학 계산 분야에서도 이미 널리 사용되고 있습니다. numpy와 scipy 기반으로 만들어진 많은 모듈들이 휼륭한 생태계를 이루고 있기 때문입니다. 그러나 극한의 계산 성능을 요구하는 분야(HPC, High Performance Computing)에서는 여전히 C와 Fortran으로만으로 짜여진 코드들이 선호되고 있습니다. 이런 분야에서 Python에 대한 일반적인 견해는 전처리/후처리에는 유용하지만 메인 코드에 적용하기에는 느리다라는 것입니다.
이번 발표에서는 HPC 분야에서도 Python의 유용함을 보여줍니다. 계산이 집중된 부분만을 Fortran, C로 구현하여 Python 메인 코드에 접합하면, Python의 장점은 충분히 활용하면서도 계산 성능에 큰 손해는 보지 않을 수 있습니다. 게다가 CUDA-C, OpenCL-C와 연동하면 GPU, MIC와 같은 가속 프로세서들도 비교적 쉽게 활용할 수 있습니다. 이번 발표에서는 간단한 시뮬레이션 코드를 예제로 사용하여 Python 코드로부터 시작하여 Fortran, C, CUDA-C, OpenCL-C 등을 단계적으로 접합해 나가는 것을 보여줄 것입니다.
Python의 계산성능 향상을 위해 Fortran, C, CUDA-C, OpenCL-C 코드들과 연동하기Ki-Hwan Kim
PYCON Korea 2015
Python은 과학 계산 분야에서도 이미 널리 사용되고 있습니다. numpy와 scipy 기반으로 만들어진 많은 모듈들이 휼륭한 생태계를 이루고 있기 때문입니다. 그러나 극한의 계산 성능을 요구하는 분야(HPC, High Performance Computing)에서는 여전히 C와 Fortran으로만으로 짜여진 코드들이 선호되고 있습니다. 이런 분야에서 Python에 대한 일반적인 견해는 전처리/후처리에는 유용하지만 메인 코드에 적용하기에는 느리다라는 것입니다.
이번 발표에서는 HPC 분야에서도 Python의 유용함을 보여줍니다. 계산이 집중된 부분만을 Fortran, C로 구현하여 Python 메인 코드에 접합하면, Python의 장점은 충분히 활용하면서도 계산 성능에 큰 손해는 보지 않을 수 있습니다. 게다가 CUDA-C, OpenCL-C와 연동하면 GPU, MIC와 같은 가속 프로세서들도 비교적 쉽게 활용할 수 있습니다. 이번 발표에서는 간단한 시뮬레이션 코드를 예제로 사용하여 Python 코드로부터 시작하여 Fortran, C, CUDA-C, OpenCL-C 등을 단계적으로 접합해 나가는 것을 보여줄 것입니다.
산포된 데이터를 정합하는 직선을 찾는 것으로 이해해도 무방합니다. 주어진 데이터를 이용해 기울기와 절편을 구하는 방법입니다.
먼저 행렬연산을 통해 구하는 방법을 설명합니다. 그리고 퍼셉트론에 사용된 것과 같은 방법을 다시 설명하므로 선택적으로 듣기 바랍니다.
설명된 예제에 대한 C 언어 코드를 제공합니다. Tensorlow 코드는 정합 과정을 시각화하여 보여줍니다.
2. Number Theoretic Algorithms
Sogang ICPC Team 1
오늘은 PS에 등장하는 간단한 여러 정수론적 알고리즘들에 대한 소개를 합니다
✓ extended euclidean
✓ chinese remainder theorem [crt]
✓ lucas theorem
✓ number theoretic transform [ntt]
4. Linear Diophantine Equations
Sogang ICPC Team 3
ax + by = 1을 생각하면, r1 = a, r2 = b일 때...
r1 = q1r2 + r3
r2 = q2r3 + r4
...
rn−3 = qn−3rn−2 + rn−1
rn−2 = qn−2rn−1 + 1
5. Linear Diophantine Equations
Sogang ICPC Team 4
반대로 올라오면
1 = rn−2 − qn−2rn−1
rn−1 = rn−3 − qn−3rn−2
⇒ 1 = −qn−2rn−3 + (1 + qn−2qn−3) rn−2
이런 식으로 계속 대입하면서 올라오면 ax + by = 1이 성립하는 한 가지 경우를 구할 수
있다
9. Linear Diophantine Equations
Sogang ICPC Team 8
1 #include <bits/stdc++.h>
2
3 using namespace std;
4 using ll = long long;
5
6 inline tuple<ll, ll, ll> exgcd(const ll& a, const ll& b) {
7 if (b == 0) return make_tuple(a, 1, 0);
8 const auto& t = exgcd(b, a % b);
9 ll g = get<0>(t), x = get<1>(t), y = get<2>(t);
10 return make_tuple(g, y, x - (a / b) * y);
11 }
exgcd (a, b) = {gcd (a, b) , x, y} where ax + by = 1
시간 복잡도는 O (log (n + m))
10. Linear Diophantine Equations
Sogang ICPC Team 9
임의의 m에 대해 a−1
(mod m)은 ak + bm = 1인 k를 구하는 것과 같음을 이용해,
Euler’s theorem aφ(m)
≡ 1 (mod m)을 이용하지 않고 곱셈 역원을 구할 수도 있음에 참고
11. 해의 개수 #
11661
Sogang ICPC Team 10
Ax + By + C = 0의 해의 개수를 구하는 프로그램을 작성하시오.
A, B, C, x, y는 모두 정수이고, x1 ≤ x ≤ x2, y1 ≤ y ≤ y2 인 해의 개수를 구해야 한다.
이쯤 되면 그냥 수학문제 아닌가요?
✓ 네.
12. 해의 개수 #
11661
Sogang ICPC Team 11
gcd (A, B) ∤ C 일 경우에는 일단 해가 없고, G = gcd (A, B)이라면
Ax + By + C = 0
Ax + By = −C
ax + by = −c aG = A bG = B cG = C
a
(
−
x
c
)
+ b
(
−
y
c
)
= 1
를 만족하는 특수해
(
x′
0, y′
0
)
=
(
−
x0
c
, −
y0
c
)
를 먼저 구하고
13. 해의 개수 #
11661
Sogang ICPC Team 12
그 특수해를 이용해서
x1 ≤ x0 + bk ≤ x2 bG = B
y1 ≤ y0 + ak ≤ y2 aG = A
를 만족하는 k의 개수를 적절히 구해주자
처리할 예외가 많음에 주의(x1 > x2 같은 케이스가 들어온다던가..), 코드 생략.
14. System of Congrugences
Sogang ICPC Team 13
n ≡ a1 (mod m1)
n ≡ a2 (mod m2)
...
n ≡ ak (mod mk)
n ≡ x (mod m1m2 × · · · × mk)?
15. System of Congrugences
Sogang ICPC Team 14
식이 두 개 있다고 생각해 보자
n ≡ a1 (mod m1)
n ≡ a2 (mod m2)
모듈로의 정의에 의해
n = a1 + k1m1 = a2 + k2m2
16. System of Congrugences
Sogang ICPC Team 15
a1 + k1m1 = a2 + k2m2
⇒ a1 − a2 = −k1m1 + k2m2
여기서 적절한 k1 과 k2 를 구하면 적절한 n을 구할 수 있고, 이를 통해 n (mod m1m2)도
구할 수 있을 듯 한데..
17. System of Congrugences
Sogang ICPC Team 16
a1 − a2 = −k1m1 + k2m2
이 식은 diophantine equation이므로 적절한 k1 과 k2 를 찾을 수 있어 보인다
18. System of Congrugences
Sogang ICPC Team 17
13 inline ll crt(const ll &a1, const ll &a2, const ll &m1, const ll &m2) {
14 const auto &t = exgcd(m1, m2);
15 ll d = get<0>(t), x0 = get<1>(t);
16 const ll &m = m1 * m2 / d;
17 return ((a1 + x0 * (a2 - a1) * m1 / d) % m + m) % m;
18 }
시간 복잡도는 O (log (m1 + m2))
19. 카잉 달력 #
6064
Sogang ICPC Team 18
M, N, x, y가 주어지고, 예를 들어 M = 4, N = 5일 때 각 년도가
⟨1 : 1⟩ ⟨2 : 2⟩ ⟨3 : 3⟩ ⟨4 : 4⟩ ⟨1 : 5⟩
⟨2 : 1⟩ ⟨3 : 2⟩ ⟨4 : 3⟩ ⟨1 : 4⟩ ⟨2 : 5⟩
와 같은 식으로 표현된다면 ⟨x : y⟩는 몇 번째 해인가?
20. 카잉 달력 #
6064
Sogang ICPC Team 19
⟨x : y⟩를 T 번째 해라고 하면
T ≡ x (mod M)
T ≡ y (mod N)
이 성립하므로, CRT를 활용해 해결 가능. 단 gcd (N, M) ∤ (x − y)이면 유효하지 않은
표현이 된다. 코드 생략.
21. Binomial Coefficient Modulo Prime
Sogang ICPC Team 20
Lucas’s Theorem: m, n ∈ Z+
과 소수 p에 대해 다음이 성립한다.
(
n
m
)
≡
k∏
i=0
(
ni
mi
)
(mod p)
where m = mkpk
+ · · · + m1p + m0 and n = nkpk
+ · · · + n1p + n0.
n과 m을 p진법으로 표현한 뒤, 각 자릿수에 대해 이항 계수를 구한 것을 전부 곱한 것.(
n
m
)
= 0 if n < m.
22. 돌아온 떡파이어 #
15718
Sogang ICPC Team 21
떡파이어는 떡국을 먹은 그릇의 개수만큼 나이를 먹는다. 그들은 매일 떡국을 먹는데,
하루에 얼마든지 원하는 만큼 떡국을 먹을 수 있다. 그러나 떡국을 하루라도 먹지 않으면
생을 마감하게 된다.
M 째날에 N 세로 생을 마감한 떡파이어가 나이를 먹는 과정의 경우의 수를 세는 100, 007로
나눈 나머지를 구하는 프로그램을 작성한다. N = 3, M = 3일 때를 예로 들면,
✓ 첫째 날 1개, 둘째 날 2개, 셋째 날 0개
✓ 첫째 날 2개, 둘째 날 1개, 셋째 날 0개
의 2가지 경우가 있다.
23. 돌아온 떡파이어 #
15718
Sogang ICPC Team 22
답은 (
N − 1
M − 2
)
임을 쉽게 유도할 수 있고, 100, 007에 대해 Lucas’s theorem을 쓰면 된다 ...?
24. 돌아온 떡파이어 #
15718
Sogang ICPC Team 23
하지만
100, 007 = 97 × 1, 031
따라서
✓ 97에 대해, 1, 031에 대해 각각 Lucas’s를 쓰고
✓ 각각의 결과에 대해 CRT를 이용해 100, 007로 나눈 나머지를 구해야 한다.
좋은 정수론 웰노운 연습문제
25. Number Theoretic Transform
Sogang ICPC Team 24
큰 수에서 convolution을 FFT로 계산하면 실수 오차 때문에 틀릴 가능성이 있다
✓ FFT에서 e−2πik/N
부분을 어떤 소수 p의 n번째 원시근으로 바꾸면, C 대신 Z/pZ
위에서 변환할 수 있다!
✓ 실수가 등장하지 않고, 실수 오차를 걱정할 필요가 없어진다
26. Number Theoretic Transform
Sogang ICPC Team 25
원시근
✓ m ≥ 2에 대해 gcd (g, m) = 1이고 ordm g = φ (m)인 정수 g는 m의 원시근이다
✓ ordm g = φ (m) ⇒ gφ(m)
≡ 1 (mod m)
원시근은 나이브하게 구해놓을 수 있다 (시간도 얼마 안 걸림!)
27. Number Theoretic Transform
Sogang ICPC Team 26
“NTT 소수”
754, 974, 721 − 1 = 225
× p R = 11
377, 487, 361 − 1 = 224
× p R = 7
104, 857, 601 − 1 = 223
× p R = 3
28. Number Theoretic Transform
Sogang ICPC Team 27
11 using iarray = valarray<int>;
12 void ntt(iarray &a, bool f, int P, int R) {
13 const int N = a.size();
14 for (int i = 1, j = 0; i < N; i++) {
15 int b = N >> 1;
16 for (; j >= b; b >>= 1)
17 j -= b;
18 j += b;
19 if (i < j)
20 swap(a[i], a[j]);
21 }
P 에 소수를, R에 P 의 원시근을 집어넣는다
29. Number Theoretic Transform
Sogang ICPC Team 28
22 for (int i = 1; i < N; i <<= 1) {
23 int x = pow(f ? pow(R, P - 2, P) : R, P / i >> 1, P);
24 for (int j = 0; j < N; j += i << 1) {
25 int y = 1;
26 for (int k = 0; k < i; k++) {
27 ll u = a[j + k];
28 ll z = (ll)a[i + j + k] * y % P;
29 a[j + k] = (u + z) % P;
30 a[i + j + k] = (u - z + P) % P;
31 y = (ll)y * x % P;
32 }
33 }
34 }
30. Number Theoretic Transform
Sogang ICPC Team 29
35 if (f) {
36 int j = pow(N, P - 2, P);
37 for (int i = 0; i < N; i++)
38 a[i] = (ll)a[i] * j % P;
39 }
40 }
FFT에서 e−2πik/N
부분만 전부 교체한 것
이걸 FFT처럼 ntt (a)와 ntt (b)를 원소별로 곱한 뒤 ntt−1
(x)를 해 주면 된다
31. 씽크스몰 #
11385
Sogang ICPC Team 30
f (x) g (x)의 계수를 전부 XOR하라. 단, f 와 g는 106
차 이하의 다항식이고 그 계수도 전부
106
차 이하의 양의 정수이다.
✓ 곱해진 다항식의 계수는 263
미만인 거 같긴 합니다...
32. 씽크스몰 #
11385
Sogang ICPC Team 31
f 와 g는 106
차 이하의 다항식이고 그 계수도 전부 106
차 이하의 양의 정수이다.
✓ 이걸 단순 FFT로 계산할 수 있을까?
✓ 실수 오차 최적화를 정말 잘 하면 AC를 받을 수도 있긴 한데 비추
33. 씽크스몰 #
11385
Sogang ICPC Team 32
대신 적당히 큰
(
> 109
)
소수 두 개에 대해 NTT를 한 번씩 돌리고, 이를 CRT로 합치는
방법을 사용하자. 코드 생략.
34. 8회차 연습문제
Sogang ICPC Team 33
Extended euclidean
✓ 해의 개수 #
11661
1. 피보나치 문제해결전략 #
10327
2. A + B #
9267
Chinese remainder theorem
✓ 카잉 달력 #
6064
3. 날짜 계산 #
1476
Lucas theorem
✓ 돌아온 떡파이어 #
15178
4. 이항 계수 4 #
11402
Number theoretic transform
✓ 씽크스몰 #
11385