Appendix B: Practice - hochan222/Everything-in-JavaScript GitHub Wiki

Closure (PART 1)

λ‹€μŒ ν”„λ‘œκ·Έλž¨μ€ λΉ„νš¨μœ¨μ μ΄λ‹€. ν΄λ‘œμ €μ™€ λ©”λͺ¨μ΄μ œμ΄μ…˜μ„ μ΄μš©ν•˜μ—¬ 효율적인 ν”„λ‘œκ·Έλž¨μœΌλ‘œ λ§Œλ“œμ‹œμ˜€.

isPrime(11); // true
isPrime(12); // false
factorize(11); // [ 11 ]
factorize(12); // [ 3, 2, 2 ] --> 3*2*2=12
function isPrime(v) { 
    if (v <= 3) {
        return v > 1; 
    }
    if (v % 2 == 0 || v % 3 == 0) { 
        return false;
    }

    var vSqrt = Math.sqrt(v);
    for (let i = 5; i <= vSqrt; i += 6) {
        if (v % i == 0 || v % (i + 2) == 0) { 
            return false;
        } 
    }
    return true; 
}
function factorize(v) { 
    if (!isPrime(v)) {
        let i = Math.floor(Math.sqrt(v)); 
        while (v % i != 0) {
            i--; 
        }
        return [ 
            ...factorize(i),
            ...factorize(v / i) 
        ];
    }
    return [v]; 
}
πŸ“„ 닡지
function isPrime(v) { 
    if (v <= 3) {
        return v > 1; 
    }
    if (v % 2 === 0 || v % 3 === 0) { 
        return false;
    }

    var vSqrt = Math.sqrt(v);
    for (let i = 5; i <= vSqrt; i += 6) {
        if (v % i === 0 || v % (i + 2) === 0) { 
            return false;
        } 
    }
    return true; 
}

var factorize = (function (v) {
    var cache = {};
    
    var fac = function (v) { 
        console.log(cache)
        if (cache[v.toString()])
            return [v];
        if (!isPrime(v)) {
            let i = Math.floor(Math.sqrt(v)); 
            while (v % i !== 0) {
                i--; 
            }
            return [ 
                ...fac(i),
                ...fac(v / i) 
            ];
        }
        cache[v.toString()] = true;
        return [v]; 
    }
    
    return (fac);
})();

console.log(isPrime(11));
console.log(isPrime(12));
console.log(factorize(11));
console.log(factorize(12));
console.log(factorize(4327));
console.log(factorize(4327));
console.log(factorize(4327));
console.log(factorize(4327));

Output

true
false
{}
[ 11 ]
{ '11': true }
{ '11': true }
{ '3': true, '11': true }
{ '3': true, '11': true }
{ '2': true, '3': true, '11': true }
[ 3, 2, 2 ]
{ '2': true, '3': true, '11': true }
[ 4327 ]
{ '2': true, '3': true, '11': true, '4327': true }
[ 4327 ]
{ '2': true, '3': true, '11': true, '4327': true }
[ 4327 ]
{ '2': true, '3': true, '11': true, '4327': true }
[ 4327 ]

Closure (PART 2)

λ‹€μŒ ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•΄μ£Όμ„Έμš”! ν΄λ‘œμ €λ₯Ό μ΄μš©ν•΄μ„œ.

function toggle(/* .. */) { 
    // ..
}

var hello = toggle("hello");
var onOff = toggle("on","off");
var speed = toggle("slow","medium","fast");

hello(); // "hello"
hello(); // "hello"

onOff(); // "on"
onOff(); // "off"
onOff(); // "on"

speed(); // "slow"
speed(); // "medium"
speed(); // "fast"
speed(); // "slow"
πŸ“„ 닡지
function toggle(...argv) { 
    let index = 0;
    let mod = argv.length;
    return function toggleLogic() {
        console.log(argv[index++%mod]);
    };
}

var hello = toggle("hello");
var onOff = toggle("on","off");
var speed = toggle("slow","medium","fast");

hello(); 
hello(); 

onOff(); 
onOff(); 
onOff(); 

speed(); 
speed(); 
speed(); 
speed(); 

Closure (PART 3)

κΈ°λ³Έ 계산기λ₯Ό λ§Œλ“€μ–΄λ³΄μž. μ†Œμˆ˜μž…λ ₯은 μ§€μ›λ˜μ§€ μ•ŠλŠ”λ‹€. +, -, /, %, *, = 을 μ§€μ›ν•œλ‹€.
μŒμˆ˜λŠ” λ‚˜μ˜¬ 수 μžˆλ‹€. 10μ§„μˆ˜ 계산 κ°€λŠ₯ν•΄μ•Όν•œλ‹€. 계산기 λ™μž‘μ„ λ”°λΌν•΄μ•Όν•œλ‹€.

function calculator() { // ..
}

var calc = calculator();
calc("4");  // 4 
calc("+");  // + 
calc("7");  // 7
calc("3");  // 3 
calc("-");  // - 
calc("2");  // 2 
calc("=");  // 75 
calc("*");  // * 
calc("4");  // 4 
calc("=");  // 300 
calc("5");  // 5 
calc("-");  // - 
calc("5");  // 5 
calc("=");  // 0

μ²˜μŒλΆ€ν„° λ‹€μ§œλ©΄ νž˜λ“œλ‹ˆκΉŒ λ„μ›€μ΄λ˜λŠ” ν•¨μˆ˜λ₯Ό μ£Όκ² λ‹€.

