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; }
//******************************************************************* // 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); }