From c4572b7a50c1f17212ce6717f1f2338dc7acf184 Mon Sep 17 00:00:00 2001 From: torosediles Date: Tue, 14 May 2024 20:21:09 +0200 Subject: [PATCH] h 2.0 --- implementation/romans.js | 105 +++++++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 31 deletions(-) diff --git a/implementation/romans.js b/implementation/romans.js index 8a5645a..555fd0a 100644 --- a/implementation/romans.js +++ b/implementation/romans.js @@ -3,32 +3,33 @@ const INVALID_ROMAN = 'Please enter a valid roman'; const INVALID_INTEGER = 'Please enter a valid integer'; const OUT_OF_RANGE = 'Out of range (1-3999)'; -function init() { - +function init() { + // Load elements once to avoid repetition on every invocation - var modeCheckbox = document.querySelector('input[type="checkbox"]'); + var modeCheckbox = document.querySelector('input[type=\'checkbox\']'); var header = document.querySelector('h1'); var convertButton = document.querySelector('.convert-button'); var outputArea = document.querySelector('.convert-output'); - var inputArea = document.querySelector('input[type="text"]'); + var inputArea = document.querySelector('input[type=\'text\']'); - const getModeTitle = (integerToRoman) => { - return integerToRoman ? 'Integer To Roman' : 'Roman To Integer'; - }; - modeCheckbox.addEventListener('change', (e) => { + modeCheckbox.addEventListener('change', function(e) { header.innerHTML = getModeTitle(e.target.checked); }); + const getModeTitle = function(integerToRoman) { + return integerToRoman ? 'Integer To Roman' : 'Roman To Integer'; + }; + // Now, the convertion operation does only perform the operation. // Things we have extracted to this listener: // 1 - Read the UI inputs (inputArea.value) // 2 - Write the UI output (outputArea.innerHTML) // 3 - Show error messages // This is cleaner and also removes code duplications - convertButton.addEventListener('click', () => { - let inputValue = inputArea.value; - let convertion = modeCheckbox.checked ? convertIntegerToRoman(inputValue) : convertRomanToInteger(inputValue); + convertButton.addEventListener('click', function() { + var inputValue = inputArea.value; + var convertion = modeCheckbox.checked ? convertIntegerToRoman(inputValue) : convertRomanToInteger(inputValue); if (convertion.result) { outputArea.innerHTML = convertion.value; } else { @@ -43,12 +44,12 @@ function init() { // On top of that, they return a JSON object instead of updating the // UI directly. The JSON object contains the result (ok/nok), the value // and an error message if needed -const convertRomanToInteger = (roman) => { +const convertRomanToInteger = function(roman) { - let response = { - value: 0, + var response = { + value: 0, message: '', - result: false + result: false }; // Regexp to check if a string is a valid roman number @@ -66,9 +67,9 @@ const convertRomanToInteger = (roman) => { return response; } - let arr = ['I', 'V', 'X', 'L', 'C', 'D', 'M']; + var arr = ['I', 'V', 'X', 'L', 'C', 'D', 'M']; - let values = { + var values = { I: 1, V: 5, X: 10, @@ -78,11 +79,11 @@ const convertRomanToInteger = (roman) => { M: 1000, }; - let sum = 0; + var sum = 0; - let prevIndex = 0; + var prevIndex = 0; - for (let i = roman.length - 1; i >= 0; i--) { + for (var i = roman.length - 1; i >= 0; i--) { if (arr.indexOf(roman[i]) >= prevIndex) { sum = sum + values[roman[i]]; } else { @@ -103,12 +104,12 @@ const convertRomanToInteger = (roman) => { // On top of that, they return a JSON object instead of updating the // UI directly. The JSON object contains the result (ok/nok), the value // and an error message if needed -const convertIntegerToRoman = (num) => { +const convertIntegerToRoman = function(num) { - let response = { + var response = { value: 0, - message: '', - result: false + message: '', + result: false }; // Regexp to check the input is a valid integer @@ -125,7 +126,7 @@ const convertIntegerToRoman = (num) => { // Integer not in the supported range -> exit with the right message if (Number(num) > 3999 || Number(num) < 1) { response.message = OUT_OF_RANGE; - return response; + return response; } const mapping = { @@ -138,10 +139,10 @@ const convertIntegerToRoman = (num) => { 1000: 'M', }; - let count = 1; - let str = ''; + var count = 1; + var str = ''; while (num > 0) { - let last = parseInt(num % 10); + var last = parseInt(num % 10); last *= count; if (last < 10) { str += lessThan9(last, mapping); @@ -159,7 +160,7 @@ const convertIntegerToRoman = (num) => { return response; }; -const lessThan9 = (num, obj) => { +const lessThan9 = function(num, obj) { if (num === 9) { return obj[1] + obj[10]; } else if (num >= 5 && num < 9) { @@ -171,7 +172,7 @@ const lessThan9 = (num, obj) => { } }; -const greaterThan9 = (num, obj) => { +const greaterThan9 = function(num, obj) { if (num >= 10 && num < 50) { if (num === 10) { return obj[10]; @@ -216,8 +217,50 @@ const greaterThan9 = (num, obj) => { if (num === 1000) { return obj[1000]; } - return obj[1000].repeat(parseInt(num / 1000)); } }; +if (!String.prototype.repeat) { + String.prototype.repeat = function(count) { + 'use strict'; + if (this == null) { + throw new TypeError('can\'t convert ' + this + ' to object'); + } + var str = '' + this; + count = +count; + if (count != count) { + count = 0; + } + if (count < 0) { + throw new RangeError('repeat count must be non-negative'); + } + if (count == Infinity) { + throw new RangeError('repeat count must be less than infinity'); + } + count = Math.floor(count); + if (str.length == 0 || count == 0) { + return ''; + } + // Ensuring count is a 31-bit integer allows us to heavily optimize the + // main part. But anyway, most current (August 2014) browsers can't handle + // strings 1 << 28 chars or longer, so: + if (str.length * count >= 1 << 28) { + throw new RangeError('repeat count must not overflow maximum string size'); + } + var rpt = ''; + for (;;) { + if ((count & 1) == 1) { + rpt += str; + } + count >>>= 1; + if (count == 0) { + break; + } + str += str; + } + // Could we try: + // return Array(count + 1).join(this); + return rpt; + }; +}