project euler 71

Problem 71


Ordered fractions

Consider the fraction, n/d, where n and d are positive integers. If n < d and HCF(n,d)=1, it is called a reduced proper fraction.

If we list the set of reduced proper fractions for d ≤ 8 in ascending order of size, we get:

1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8,  2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

It can be seen that 2/5 is the fraction immediately to the left of 3/7.

By listing the set of reduced proper fractions for d ≤ 1,000,000 in ascending order of size, find the numerator of the fraction immediately to the left of 3/7.


有序分数

考虑形如n/d的分数,其中n和d均为正整数。如果n < d且其最大公约数为1,则该分数称为最简真分数。

如果我们将d ≤ 8的最简真分数构成的集合按大小升序列出,我们得到:

1/8, 1/7, 1/6, 1/5, 1/4, 2/7, 1/3, 3/8,  2/5, 3/7, 1/2, 4/7, 3/5, 5/8, 2/3, 5/7, 3/4, 4/5, 5/6, 6/7, 7/8

可以看出2/5是3/7直接左邻的分数。

将所有d ≤ 1,000,000的最简真分数按大小升序排列,求此时3/7直接左邻的分数的分子。

package projecteuler;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

public class Prj71  extends TestCase{

	public static final int UP_LIMIT = 1000000;

	public Prj71(String name) {
		super(name);
	}

	public static Test suite() {
		TestSuite suite = new TestSuite(Prj71.class);
		suite.addTest(new Prj71("testOrderedFractionsUseFarey"));
		//suite.addTest(new Prj71("qtestOrderedFractions"));

		return suite;
	}

	/**
	 * http://mathworld.wolfram.com/FareySequence.html;
	 * http://www.docin.com/p-835313638.html
	 */
	public void testOrderedFractionsUseFarey() {
		List<ReducedProperFraction> start = new ArrayList<ReducedProperFraction>();
		start.add(new ReducedProperFraction(0, 1));
		start.add(new ReducedProperFraction(1, 1));

		ReducedProperFraction find = new ReducedProperFraction(3, 7);
		List<ReducedProperFraction> dataList = iter(start, find, 1);

		for (ReducedProperFraction rpf : dataList) {
			System.out.println(rpf);
		}
		int idx = dataList.indexOf(find);
		assert (idx > 1);
		ReducedProperFraction lf = dataList.get(idx - 1);

		while (true) {

			int nn = lf.n + find.n;
			int dd = lf.d + find.d;

			if (nn > UP_LIMIT || dd > UP_LIMIT) {
				break;
			} else {

				lf = new ReducedProperFraction(nn, dd);
			}

		}

		System.out.println(lf);

	}

	List<ReducedProperFraction> iter(List<ReducedProperFraction> dataList,
			ReducedProperFraction find, int level) {

		boolean flag = false;
		for (int i = 0; i < dataList.size(); i++) {
			ReducedProperFraction rpf = dataList.get(i);
			if (rpf.n == find.n && rpf.d == find.d) {
				flag = true;
				break;
			}
		}

		if (flag) {
			return dataList;
		} else {
			List<ReducedProperFraction> next = new ArrayList<ReducedProperFraction>();
			next.add(new ReducedProperFraction(0, 1));
			for (int i = 1; i < dataList.size(); i++) {
				ReducedProperFraction lf = dataList.get(i - 1);
				ReducedProperFraction rt = dataList.get(i);
				if (lf.d + rt.d > (level + 1) || lf.n + rt.n > (level + 1)) {

				} else {
					next.add(new ReducedProperFraction(lf.n + rt.n, lf.d + rt.d));
				}
				next.add(new ReducedProperFraction(rt.n, rt.d));
			}
			return iter(next, find, level + 1);
		}
	}

	/**
	 * out of memory
	 */
	public void qtestOrderedFractions() {

		int count = 0;

		List<ReducedProperFraction> dataList = new ArrayList<ReducedProperFraction>();
		for (int i = 2; i <= UP_LIMIT; i++) {
			for (int j = 1; j < i; j++) {
				if (gcd(i, j) == 1) {
					count++;
					if (count % 10000 == 0) {
						System.out.println("i=" + i + ",j=" + j + ",count="
								+ count);
					}
					dataList.add(new ReducedProperFraction(j, i));
				}
			}
		}

		Collections.sort(dataList);

		for (int i = 0; i < dataList.size(); i++) {
			System.out.println(i + dataList.get(i).toString());
		}

	}

	/**
	 * n/d
	 * 
	 * @author suc
	 *
	 */
	public static class ReducedProperFraction implements
			Comparable<ReducedProperFraction> {

		public int n;
		public int d;

		public ReducedProperFraction(int n, int d) {
			this.n = n;
			this.d = d;
		}

		@Override
		public int compareTo(ReducedProperFraction o) {

			if (n * o.d == d * o.n) {
				return 0;
			} else if (n * o.d < d * o.n) {
				return -1;
			}

			return 1;
		}

		@Override
		public String toString() {
			return "ReducedProperFraction [n=" + n + ", d=" + d + "]";
		}

		@Override
		public int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + d;
			result = prime * result + n;
			return result;
		}

		@Override
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			ReducedProperFraction other = (ReducedProperFraction) obj;
			if (d != other.d)
				return false;
			if (n != other.n)
				return false;
			return true;
		}
	}

	public int gcd(int m, int n) {

		int a = m;
		int b = n;
		if (m < n) {
			a = n;
			b = m;
		}

		int t = 0;
		while (a % b != 0) {
			t = a % b;
			a = b;
			b = t;
		}
		return b;

	}

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值