Esempio n. 1
0
int solve_104()
{
	Pair num0(1, 1), num1(1, 1);
	int result = 2;

#ifdef ApproachOne
	const Pair::Number Max = (~((Pair::Number)0)) / 10;	// UINT64_MAX / 10
	for(; !Pandigital(num1); ++result)
	{
		// It's easy to handle the low-9 digits.
		Pair::Number t_low = num1.low;
		num1.low = (num1.low + num0.low) % Sieve;
		num0.low = t_low;

		Pair::Number t_high = num1.high + num0.high;

		// dig_count(x) + dig_count(y) <= 1 + max(dig_count(x), dig_count(y)).
		if(t_high > Max)
		{
			// num1.high is a little too big, shrink it.
			t_high /= 10;
			num1.high /= 10;
		}

		num0.high = num1.high;
		num1.high = t_high;
	}
#else	// Another approach, amazing.
	for(; ; )
	{
		++result;
		// It's easy to handle the low-9 digits.
		Pair::Number t_low = num1.low;
		num1.low = (num1.low + num0.low) % Sieve;
		num0.low = t_low;

		if(PanHelper(num1.low))
		{
			// F(n) = ((phi ^ n) / sqrt(5.0)).
			// phi = (1 + sqrt(5)) / 2, 黄金分割.
			// 设 l_10 = log10(F(n))
			// 然后计算
			// pow(10, 8.0 + (l_10的小数部分)).
			// 因为是10的乘方,所以非000项都是由10的小数次方产生的.
			// 当n足够大时,这个值非常接近F(n).
			// log(pi) = 0.20898764024997873.
			// log(sqrt(5)) = 0.3494850021680094.
			const double t = (result * 0.20898764024997873 - 0.3494850021680094);
			num1.high = (Pair::Number)pow(10, t - (Pair::Number)t + 8.0);
			if(PanHelper(num1.high))
				break;
		}
	}
#endif
	return result;
}
Esempio n. 2
0
    //*******************************************************************
    // The following visitor functions deal with detecting Z's in the
    // logic, stripping the Z's out and creating an __en signal and its
    // logic.
    //*******************************************************************
    virtual void visit(AstPull* nodep, AstNUser*) {
        // replace any pullup/pulldowns with assignw logic and an __en
        // signal just like it is any other tristate signal.  The only
        // difference is that the user2() variable on the __en signal
        // will be given a pull direction--i.e. pulldown=1, pullup=2.
        // This will signal the driver exansion logic to put a default
        // pullup or pulldown state on the tristate bus under the high-Z
        // condition when no one is driving the bus.  Given the complexity
        // of merging tristate drivers at any level, the current limitation
        // of this implementation is that a pullup/down gets applied
        // to all bits of a bus and a bus cannot have drivers in opposite
        // directions on indvidual pins.
        AstNode* outp = nodep->lhsp()->unlinkFrBack();;
        AstVarRef* outrefp = NULL;
	int width=-1;
	if (outp->castVarRef()) {
	    outrefp = outp->castVarRef();
	} else if (outp->castSel()) {
	    outrefp = outp->castSel()->fromp()->castVarRef();
	    width = outp->castSel()->widthConst();
	} else {
	    nodep->v3error("Can't find LHS varref");
	}
	outrefp->lvalue(true);
	AstVar* varp = outrefp->varp();
	if (width==-1) width=varp->width();

        V3Number num0 (nodep->fileline(), width);
	num0.setAllBits0();
	V3Number num1 (nodep->fileline(), width);
	num1.setAllBits1();

	AstConst* enrhsp = new AstConst(nodep->fileline(), num0);
	AstVar* enp = createEnableVar(outp, outrefp, enrhsp, width, "pull");
	enp->user2(nodep->direction()+1); // record the pull direction

	AstAssignW* newassp = new AstAssignW(nodep->fileline(), outp,
					     new AstConst(nodep->fileline(), nodep->direction() ? num1 : num0));
	nodep->replaceWith(newassp);
	nodep->deleteTree(); nodep=NULL;
	newassp->iterateChildren(*this);
    }