Skip to content

Instantly share code, notes, and snippets.

@Regentag
Created April 26, 2015 15:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Regentag/c82b2534b08fb4b699bf to your computer and use it in GitHub Desktop.
Save Regentag/c82b2534b08fb4b699bf to your computer and use it in GitHub Desktop.
// 모 채널에서 뉴스에 내보냈던 바로 그 이름궁합.
// 2015. 4. 27.
use std::env;
use std::borrow::Borrow;
/// 초성
#[allow(dead_code)]
static CHO : [char;19] = [
'ㄱ', 'ㄲ', 'ㄴ', 'ㄷ', 'ㄸ',
'ㄹ', 'ㅁ', 'ㅂ', 'ㅃ', 'ㅅ',
'ㅆ', 'ㅇ', 'ㅈ', 'ㅉ', 'ㅊ',
'ㅋ', 'ㅌ', 'ㅍ', 'ㅎ' ];
/// 초성 획수
static CHO_VAL: [usize;19] = [
2, 4, 2, 3, 6,
5, 4, 4, 8, 2,
4, 1, 3, 6, 4,
3, 4, 4, 3 ];
/// 중성
#[allow(dead_code)]
static JUNG: [char;21] = [
'ㅏ', 'ㅐ', 'ㅑ', 'ㅒ', 'ㅓ',
'ㅔ', 'ㅕ', 'ㅖ', 'ㅗ', 'ㅘ',
'ㅙ', 'ㅚ', 'ㅛ', 'ㅜ', 'ㅝ',
'ㅞ', 'ㅟ', 'ㅠ', 'ㅡ', 'ㅢ',
'ㅣ' ];
/// 중성 획수
static JUNG_VAL: [usize;21] = [
2, 3, 3, 4, 2,
3, 3, 4, 2, 4,
5, 3, 3, 2, 4,
5, 3, 3, 1, 2,
1 ];
/// 종성
#[allow(dead_code)]
static JONG: [char;28] = [
' ', 'ㄱ', 'ㄲ', 'ㄳ', 'ㄴ',
'ㄵ', 'ㄶ', 'ㄷ', 'ㄹ', 'ㄺ',
'ㄻ', 'ㄼ', 'ㄽ', 'ㄾ', 'ㄿ',
'ㅀ', 'ㅁ', 'ㅂ', 'ㅄ', 'ㅅ',
'ㅆ', 'ㅇ', 'ㅈ', 'ㅊ', 'ㅋ',
'ㅌ', 'ㅍ', 'ㅎ' ];
/// 종성 획수
static JONG_VAL: [usize;28] = [
0, 2, 4, 4, 2,
5, 5, 3, 5, 7,
9, 9, 7, 9, 9,
8, 4, 4, 6, 2,
4, 1, 3, 4, 3,
4, 4, 3 ];
/// 한국어로 된 `이름' 인가요?
fn is_kor_name( name: &str ) -> bool
{
let len = name.chars().count();
if len < 2 || len > 4
{
false
}
else
{
let mut ok = true;
for c in name.chars()
{
let code = c as usize;
if code < 0xAC00 || code > 0xD7A3
{
ok = false;
break;
}
}
ok
}
}
/// 숫자의 1의 자리만 가져온다.
fn get1( n: usize ) -> usize
{
if n > 9
{
get1( (n-10) )
}
else
{
n
}
}
/// 이름의 각 글자에 대한 획 수를 가져온다.
/// 초성,중성,종성 분리를 위해 다음 두 페이지를 참조하였습니다:
/// * http://westzero.tistory.com/112
/// * http://helloworld.naver.com/helloworld/76650
fn get_char_values( string: &str ) -> Vec<usize>
{
let mut vl: Vec<usize> = Vec::new();
for c in string.chars()
{
let code = c as usize;
if code < 0xAC00 || code > 0xD7A3
{
continue;
}
let a = code - 0xAC00;
let cho = a / (21*28);
let jung = (a % (21*28)) / 28;
let jong = a % (28);
let v = CHO_VAL[cho] + JUNG_VAL[jung] + JONG_VAL[jong];
vl.push( get1(v) );
}
vl
}
/// 두 이름을 합쳐 한 문자열로.
/// ln : 두 이름 중 긴쪽.
/// sn : 두 이름 중 짧은쪽.
fn join_name( ln: &str, sn: &str ) -> String
{
let ll: Vec<char> = ln.chars().collect();
let ss: Vec<char> = sn.chars().collect();
let mut cnt: usize = 0;
let mut j = String::new();
while cnt < ll.len()
{
j.push( ll[cnt] );
if cnt < ss.len()
{
j.push( ss[cnt] );
}
cnt += 1;
}
j
}
/// 글자간의 획 수를 더하면서
/// 궁합(...)을 계산한다.
/// 결과 벡터의 크기가 2이면 최종 계산이 끝난것이다.
fn calc_gunghab( v: &Vec<usize> ) -> Vec<usize>
{
let mut nv: Vec<usize> = Vec::new();
let mut cnt: usize = 1;
while cnt < v.len()
{
nv.push( get1(v[cnt-1] + v[cnt]) );
cnt += 1;
}
nv
}
fn print_with_space( str: &String )
{
for c in str.chars()
{
print!( "{} ", c );
}
print!("\n");
}
fn print_with_space_n( num: &Vec<usize> )
{
for n in num
{
print!( "{} ", n );
}
print!("\n");
}
fn print_space( n: usize )
{
let mut i: usize = 0;
while i < n
{
print!(" ");
i += 1;
}
}
fn main()
{
let args: Vec<_> = env::args().collect();
if args.len() != 3
{
println!( "두 사람의 이름을 입력하세요." );
return;
}
let name1 = args[1].borrow();
let name2 = args[2].borrow();
if !is_kor_name( &name1 ) || !is_kor_name( &name2 )
{
println!( "이름은 한국어로 2~4글자로 입력하세요." );
return;
}
let join = if name2.len() > name1.len()
{
join_name( &name2, &name1 )
}
else
{
join_name( &name1, &name2 )
};
// 이름부터 먼저 출력해준다.
print_with_space( &join );
let mut v = get_char_values( &join.borrow() );
let mut indent = 1;
while v.len() != 2
{
print_space( indent );
print_with_space_n( &v );
v = calc_gunghab( &v );
indent += 1;
}
print_space( indent );
print_with_space_n( &v );
// 싱크로율(...) 계산
let sync_rate = (v[0]*10) + v[1];
println!( "\n'{}', '{}'의 싱크로율은 {}% 입니다!",
name1, name2, sync_rate );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment