고대 이집트 사람들은 장인의 경지에 오른 엔지니어와 건축가들도 수학적인 지식은 조금의 흠을 가지고 있다. 그 중에 하나가 분수를 취급하는 그들의 체계가 그렇다.
그 때는 모든 분수는 분자가 1 인 수(단위 분수)만을 다루었다.
1/2, 1/3, 1/4, 1/5, ...
복잡한 분수들은 단위 분수의 합으로 표현되어 졌다.
예를 들어 ,
3/5 = 1/2 + 1/10 (NOT 1/5 + 1/5 + 1/5) ... 합으로 표현될 때 같은 분모가 두 번이상 나오면 안 된다.
5/7 = 1/2 + 1/5 + 1/70
불행하게도 , 그 시대에는 계산기가 없었다.
당신은 계산기를 가지고 있어, 이들을 단위 분수의 합으로 바꿀 수 있도록 도와 줄 수가 있다.
분자입력:5
분모입력:7
5 / 7 = 1 / 2 + 1 / 5 + 1 / 70
분자입력:1
분모입력:5
1 / 5 = 1 / 5
분자입력:7
분모입력:10
7 / 10 = 1 / 2 + 1 / 5
19개의 풀이가 있습니다.
from fractions import Fraction
def f(m, n):
frc = Fraction(m, n)
L = []
k = 2
while frc.numerator != 1:
if Fraction(1,k) < frc:
L.append(k)
frc = frc - Fraction(1,k)
k += 1
L.append(frc.denominator)
s = '%d/%d = ' % (m, n)
s = s + ' + '.join(map(lambda x : '1/' + str(x), L))
print(s)
>>> f(3,7)
3/7 = 1/3 + 1/11 + 1/231
>>> f(5,7)
5/7 = 1/2 + 1/5 + 1/70
>>> f(13,131)
13/131 = 1/11 + 1/121 + 1/15851
>>> f(21, 97)
21/97 = 1/5 + 1/61 + 1/9862 + 1/291767270
from fractions import Fraction
numer = int(input('Enter a numerator: ')) # 분자 입력 받기
denom = int(input('Enter a denominator: ')) # 분모 입력 받기
num = Fraction(numer,denom) # 입력 받은 수 분수로 만들기
print(str(num),'=', end=' ') # '입력 받은 수 =' 출력
div = 2 # 포함 여부 확인할 수의 분자 초기값
result = [] # 포함되어 있을 경우 저장할 리스트
while True:
if num >= Fraction(1,div): # 입력받은 수가 포함 여부 확인할 수보다 크면,
result.append(str(Fraction(1,div))) # 입력받은 수에 포함된 것이므로 리스트에 추가
num -= Fraction(1,div) # 입력 받은 수에서 확인된 수 빼주기
if num == 0:
break # 입력받은 수가 0이면 반복문 종료
div += 1 # 분자 +1 하여 반복
print(' + '.join(result)) # 결과 출력
처음에는 나누기 연산을 사용하여 풀었는데, 컴퓨터 연산 오차로 인하여 if num==0 이 부분에 걸리지 않아, fractions 클래스를 사용하게 되었습니다.
from fractions import Fraction
n = input('numerator/denominator = ')
n_fr = Fraction(*map(int, n.split('/')))
denom = 2
u_fr_lst = []
while n_fr.numerator > 1:
u = Fraction(1, denom)
if n_fr > u:
u_fr_lst.append(u)
n_fr -= u
denom += 1
print(n, '=', ' + '.join(map(str, u_fr_lst + [n_fr])))
from fractions import Fraction
import math
while True:
nume=int(input("Input numerator: "))
deno=int(input("Input denominator: "))
print()
user=Fraction(nume,deno)
rem=user
unitfraclist=[]
while True:
if rem.numerator==1:
unitfraclist.append(rem)
break
remdeno=math.ceil(1/rem)
unitfraclist.append(Fraction(1,remdeno))
rem=rem-Fraction(1,remdeno)
print("{}/{} =".format(nume,deno),end=' ')
print(user,end=' ')
print('=',end=' ')
for i in range(len(unitfraclist)-1):
print(unitfraclist[i],end=' ')
print('+',end=' ')
print(unitfraclist[-1])
print()
b1=int(input('분자입력:'))
b2=int(input('분모입력:'))
print(b1,'/',b2,'=',end=' ')
while b2%b1 != 0 :
s1=b1/b2
s2=1/s1
bm=int(s2)+1
print(1,'/',bm,'+',end=' ')
#분수계산
b1=bm*b1-b2
b2=b2*bm
print(1,'/',int(b2/b1))
실행결과
분자입력:5
분모입력:7
5 / 7 = 1 / 2 + 1 / 5 + 1 / 70
분자입력:21
분모입력:97
21 / 97 = 1 / 5 + 1 / 61 + 1 / 9862 + 1 / 291767270
<해결방법:알고리즘>
3/5 입력 되었으면
1/(3/5)=1.6666666666666666666666666666667
이 값이 정수로 떨어지지 안음으로 이 값보다 큰 정수 2를 분모로 하는 "1/2 + "을 출력하고
3/5 에서 1/2을 빼줌 : 코딩소스에서 "#분수계산" 부분
3/5 - 1/2 = 1/10 ...1)
다시 1(1/10)=10
10으로 딱 덜어 짐으로 "1/10"을 출력하고 종료
소스에서는 1)식을 변환하여 분모가 분자로 나누어 떨어질때 종료 조건으로 삼았습니다.
함수를 안쓰고 내부에서 처리 하였습니다.
~ 아! int(), print(),input()은 썻네요. T.T;
from fractions import Fraction
def fractions(n,d):
b = 2
f1 = Fraction(n, d)
res = []
while f1 != 0:
f2 = Fraction(1, b)
if f1 >= f2:
res.append(str(f2))
f1 -= f2
b += 1
return '+'.join(res)
num, denum = int(input()), int(input())
print(fractions(num, denum))
C#
TLDR;
using System;
using System.Numerics;
using System.Collections.Generic;
namespace CD226
{
internal class Program
{
private static void Main()
{
Console.Write("분자입력: ");
int numerator = int.Parse(Console.ReadLine());
Console.Write("분모입력: ");
int denominator = int.Parse(Console.ReadLine());
Fraction input = new Fraction(numerator, denominator);
string result = string.Join(" + ", Fraction.GetEgyptianFraction(input));
Console.WriteLine($"{input} = {result}");
}
}
public class Fraction
{
public BigInteger Numerator { get; private set; }
public BigInteger Denominator { get; private set; }
public Fraction(BigInteger numerator, BigInteger denominator)
{
Numerator = numerator;
Denominator = denominator;
}
public override string ToString() => $"{Numerator}/{Denominator}";
public static Fraction operator -(Fraction fractionA, Fraction fractionB)
{
BigInteger lcm = LCM(fractionA.Denominator, fractionB.Denominator);
BigInteger numerator = fractionA.Numerator * lcm / fractionA.Denominator
- fractionB.Numerator * lcm / fractionB.Denominator;
Fraction result = new Fraction(numerator, lcm);
return result;
}
// 두 분수 인스턴스에 대해 통분된 표현의 분수 인스턴스 튜플을 반환합니다
public static
(Fraction, Fraction) ReductionToCommonDenominator(Fraction fractionA, Fraction fractionB)
{
BigInteger lcm = LCM(fractionA.Denominator, fractionB.Denominator);
Fraction newFractionA =
new Fraction(fractionA.Numerator * lcm / fractionA.Denominator, lcm);
Fraction newFractionB =
new Fraction(fractionB.Numerator * lcm / fractionB.Denominator, lcm);
return (newFractionA, newFractionB);
}
public static bool operator >=(Fraction fractionA, Fraction fractionB)
{
(Fraction frA, Fraction frB) = ReductionToCommonDenominator(fractionA, fractionB);
return frA.Numerator >= frB.Numerator;
}
public static bool operator <=(Fraction fractionA, Fraction fractionB)
{
(Fraction frA, Fraction frB) = ReductionToCommonDenominator(fractionA, fractionB);
return frA.Numerator <= frB.Numerator;
}
// 주어진 분수 인스턴스를 이집트식 분수 표기법(단위 분수의 합)으로 변환합니다.
public static List<Fraction> GetEgyptianFraction(Fraction fraction)
{
List<Fraction> fractions = new List<Fraction>();
Fraction targetFraction = fraction;
BigInteger lastDenominator = 2;
while (targetFraction.Numerator != 1)
{
Fraction checkFraction = new Fraction(1, lastDenominator);
while (checkFraction >= targetFraction)
{
lastDenominator++;
checkFraction.Denominator++;
}
fractions.Add(checkFraction);
targetFraction -= checkFraction;
lastDenominator++;
}
fractions.Add(targetFraction);
return fractions;
}
public static BigInteger GCD(BigInteger numberA, BigInteger numberB)
{
while (numberB != 0)
{
BigInteger temp = numberA % numberB;
numberA = numberB;
numberB = temp;
}
return numberA;
}
public static BigInteger LCM(BigInteger numberA, BigInteger numberB)
=> checked(numberA * numberB / GCD(numberA, numberB));
}
}
Ruby
Rational
def fracs(num, deno=2, seq=[])
rem = num - Rational(1, deno)
seq << Rational(1, deno) if rem >= 0
rem > 0 ? fracs(rem, deno+1, seq) : (rem < 0 ? fracs(num, deno+1, seq) : seq)
end
def sum_of_fracs
frac = Rational(gets.to_i, gets.to_i)
puts "#{frac} = #{fracs(frac).join(' + ')}"
end
Test
$stdin = StringIO.new("3\n5\n")
expect { sum_of_fracs }.to output("3/5 = 1/2 + 1/10\n").to_stdout
$stdin = StringIO.new("7\n10\n")
expect { sum_of_fracs }.to output("7/10 = 1/2 + 1/5\n").to_stdout
Output
sum_of_fracs
5
7
5/7 = 1/2 + 1/5 + 1/70
from fractions import Fraction
result = []
def calc(up,down,a=2):
if Fraction(up,down) > 0 and Fraction(up,down) >= Fraction(1,a):
result.append(a)
up = (up*a)-(down)
down = down*a
calc(up,down,a+1)
elif Fraction(up,down) > 0 and Fraction(up,down) < Fraction(1,a):
calc(up,down,a+1)
else: return
def show():
global result
result = []
up = int(input("분자입력:"))
down = int(input("분모입력:"))
calc(up,down)
print(up,'/',down,' = ',' + '.join(map(lambda x : '1/' + str(x), result)))
show()
#include <stdio.h>
#include <math.h>
int main(){
double numerator;
double denominator;
double fraction;
int oneOvern;
printf("분자입력:");
scanf("%lf",&numerator);
printf("분모입력:");
scanf("%lf",&denominator);
fraction = numerator/denominator;
printf("%d / %d = ",(int)numerator,(int)denominator);
if(numerator == 1){
printf("%d / %d\n",1,(int)denominator);
}else{
for(oneOvern=1;fabs(fraction)>1.00e-3;oneOvern++){
if(fraction > (double)1/oneOvern-0.05){
printf("%d / %d + ",1,oneOvern);
fraction = fraction - (double)1/oneOvern;
}
}
printf("\b\b ");
}
return 0;
}
python 3.6
from fractions import Fraction
def fraction_decompose(A, d=2):
if d == 2:
print(A, '=', end=' ')
if A.numerator <= 1:
print(A)
else:
while A - Fraction(1, d) < 0:
d += 1
print(Fraction(1, d), end=' + ')
return fraction_decompose(A - Fraction(1, d), d=d+1)
numerator = int(input('numerator : '))
denominator = int(input('denominator : '))
fraction_decompose(Fraction(numerator, denominator))
Note : Fraction(5/7)로 넣으면 인자가 float로 들어가기 때문에 Fraction(7142857142857143, 10000000000000000) 이런 식으로 인식됨. 그래서 Fraction(5, 7)와 같은 방식으로 입력해야 함.`
C++로 분수 클래스를 만들어서 필요한 기능만 구현하여 짜봤습니다
#include<iostream>
using namespace std;
class Bunsu {
public:
Bunsu( unsigned int upper, unsigned int lower) :lower(lower), upper(upper){
Yakbun();
}
void Yakbun() {
unsigned int tmp = GCD(lower, upper);
lower /= tmp;
upper /= tmp;
}
void BunsuMinus(const Bunsu& x) {
unsigned int tmp = (upper * x.lower) - (x.upper * lower);
if (tmp > 0) {
upper = tmp;
lower = lower * x.lower;
Yakbun();
}
else if (tmp == 0) {
upper = 0;
lower = 1;
}
}
int CanMinus(const Bunsu& x) {
if (this->IsZero()) { return 0; }
if ((upper * x.lower) < (x.upper * lower) ) {
return 0;
}
else {
return 1;
}
}
int IsZero() {
return (upper == 0);
}
void ShowBunsu() const{
cout << upper << " / " << lower;
}
private:
unsigned int lower, upper;
int GCD(unsigned int a, unsigned int b) {
unsigned int tmp;
while (b) {
tmp = a % b;
a = b;
b = tmp;
}
return a;
}
};
int main() {
unsigned int Upper, Lower;
cout << "분자입력: ";
cin >> Upper;
cout << "분모입력: ";
cin >> Lower;
if (Upper*Lower == 0) { return 0; }
Bunsu a(Upper, Lower);
cout << Upper << " / " << Lower << " = ";
unsigned int i = 1;
while (1) {
Bunsu b(1, i);
if (a.CanMinus(b)) {
a.BunsuMinus(b);
b.ShowBunsu();
if (a.IsZero()) {
break;
}
else{
cout << " + ";
}
}
i++;
}
cout << endl;
return 0;
}
#include <stdio.h>
int main(void)
{
int a = 2;
int bunja,bunmo;
int nambunja = 0,nambunmo = 0;
printf("분자입력:");
scanf("%d",&bunja);
printf("분모입력:");
scanf("%d",&bunmo);
printf("%d / %d = ",bunja,bunmo);
nambunja = bunja;
nambunmo = bunmo;
while(nambunja != 1)
{
nambunja *= a; nambunmo *= a;
if(nambunmo/a <= nambunja)
{
nambunja -= nambunmo/a;
if(a != 2) { printf("+ "); }
printf("1 / %d ",nambunmo/(nambunmo/a));
}
else
{
nambunja /= a; nambunmo /= a;
}
if(nambunja == 0) break;
a++;
}
if(a != 2 && nambunja == 1) printf("+ ");
if(nambunja != 0) printf("1 / %d",nambunmo);
}
from fractions import Fraction
nn = input("분자 : ")
dd = input("분모 : ")
n = int(nn)
d = int(dd)
number = Fraction(n, d)
o = 1
k = []
while number != 0 :
if o == d :
o = o + 1
if Fraction(1, o) < number :
k.append("1/%d" %o)
number = number - Fraction(1, o)
o = o+1
elif Fraction(1, o) == number :
k.append("1/%d" %o)
number = number - Fraction(1, o)
break
o = o+1
print(" + ".join(k))
결과 분자 : 56 분모 : 88
1/2 + 1/8 + 1/89 + 1/7832
분자 : 5 분모 : 7
1/2 + 1/5 + 1/70
입력한 분모와 같은 분모를 가지는 수로 나타나는 현상을 수정했어요!
/*
고대 이집트 사람들은 장인의 경지에 오른 엔지니어와 건축가들도 수학적인 지식은 조금의 흠을 가지고 있다. 그 중에 하나가 분수를 취급하는 그들의 체계가 그렇다.
그 때는 모든 분수는 분자가 1 인 수(단위 분수)만을 다루었다.
1/2, 1/3, 1/4, 1/5, ...
복잡한 분수들은 단위 분수의 합으로 표현되어 졌다.
예를 들어 ,
3/5 = 1/2 + 1/10 (NOT 1/5 + 1/5 + 1/5) ... 합으로 표현될 때 같은 분모가 두 번이상 나오면 안 된다.
5/7 = 1/2 + 1/5 + 1/70
불행하게도 , 그 시대에는 계산기가 없었다.
당신은 계산기를 가지고 있어, 이들을 단위 분수의 합으로 바꿀 수 있도록 도와 줄 수가 있다.
분자입력:5
분모입력:7
5 / 7 = 1 / 2 + 1 / 5 + 1 / 70
분자입력:1
분모입력:5
1 / 5 = 1 / 5
분자입력:7
분모입력:10
7 / 10 = 1 / 2 + 1 / 5
*/
var str = "Hello, playground"
struct Value {
var numerator:UInt
var denominator:UInt
var isInfinity:Bool
}
func solution(numerator:UInt,denominator:UInt) -> String? {
if denominator == 0 {
return nil
}
var currentNumerator:UInt = numerator
var currentDenominator:UInt = denominator
var values:Array<Value> = Array()
for i in 2...denominator {
if Float(currentNumerator)/Float(currentDenominator) >= 1.0/Float(i) {
let value:Value = Value(numerator: 1, denominator: i, isInfinity: false)
values.append(value)
currentNumerator = (currentNumerator * i ) - (1 * currentDenominator)
currentDenominator = currentDenominator * i
}
}
print("currentNumerator:\(currentNumerator) currentDenominator:\(currentDenominator)")
if currentNumerator != 0 {
if currentDenominator%currentNumerator == 0 {
currentDenominator = currentDenominator/currentNumerator
currentNumerator = 1
let value:Value = Value(numerator: currentNumerator, denominator: currentDenominator, isInfinity: false)
values.append(value)
}
else {
print("이거 무한아닌가??;;;;")
let value:Value = Value(numerator: 1, denominator: currentDenominator, isInfinity: true)
values.append(value)
}
}
var returnStr:String = "\(numerator) / \(denominator) = "
for i in 0..<values.count {
if i != 0 {
returnStr = returnStr + " + "
}
returnStr = returnStr + "\(values[i].numerator) / \(values[i].denominator)"
if values[i].isInfinity {
returnStr = returnStr + "..."
}
}
return returnStr
}
print("result:\(solution(numerator: 5, denominator: 7))")
from fractions import Fraction import math
while True: nume=int(input("Input numerator: ")) deno=int(input("Input denominator: ")) print() user=Fraction(nume,deno) rem=user unitfraclist=[]
while True:
if rem.numerator==1:
unitfraclist.append(rem)
break
remdeno=math.ceil(1/rem)
unitfraclist.append(Fraction(1,remdeno))
rem=rem-Fraction(1,remdeno)
print("{}/{} =".format(nume,deno),end=' ')
print(user,end=' ')
print('=',end=' ')
for i in range(len(unitfraclist)-1):
print(unitfraclist[i],end=' ')
print('+',end=' ')
print(unitfraclist[-1])
Fraction 모듈을 쓰니까 쉽게 됩니다!
from fractions import Fraction
def FillFraction(frNum):
frSum = Fraction(0,1)
nBase = 2
while frSum<frNum:
frSumNew = frSum+Fraction(1,nBase)
if frSumNew<=frNum:
if nBase>2:
print(' + ',end='')
print('1/',nBase,end='')
frSum = frSumNew
nBase += 1
print('')
return
a = int(input('분자입력:'))
b = int(input('분모입력:'))
print(a,'/',b,end=' = ')
FillFraction(Fraction(a,b))
그시대에 태어날 일이 없어서.ㅡㅡㅋㅋㅋ https://tedbirli.com/
using System;
using System.Collections.Generic;
namespace solution
{
class Program
{
static void Main(string[] args)
{
Console.Write(" 분자입력:");
int bunja = int.Parse(Console.ReadLine());
Console.Write(" 분모입력:");
int bunmo = int.Parse(Console.ReadLine());
Console.Write("\n\n {0}/{1} =",bunja,bunmo);
makeOneBunsu(bunja, bunmo);
}
private static void makeOneBunsu(int bunja, int bunmo)
{
List<int> list = new List<int>();
int val = 1;
while(bunmo % bunja != 0)
{
val = bunmo / bunja + 1;
//Console.Write(" + 1/{0}", val);
list.Add(val);
bunja = bunja * val - bunmo;
bunmo *= val;
}
list.Add(bunmo / bunja);
Console.WriteLine(" 1/{0}", string.Join(" + 1/", list));
}
}
}