function useCalc(calc,keys) { 
    return [...keys].reduce(
        function showDisplay(display,key){ 
            var ret = String( calc(key) ); 
            return (
                display + 
                (
                  (ret != "" && key == "=") ?
                      "=" :
                      ""
                  )+
                  ret 
            );
        },
        ""
    ); 
}

useCalc(calc,"4+3=");    // 4+3=7
useCalc(calc,"+9=");     // +9=16
useCalc(calc,"*8=");     // *5=128
useCalc(calc,"7*2*3=");  // 7*2*3=42
useCalc(calc,"1/0=");    // 1/0=ERR
useCalc(calc,"+3=");     // +3=ERR
useCalc(calc,"51=");     // 51

계산기 ν‘œμ€€ 좜λ ₯ ν˜•μ‹μ΄ ν•„μš”ν•˜λ‹€. μ•„λž˜μ™€ 같은 ν•¨μˆ˜λ₯Ό μ‚¬μš©ν•˜λ©΄λœλ‹€. λ™μž‘μ€ 크게 μ‹ κ²½ μ“°μ§€λ§μž. 음수 e처리 11자리 μ²˜λ¦¬λ“±μ— κ΄€ν•œκ²ƒμ΄λ‹€.

function formatTotal(display) {
    if (Number.isFinite(display)) {
        // constrain display to max 11 chars
        let maxDigits = 11;
        // reserve space for "e+" notation? 
        if (Math.abs(display) > 99999999999) {
            maxDigits -= 6; 
        }
        // reserve space for "-"?
        if (display < 0) { 
             maxDigits--;
        }

        // whole number?
        if (Number.isInteger(display)) { 
            display = display
                .toPrecision(maxDigits) 
                .replace(/\.0+$/,"");
        }
        // decimal
        else {
            // reserve space for "." 
            maxDigits--;
            // reserve space for leading "0"? 
            if (
                Math.abs(display) >= 0 &&
                Math.abs(display) < 1 
            ){
                maxDigits--; 
            }
            display = display 
                .toPrecision(maxDigits) 
                .replace(/0+$/,"");
            } 
        }
        else {
            display = "ERR";
        }
    return display; 
}
πŸ“„ 닡지
function formatTotal(display) {
    if (Number.isFinite(display)) {
        // constrain display to max 11 chars
        let maxDigits = 11;
        // reserve space for "e+" notation? 
        if (Math.abs(display) > 99999999999) {
            maxDigits -= 6; 
        }
        // reserve space for "-"?
        if (display < 0) { 
             maxDigits--;
        }

        // whole number?
        if (Number.isInteger(display)) { 
            display = display
                .toPrecision(maxDigits) 
                .replace(/\.0+$/,"");
        }
        // decimal
        else {
            // reserve space for "." 
            maxDigits--;
            // reserve space for leading "0"? 
            if (
                Math.abs(display) >= 0 &&
                Math.abs(display) < 1 
            ){
                maxDigits--; 
            }
            display = display 
                .toPrecision(maxDigits) 
                .replace(/0+$/,"");
            } 
        }
        else {
            display = "ERR";
        }
    return display; 
}
function calculator() { 
    let total = 0;
    let nbr = "";
    let operator = '';
    let is_equal = 0;
    
    return function calc(key) {
        if (is_equal) {
            is_equal = 0;
            if (is_number(key)) {
                total = 0;
                operator = '';
            }
        }
        if (is_number(key)) {
            nbr += key;
            return (key);
        }
        if (is_operator(key)) {
            if (operator === '') {
                total = Number(nbr);
                nbr = "";
                return (operator = key);
            }
            total = calc_operator(total, operator, Number(nbr));
            nbr = "";
            return (operator = key);
        }
        if (key === '=') {
            if (operator === '') {
                total = Number(nbr);
            } else {
                total = calc_operator(total, operator, Number(nbr));
                is_equal = 1;
                nbr = "";
            }
            return (formatTotal(total));
        }
        return "";
    }
    
    function is_number(str) {
        if (str >= '0' && str <= '9')
            return (true);
        return (false);
    }
    
    function is_operator(str) {
        if (str === '+' || str === '-'
        || str === '/' || str === '%'
        || str === '*')
            return (true);
        return (false);
    }
    
    function calc_operator(total, operator, num) {
        let result = 0;
        
        if (operator === '+')
            result = total + num;
        if (operator === '/')
            result = total / num;
        if (operator === '%')
            result = total % num;
        if (operator === '-')
            result = total - num;
        if (operator === '*')
            result = total * num;
        return (result);
    }
}

var calc = calculator();

function useCalc(calc, keys) { 
    return [...keys].reduce(
        function showDisplay(display, key){ 
            var ret = String( calc(key) ); 
            return (
                display + 
                (
                  (ret != "" && key == "=") ?
                      "=" :
                      ""
                  )+
                  ret 
            );
        },
        ""
    ); 
}

console.log(useCalc(calc,"4+3="));    // 4+3=7
console.log(useCalc(calc,"+9="));     // +9=16
console.log(useCalc(calc,"*8="));     // *8=128
console.log(useCalc(calc,"7*2*3="));  // 7*2*3=42
console.log(useCalc(calc,"1/0="));    // 1/0=ERR
console.log(useCalc(calc,"+3="));     // +3=ERR
console.log(useCalc(calc,"51="));     // 51

⚠️ **GitHub.com Fallback** ⚠️