JSFiddle - React, Tailwind, and code Playground

Fibonacci

by Terry Young

HTML

<div id="generator" class="container">
    <div class="caption">Fibbonaci Sequence Generator</div>
    <div class="bar">
        <div class="slider">
            <label>Animation Speed</label>
            <div class="control"></div>
        </div>
        <span class="status"></span>
    </div>
    <div class="numbers"></div>
</div>

<div id="calculator" class="container">
    <div class="caption">Fibbonaci Calculator</div>
    <div class="bar">
        <label>Find the</label>
        <input type="text" class="input" value="1" />
        <label><span class="nth">st</span> number of the Fibbonaci Sequence</label>
    </div>
    <textarea class="output"></textarea>
</div>

<div id="validator" class="container">
    <div class="caption">Fibbonaci Validator</div>
    <div class="bar">
        <label>Type a number below to see if it is a number from the Fibbonaci Sequence</label>
    </div>
    <div class="bar results">
        No
    </div>
    <textarea class="input"></textarea>
</div>

CSS

html, body {
    width:100%;
    height:100%;
    margin:0;
    border:0;
    padding:10px;
    /*overflow:hidden;*/
}

/* font */
html, body, input, textarea, .ui-tooltip, .ui-tooltip-content, .ui-spinner-input {
    font-family: Consolas, Geneva, Tahoma !important;
    font-size: 9pt !important;
    outline:none !important;
}

.ui-tooltip, .ui-tooltip-content {
    width:auto;
}

#generator {
    height: 250px;
}
#calculator {
    height:155px;
}
#validator {
    height:155px;
}
.container {
    width:90%;
    margin:auto auto;   
    border: 1px solid black;
    padding: 1px;
}
.caption {
    height:1em;
    background-color: darkblue;
    color: white;
    padding:10px;
    margin:0px;
}
.bar {
    height:1em;
    border-bottom: 1px dotted black;
    padding:10px;
    margin:0px;
}
.bar .slider {
    float: left;
    width:340px;
}
.bar .slider label {
    display:block;
    margin-right: 20px;
    float:left;
}
.bar .control {
    float:left;
    width:200px;
}
.bar .status {
    margin: 10px;
}
.numbers {
    height:165px;
    padding:10px;
    margin:0px;
    overflow:auto;
}

.number {
    color:black;
}

.numbers span {
    background-color: #ededed;
    color: gray;
    padding:5px;
    margin:3px;
    float:left;
    overflow:hidden;
    cursor: default;
}

.numbers span:hover {
    background-color: darkblue;
    color: white;
}

.numbers span.current,
.numbers span.operator {
    background-color: pink;
    text-align: center;
    color: red;
    font-weight: bold;
}

.numbers span.last {
    background-color: lightgreen;
    color: darkgreen;
    font-weight:bold;
}

#calculator textarea {
    margin: 1px 0 0 -1px;
    padding:0;
    display:block;
    border:0;
    outline:none;
    width:100%;
    height:80px;
}

#calculator .bar {
    height:1.5em;
    vertical-align:middle;
}

JavaScript

/**
 * Used by fib(), performs Big Integer addition to derive the next number in the 
 * Fibonnaci sequence 
 * (returns as an array of numbers per digit)
 */
function add(a, b) {
    while (a.length < b.length) a.unshift(0);
    while (a.length > b.length) b.unshift(0);
    var carry = 0, sum = []
    for (var i = a.length - 1; i >= 0; i--) {
        var s = a[i] + b[i] + carry;
        if (s >= 10) {
            s = s - 10;
            carry = 1;
        } else {
            carry = 0;
        }
        sum.unshift(s);
    }
    if (carry)
        sum.unshift(carry);
    return sum;
}

/**
 * Returns the n-th number in the Fibonnaci sequence
 * Usage: var x = fib(4000); // return the 4000th number in the Fibonnaci sequence
 */
function fib(n) {
    var f1 = [0];
    var f2 = [1];

    while (n--) {
        var f3 = add(f1, f2);
        f1 = f2;
        f2 = f3;
    }
    return f1.join("");
}

/**
 * Namespace for configs and generated results
 */
var f = {
    lim: Infinity, // sequence limit. (Either a positive Integer or the Infinity object)
    c: 0, // current iteration
    n: [], // numbers only,
    ms: [], // milliseconds it took to calculate
    t: [], // div.number elements
    
    paused: false, // reserved
    
    f: 150, // animation sequence speed,
    s: 150, // slide speed
    fx: {
            effect: 'slide',
            direction: 'left',
            duration: 100
        },
    scrollMargin: 60,
    opHide: {width:0, marginLeft: 0, marginRight: 0, borderLeft: 0, borderRight: 0},
    opShow: {width:12, marginLeft: 3, marginRight: 3, borderLeft: 5, borderRight: 5}
};

/**
 * Pre-process the next number in the Fibonnaci sequence
 */
function nextFib () {
    var start = new Date(),
        x = fib(++f.c),
        end = new Date(),
        diff = end - start;
    f.n[f.c] = x;    
    f.ms[f.c] = diff;
}

/**
 * Animate the addition of the current and previous numbers 
 * in the Fibonnaci sequence
 */
function showAddition (undefined) {
   ...