끝없이 이어지는 무한소수 중 특정한 부분이 계속 반복되는 소수를 순환소수라고 하며, 반복되는 부분을 순환마디라고 한다.
모든 순환소수는 아래처럼 분수로 표현이 가능하다.
x = 0.5555....
10x = 5.55555....
9x(10x-x) = 5.5555... - 0.55555... = 5
x = 5/9
순환소수와 순환마디를 입력하면 기약분수로 표현한 값을 출력하는 프로그램을 작성하시오.
예시:
첫 번째 입력은 첫 번째 순환마디가 끝나는 부분까지의 순환소수,
두 번째 입력은 순환마디
0.5 → 5/9
5
1.49 → 3/2
9
21개의 풀이가 있습니다.
파이썬 3 입니다.
def gcd(a, b): # 최대공약수
if a < b: (a, b) = (b, a)
while b != 0: (a, b) = (b, a % b)
return a
p = input('변환할 순환소수를 첫번째 순환마디까지 입력하세요. : ')
if '.' not in p: p += '.' # p가 정수인 경우 뒤에 .을 추가해줌 ex 15 -> 15.
u = input('순환마디를 입력하세요. : ')
f = len(p) - p.find('.') - 1 # f는 첫번째 입력값의 소수점 밑의 자리수
pi, ui = float(p), int(u)
# 결과값 = 첫번째 순환마디까지 + 나머지 파트
# " " = pi + ui / ((10**f)*(10**len(u) - 1))
# pi = (pi * 10**f) / 10**f -> pi 를 분수형태로 변경 후 덧셈을 실시
# 나머지 파트 : ex) 순환마디가 456 -> (456/999) / 10**f
# upper 와 lower 는 결과값의 분자와 분모 (약분하기 전)
upper = pi * (100**f) * (10**len(u) - 1) + ui*10**f
lower = (100**f)*(10**len(u) - 1)
g = gcd(upper, lower) # 최대공약수로 나눠줌으로써 약분
upper /= g
lower /= g
print(int(upper), '/', int(lower))
print(int(upper)/int(lower)) # 최종결과 확인
결과
변환할 순환소수를 첫번째 순환마디까지 입력하세요. : 15.064
순환마디를 입력하세요. : 064
15049 / 999
15.064064064064064
변환할 순환소수를 첫번째 순환마디까지 입력하세요. : 156.654
순환마디를 입력하세요. : 54
8616 / 55
156.65454545454546
def gcd(a, b):
if b == 0: return a
else: return gcd(b, a%b)
x = float(input('순환소수 입력: '))
y = int(input('순환마디 입력: '))
i = int(10**len(str(x).split('.')[1]) * x) - int(10**(len(str(x).split('.')[1])-len(str(y))) * x)
j = 10**len(str(x).split('.')[1]) - 10**(len(str(x).split('.')[1])-len(str(y)))
print('출력: {}/{}'.format(int(i/gcd(i,j)),int(j/gcd(i,j))))
순환소수 입력: 1.49
순환마디 입력: 9
출력: 3/2
순환소수 입력: 1.254367
순환마디 입력: 4367
출력: 57011/45450
import java.util.Scanner;
public class bun{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("순환소수와 순환마디 입력");
String input1 = sc.nextLine();
String input2 = sc.nextLine();
String [] arr = input1.split("\\.");
String a1 = arr[0];
String b1 = "";
int count = 0;
for(int i=0;i<arr[1].length()-input2.length()+1;i++){
if((arr[1].substring(i,i+input2.length())).equals(input2) == false)
count++;
}
a1 += arr[1];
int bun1 = Integer.parseInt(a1) - Integer.parseInt(input2);
for(int i=0; i<input2.length();i++)
b1 += "9";
for(int i=0; i<count;i++)
b1 += "0";
int a = bun1;
int b = Integer.parseInt(b1);
while( a!= 0) {
if( a < b) {
int temp = a;
a = b;
b = temp;
}
a = a - b;
}
System.out.println(bun1/b + "/" + Integer.parseInt(b1)/b);
}
}
import java.util.Scanner;
public class Javatutorial {
public static long gcd(long a, long b) {
if (b == 0)
return a;
else
return gcd(b, a % b);
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String n, rec;
int a, b;
long bunmo, bunja, G;
// 입력
System.out.print("순환소수=");
n = sc.next();
System.out.print("순환마디=");
rec = sc.next();
// a: 마디 앞까지 10^a, b, 마디 끝까지 10^b
b = n.length() - n.indexOf(".") - 1;
a = b - rec.length();
n = n.replace(".", ""); // 소숫점 제거
// 계산
bunmo = (long)(Math.pow(10, b) - Math.pow(10, a));
bunja = Long.parseLong(n) - Long.parseLong(n.substring(0, n.length() - rec.length()));
// 기약분수
G = gcd(bunja, bunmo);
bunja /= G;
bunmo /= G;
System.out.println(bunja + "/" + bunmo);
sc.close();
}
}
x = input()
recurring = input()
x_temp = (x.split('.')[0] + x.split('.')[1][:-1 * len(recurring)])
q = int(x_temp + recurring) - int(x_temp)
p = 10 ** len(x.split('.')[1]) - 10 ** len(x.split('.')[1][:-1 * len(recurring)])
i = 2
while i <= p and i <= q:
if p % i == 0 and q % i == 0:
p = p / i
q = q / i
else:
i += 1
print("%d/%d" % (q, p))
#순환소수를 분수로 나타내기
y=float(input('순환마디가 끝나는 부분까지입력: '))
x=int(input('순환마디 입력: '))
stry=str(y)#문자열로
strx=str(x)
leny=len(stry)
lenx=len(strx)
geomy=stry.index(".")
n10=leny-geomy-1
#분모
b=10**(n10)-10**(n10-lenx)
#분자
rsy=stry.rstrip(".")
aa=y*(10**(n10-lenx))
a=y*(10**(n10))-(aa//1)
#기약분수로
def irr(a,b):
j=2
while j<=a:
if b%j==0 and a%j==0:
b=b//j
a=a//j
j=1
j+=1
print('답: ',int(a),'/',b)
irr(a,b)
from math import gcd
def cyclicnum(n,nd):
n,nd = str(n),str(nd)
n1 = str(float(n)*10**len(n[n.index('.')+1:]))
n1 = int(float(n1)-int((0,n1[:n1.index(nd)])[n1[:n1.index(nd)] != '']))
n2 = int('9'*len(nd)+'0'*len(n[n.index('.')+1:n.index(nd)]))
m = gcd(n1,n2)
print('%d/%d' %(int(n1/m),int(n2/m)))
import fractions
#숫자 입력 함수
def input_number():
num_1 = input()
num_2 = input()
return exchange_fountain(num_1,num_2)
def exchange_fountain(num_1,num_2):
num = num_1
cycle_num = num_2
cycle_num_len = len(cycle_num)
#소수점 위치
place = num.find(".")
#순환 숫자 위치 찾기
cycle_place = 0
for i in range(place+1, len(num)):
if num[i:i+cycle_num_len]==cycle_num:
cycle_place=i
break
print(cycle_place)
#숫자에 따른 pow 값
#예:15.5 => 155-15 로 pow_cnt = 0
# 1.49 => 149-14 로 pow_cnt = 1
pow_cnt = 0
if (cycle_place-place)>=place :
pow_cnt = cycle_place-place-1
else :
pow_cnt = 0
#분자
result_1 = int((float(num)*pow(10,cycle_place-place))-float(num[:cycle_place])*pow(10,pow_cnt))
#분모
result_2 = pow(10,cycle_place-place)-pow(10,pow_cnt)
result = fractions.Fraction(result_1,result_2)
print(result_1)
print(result_2)
return result
num = list(input())
period = list(input())
p = len(period)
lgt = len(num) - num.index('.') - 1
dnm = int(('9' * p) + ('0' * (lgt - p)))
num.remove('.')
temp = ''
for i in num:
temp += i
a = int(temp)
for i in period:
for j in num:
if i == j:
num.remove(i)
temp = ''
for i in num:
temp += i
b = int(temp)
nm = abs(b - a)
def gcd(a, b):
if a < b:
(a, b) = (b, a)
while b != 0:
(a, b) = (b, a % b)
return a
g = gcd(dnm, nm)
print('{} / {}'.format(int(nm / g), int(dnm / g)))
C#
using System;
using System.Linq;
namespace CD162
{
internal class Program
{
private static void Main(string[] args)
{
Console.Write("순환 소수: ");
string repeatingDecimal = Console.ReadLine();
Console.Write("순환 마디: ");
string repetend = Console.ReadLine();
Console.WriteLine(ToFraction(repeatingDecimal, repetend));
Console.ReadKey();
}
private static string ToFraction(string repeatingDecimal, string repetend)
{
// 소숫점 이하 길이 및 순환 마디의 길이로 부터 양변에 곱할 10^? 크기 구함
int decimalLenAfterPoint = repeatingDecimal.Split('.').Last().Length;
int nonRepetendLenAfterPoint = decimalLenAfterPoint - repetend.Length;
int powForDecimal = (int)(Math.Pow(10, decimalLenAfterPoint));
int powForRepentend = (int)(Math.Pow(10, nonRepetendLenAfterPoint));
// 좌변
int leftHand = powForDecimal - powForRepentend;
// 우변
int righrHand = (int)(decimal.Parse(repeatingDecimal) * powForDecimal)
- (int)(decimal.Parse(repeatingDecimal) * powForRepentend);
// 기약분수
int gcd = Gcd(leftHand, righrHand);
return $"{righrHand / gcd}/{leftHand / gcd}";
}
private static int Gcd(int a, int b) // 최대공약수
{
int lg = a > b ? a : b;
int sm = a > b ? b : a;
return b == 0 ? a : Gcd(b, a % b);
}
}
}
from fractions import Fraction
a=input("순환소수: ")
b=input("순환마디: ")
num=a+b+b+b
c=num.index(b)
if num[c+1]==num[c+2]==num[c+3]==b:
q=(10**(c-1))*float(num+b)-(10**(c-2))*float(num)
w=(10**(c-1))-(10**(c-2))
print(Fraction(int(q),int(w)))
def gcd(a,b):
value = 0
if a%b == 0 :
return int(b)
else :
value = a%b
a=b
b=value
return gcd(a,b)
s1 = float(input("순환소수 입력 : "))
s2 = int(input("순환 부분 : "))
x = int(10**(len(str(s1).split(".")[1]))*s1) - int(10**(len(str(s1).split(".")[1])-len(str(s2)))*s1)
y = int(10**(len(str(s1).split(".")[1]))) - int(10**(len(str(s1).split(".")[1])-len(str(s2))))
print("{}/{}".format(int(x/gcd(x,y)),int(y/gcd(x,y))))
앞의 내용(018/06/28 21:00 Creator)을 gcd만 변경하고 그대로 copy
import math
def recnum(num, r):
b = int(10**len(str(num).split('.')[1]))
s = int(10**(len(str(num).split('.')[1])-len(str(r))))
numerator = int(num*b) - int(num*s)
denominator = int(b-s)
d = math.gcd(numerator, denominator)
return (int(denominator/d), int(numerator/d))
if __name__ == '__main__':
num = 1.49
r = 9
print('{}/{}'.format(recnum(num, r)[1], recnum(num, r)[0]))
#파이썬
#이렇게 푸는것이 맞는건지 모르겠으나 답은 나오네요
#아직 분수 다루는것도 능숙하지 못해서 불필요한 소스가 들어갔는지 모르겠습니다
#하지만 재미있게 풀었습니다^^
from math import *
def cir_dec(x,y):
print ()
print (str(x)+str(y)+str(y)+str(y)+str(y)+str(y)+str(y))
a=10**len(str(y)) #x에 얼마를 곱할지
b=1/(10**len(str(str(x)[str(x).index('.')+1:]))) #y에 얼마를 곱할지
z=len(str(x)[int(str(x).index('.'))+1:int(str(x).index(str(y)))])
numer=round(((a-1)*x)+(b*y),z)
denom=a-1
while (numer!=int(numer)): #소수가 없어질때까지 10을 곱해준다
numer*=10
denom*=10
if numer<denom:
c=ceil(numer/2)
else:
c=ceil(denom/2)
i=2
while (i<=c):
if numer%i==0 and denom%i==0:
numer/=i
denom/=i
else:
i+=1
print (' ',int(numer))
print(' = -----')
print (' ',int(denom))
cir_dec(0.5,5)
cir_dec(0.12,12)
cir_dec(1.49,9)
cir_dec(3.247,47)
cir_dec(3.3,3)
cir_dec(0.36,36)
cir_dec(0.2571428,571428)
cir_dec(0.142857,142857)
import math
def divisor(n):
return set([k for k in range(1,n+1) if n%k==0 ])
def cir2frac(n, r):
x = n * (10 ** (str(n).index(str(r)) - 2))
a = int(math.modf(10 * x)[1] - math.modf(x)[1])
b = 9 * (10 ** (str(n).index(str(r)) - 2))
c = int(a / max(divisor(a) & divisor(b)))
b = int(b / max(divisor(a) & divisor(b)))
print(str(c) + "/" + str(b))
cir2frac(1.49, 9)
cir2frac(0.5, 5)
def function1(num1, num2):
num1_left = num1.split(".")[0]
num1_right = num1.split(".")[1]
num1_tog = num1_left + num1_right
_upper = int(num1_tog) - int(num1_tog[:len(num1_tog)-len(num2)])
_lower_list = []
for i in range(len(num2)):
_lower_list.append('9')
for j in range(len(num1_right)-len(num2)):
_lower_list.append('0')
_lower = int(''.join(_lower_list))
return [_upper, _lower]
def gcd(n1, n2):
yaksu_1 = []
yaksu_2 = []
for i in range(1, n1+1):
if n1 % i == 0:
yaksu_1.append(i)
for i in range(1, n2+1):
if n2 % i == 0:
yaksu_2.append(i)
_gcd = 1
for member in yaksu_1:
if member in yaksu_2 and member > _gcd:
_gcd = member
return _gcd
if __name__ == '__main__':
num1 = input(' input 1 : ')
num2 = input(' input 2 : ')
_gcd = gcd(function1(num1, num2)[0], function1(num1, num2)[1])
print('{0:.0f} / {1:.0f}'.format(function1(num1, num2)[0] / _gcd, function1(num1, num2)[1] / _gcd))
import fractions
N = float(input())
M = int(input())
check = str(N).find(str(M))-1
print(fractions.Fraction( int(N*(10**check)) - int(N*(10**(check-1))), 10**check -(10**(check-1))))
from math import gcd
n = input("순환소수 = ") # EX. 1.495
i = input("순환마디 = ") # EX. 95
n2 = float(n) * (10 ** len(i)) # EX. 1.495 * 100 = 149.5
a = str(n2 - float(n[:-len(i)])) # EX. str(149.5 - 1.4) = 148.1
k = 10 ** (len(a)-a.find(".")-1) # EX. 10
ans1 = int(float(a) * k) # EX. 1481
ans2 = int(((10 ** len(i)) - 1) * k) # EX. 990
print(int(ans1/gcd(ans1, ans2)), "/", int(ans2/gcd(ans1, ans2))) # EX. (1481/gcd)/(990/gcd)
// Rust
// x에 10의 적당한 승수를 곱해서 반복되는 순환마디만 소수점이하에 나타나도록 하고,
// 다시 여기에, 순환마디 한 세트가 소수점 위로 올라오도록 10의 적당한 승수를 곱해주고,
// 두 수를 빼서, x에 곱해지는 left 숫자, = 오른쪽 right 숫자 간 gcd를 구해 나눠줍니다.
fn recurring_decimal() {
let a = 1.49;
let b = 1; //마지막의 반복되는 순환마디의 개수
let a_ = a.to_string();
let mut iter = a_.split('.'); // ->{Option<subslice>}
let mut d = iter.next().unwrap();
let mut f = iter.next().unwrap();
let n = f.len() - b;
let x0: u32 = (d.to_string() + &f[..n]).parse().unwrap();
let x1: u32 = (d.to_string() + &f.to_string()).parse().unwrap();
// gcd로 나누기
let mut left = 10u128.pow(n as u32) * (10u128.pow(b as u32)-1);
let mut right = (x1 - x0) as u128;
let gcd = gcd(left, right);
left /= gcd;
right /= gcd;
println!("{}/{}", right, left);
} fn gcd(a_: u128, b_: u128) -> u128 {
let mut a = a_;
let mut b = b_;
if a < b { let t = b;
b = a;
a = t;}
while b != 0 { let t = a;
a = b;
b = t % b;}
a
}
a,b = input('순환소수의 첫 번째 순환마디가 끝나는 부분과 순환마디를 space 로 분리해서 입력해주세요. ').split(' ')
u,l = (float(a)*(10**len(b)) - float(a[:-len(b)])),((10**len(b)) - 1)
u_i,l_i = int(u*10**len(a.split('.')[1])), int(l*10**len(a.split('.')[1]))
import math
math.gcd(u_i,l_i)
print(f'{int(u_i/math.gcd(u_i,l_i))}/{int(l_i/math.gcd(u_i,l_i))}')
def gcd(a, b):
if a < b:
a, b = b, a
while b != 0:
a, b = b, a % b
return a
cpn = input('순환소수: ')
cn = input('순환마디: ')
bunmo = int('9'*len(cn) + '0'*(len(cpn)-cpn.find('.')-len(cn) - 1))
str_bunja = ''.join([i for i in cpn if i != '.'])
bunja = int(str_bunja) - int(str_bunja[:-1 * len(cn)])
g = gcd(bunmo, bunja)
print('\n {0} -> {1}/{2}'.format(cpn, bunja//g, bunmo//g))