본문 바로가기

컴퓨터 과학/자료구조, 알고리즘

[Rust로 백준 하루 하나] 15-3. 분수 합

문제 (1735번)

분수 A/B는 분자가 A, 분모가 B인 분수를 의미한다. A와 B는 모두 자연수라고 하자.

 

두 분수의 합 또한 분수로 표현할 수 있다. 두 분수가 주어졌을 때, 그 합을 기약분수의 형태로 구하는 프로그램을 작성하시오. 기약분수란 더 이상 약분되지 않는 분수를 의미한다.

 

입력

첫째 줄과 둘째 줄에, 각 분수의 분자와 분모를 뜻하는 두 개의 자연수가 순서대로 주어진다. 입력되는 네 자연수는 모두 30,000 이하이다.

 

출력

첫째 줄에 구하고자 하는 기약분수의 분자와 분모를 뜻하는 두 개의 자연수를 빈 칸을 사이에 두고 순서대로 출력한다.


풀이

코드

use std::io::{self, BufReader, BufRead, BufWriter, Write};

fn main() {
    let mut reader = BufReader::new(io::stdin().lock());
    let mut writer = BufWriter::new(io::stdout().lock());

    let mut input = String::new();
    for _ in 0..2 {
        reader.read_line(&mut input).unwrap();
    }
    let mut input_iter = input
        .trim()
        .split_whitespace()
        .map(|i| i.parse::<i32>().unwrap());
    let a_child = input_iter.next().unwrap();
    let a_parent = input_iter.next().unwrap();
    let b_child = input_iter.next().unwrap();
    let b_parent = input_iter.next().unwrap();

    // 분모의 최소공배수로 분수 더하기
    let parent = lcm(a_parent, b_parent);
    let child = a_child * (parent/a_parent) + b_child * (parent/b_parent);

    // 기약분수로 만들기
    let output_parent = parent / gcd(parent, child);
    let output_child = child / gcd(parent, child);

    writeln!(writer, "{} {}", output_child, output_parent).unwrap();
}

fn lcm(a: i32, b: i32) -> i32 {
    (a * b) / gcd(a, b)
}

fn gcd(mut a: i32, mut b: i32) -> i32 {
    let mut r: i32;
    while b != 0 {
        r = a % b;
        a = b;
        b = r;
    }
    a
}

해설

특이사항 없음


추가 학습

  • 특이사항 없음