It is possible to show that the square root of two can be expressed as an infinite continued fraction.
$$\sqrt 2 =1+ \frac 1 {2+ \frac 1 {2 +\frac 1 {2+ \dots}}}$$
By expanding this for the first four iterations, we get:
$$1 + \frac 1 2 = \frac 32 = 1.5$$
$$1 + \frac 1 {2 + \frac 1 2} = \frac 7 5 = 1.4$$
$$1 + \frac 1 {2 + \frac 1 {2+\frac 1 2}} = \frac {17}{12} = 1.41666 \dots$$
$$1 + \frac 1 {2 + \frac 1 {2+\frac 1 {2+\frac 1 2}}} = \frac {41}{29} = 1.41379 \dots$$
The next three expansions are \(\frac{99}{70}\), \(\frac {239}{169}\), and \(\frac {577}{408}\), but the eighth expansion, \(\frac {1393}{985}\), is the first example where the number of digits in the numerator exceeds the number of digits in the denominator.
In the first one-thousand expansions, how many fractions contain a numerator with more digits than the denominator?
問 57 「平方根の近似分数」
2の平方根は無限に続く連分数で表すことができる.
最初の4回の繰り返しを展開すると以下が得られる.
次の3つの項は99/70, 239/169, 577/408である. 第8項は1393/985である. これは分子の桁数が分母の桁数を超える最初の例である.
最初の1000項を考えたとき, 分子の桁数が分母の桁数を超える項はいくつあるか?
struct Fraction { deno_prev: u64, deno: u64, nume: u64, n: u32, } impl Fraction { fn new() -> Self { let deno_prev = 2u64; let deno = 5u64; Self { deno_prev, deno, nume: deno_prev + deno, n: 2, } } fn increment(&mut self) { self.n += 1; self.deno_prev = self.deno; self.deno += self.nume; self.nume = self.deno_prev + self.deno; const THRESHOLD: u64 = { let mut threshold = 1u64; while threshold < u64::MAX / 100 { threshold *= 10; } threshold }; if self.deno > THRESHOLD && self.nume > THRESHOLD { self.deno /= 10; self.nume /= 10; } } fn has_numerator_more_digits(&self) -> bool { let mut n = self.nume; let mut d = self.deno; while n > 0 && d > 0 { n /= 10; d /= 10; } n > d } } fn main() { let mut count = 0u32; let mut frac = Fraction::new(); while { if frac.has_numerator_more_digits() { count += 1; } frac.increment(); frac.n <= 1000 } {} println!("{}", count); assert_eq!(count, 153); }
#[derive(Clone)] struct BigNum { v: Vec<u64>, } impl BigNum { const TEN_MIL: u64 = 10_000_000_000; fn new(n: u8) -> Self { Self { v: vec![n as u64] } } fn merge(&mut self, page: usize, n: u64, carry: &mut u64) { if self.v.get(page).is_none() { self.v.push(0u64) } if let Some(con) = self.v.get_mut(page) { *con += n + *carry; if *con < Self::TEN_MIL { *carry = 0; return; } *carry = 1; *con -= Self::TEN_MIL; } } fn double(&mut self) -> &Self { let mut carry = 0u64; for con in self.v.iter_mut() { *con *= 2; *con += carry; if *con < Self::TEN_MIL { carry = 0; continue; } carry = 1; *con -= Self::TEN_MIL; } if carry != 0 { self.v.push(1u64); } self } fn add(&mut self, b: &BigNum) { let mut p = 0usize; let mut carry = 0u64; let mut ite = b.v.iter(); while let Some(n) = ite.next() { self.merge(p, *n, &mut carry); p += 1; } while carry != 0 { self.merge(p, 0, &mut carry); p += 1; } } } struct Fraction { deno: BigNum, nume: BigNum, n: u32, } impl Fraction { fn new() -> Self { Self { deno: BigNum::new(5), nume: BigNum::new(7), n: 2, } } fn increment(&mut self) { self.n += 1; let t = self.nume.clone(); self.nume.add(self.deno.clone().double()); self.deno.add(&t); } fn has_numerator_more_digits(&self) -> bool { if self.nume.v.len() != self.deno.v.len() { return self.nume.v.len() > self.deno.v.len(); } let mut n = *self.nume.v.last().expect("BigNum must have a container"); let mut d = *self.deno.v.last().expect("BigNum must have a container"); while n > 0 && d > 0 { n /= 10; d /= 10; } n > d } } fn main() { let mut count = 0u32; let mut frac = Fraction::new(); while { if frac.has_numerator_more_digits() { count += 1; } frac.increment(); frac.n <= 1000 } {} println!("{}", count); assert_eq!(count, 153); }
fn main() { let r1 = 1f64 + 2f64.sqrt(); let r2 = 1f64 - 2f64.sqrt(); let deno_c = 1.5f64 * 2f64.log10(); let nume_c = 2f64.log10(); let log10_r1 = r1.log10(); let r2_over_r1 = r2 / r1; let mut count = 0u32; let mut pow = r2_over_r1.clone(); for n in 2u32..=1001 { pow *= r2_over_r1; let nlog10r1 = n as f64 * log10_r1; let deno_digit = (nlog10r1 + (1f64 - pow).log10() - deno_c) as u32; let nume_digit = (nlog10r1 + (1f64 + pow).log10() - nume_c) as u32; if nume_digit > deno_digit { count += 1; } } println!("{}", count); assert_eq!(count, 153); }
fn main() { let r1 = 1f64 + 2f64.sqrt(); let deno_c = 1.5f64 * 2f64.log10(); let nume_c = 2f64.log10(); let log10_r1 = r1.log10(); let mut count = 0u32; for n in 2u32..=1001 { let nlog10r1 = n as f64 * log10_r1; let deno_digit = (nlog10r1 - deno_c) as u32; let nume_digit = (nlog10r1 - nume_c) as u32; if nume_digit > deno_digit { count += 1; } } println!("{}", count); assert_eq!(count, 153); }