欣迪

最近做了一些 HackerRank 的線上測驗和教學。

因為之前刷了一些 LetCode 的題目,所以會覺得這邊的題目都比較偏簡單。不過還是有一些題目,尤其是針對 JS 的特性出題,蠻有參考價值。 這邊也稍微分享一下心得。

題目出處: https://www.hackerrank.com/challenges/js10-binary-calculator?isFullScreen=true&hr_b=1

Objective

In this challenge, we implement a calculator that uses binary numbers. Check out the attached tutorial for learning materials.

Task

Implement a simple calculator that performs the following operations on binary numbers: addition, subtraction, multiplication, and division. Note that division operation must be integer division only; for example, , , and .

The calculator’s initial state must look like this:

image
  • Element IDs. Each element in the document must have an id, specified below:innerHTMLidDescription/BehaviorresContains the result of button presses.btnsA button container that displays all eight calculator buttons.0btn0A button expressing binary digit .1btn1A button expressing binary digit .CbtnClrA button to clear the contents of .=btnEqlA button to evaluate the contents of the expression in .+btnSumA button for the addition operation.-btnSubA button for the subtraction operation.*btnMulA button for the multiplication operation./btnDivA button for the integer division operation.
  • Styling. The document’s elements must have the following styles:
    • body has a width of 33%.
    • res has a background-color of lightgray, a border that is solid, a height of 48px, and a font-size of 20px.
    • btn0 and btn1 have a background-color of lightgreen and a color of brown.
    • btnClr and btnEql have a background-color of darkgreen and a color of white.
    • btnSumbtnSubbtnMul, and btnDiv have a background-color of black, a color of red.
    • All the buttons in btns have a width of 25%, a height of 36px, a font-size of 18pxmargin of 0px, and float value left.

The .js and .css files are in different directories, so use the link tag to provide the CSS file path and the script tag to provide the JS file path:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="css/binaryCalculator.css" type="text/css">
    </head>
    
    <body>
    	<script src="js/binaryCalculator.js" type="text/javascript"></script>
    </body>
</html>

Constraints

  • All expressions in the test dataset are entered in the form , where  is the first binary number,  is the second binary number, and  is in the set .
  • Both operands will always be positive integers when converted from base- to base-.
  • All expressions will be valid.

Explanation

Consider the following sequence of button clicks:

Before pressing the  button, the result div looks like this:

27+8

After pressing the  button to evaluate our expression, the result div looks like this:

27+8eval

Notice that , , and , so our calculator evaluated the expression correctly.

Now, let’s consider our next sequence of button clicks as:

Before pressing the  button, the result div looks like this:

141x7

After pressing the  button to evaluate our expression, the result div looks like this:

141x7eval

Consider the next sequence of button clicks as:

The result div looks like this:

clear3

See the Pen
HackerRank > 10 Days of Javascript > Day 9: Binary Calculator
by Dean (@hcd1983)
on CodePen.0

我的作法,僅限於乖乖輸入正確的計算式,例如 “1+1“ , 如果出現 “1++1” 或是 “-1-1+”,會把錯誤印在 res。

怎麼做二進位的的計算

假設我們現在要計算 101 + 100

1. 把數字變成十進位

首先,我們必須把輸入的數字從二進位變成 10 進位。這邊可以用 parseInt 這個內建 function。

參考 developer.mozilla.org 上的解釋 : https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/parseInt

const num1 = parseInt(101, 2) // 5
const num2 = parseInt(100, 4) // 4
const ans = num1 + num2 //9

上述方法可以先把,數字轉為 10 進位再計算。

2.把數字變成二進位的文字

使用 Number.prototype.toString()

參考: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toString

當物件型別是 number 時,toString 的參數為代表該進位系統的數字。例如說指定 10 就等於指定十進位。

const num1 = parseInt(101, 2) // 5
const num2 = parseInt(100, 4) // 4
const ans = (num1 + num2).toString(2) // 轉為二進位文字, 這邊是 9 => "1001"

這樣就搞定基本的計算功能了。

怎麼把一串文字變成計算結果

假設現在我們有一串字串 “111+111″,怎麼把去計算出結果呢?

js 有一個危險的函數 eval 會將傳入的字符串當做 JavaScript 代碼進行執行。雖然危險,但在這邊非常好用。

const str = "111+111"
eval(str) // return 222

但是這是十進位的啊。

要怎麼把 “111” 轉換成二進位的再用 eval 得到結果呢?
先把預期執行的 code 寫一遍

const str = "111+111"

// 我們希望它變成
const strFixed = "parseInt(111, 2) + parseInt(111, 2)"

用 .replace 和 Regular Expressions 來搞定吧

用 .replace 方法找出所有的連續數字,然後將它取代成 parseInt( 數字, 2),再用 eval 執行吧。

const str = "111+111"

const strFixed = str.replace(/[0-9]+/g, 'parseInt($&, 2)') 
// return 'parseInt(111, 2)+parseInt(111, 2)'

let ans = eval(strFixed)
// 14

ans = ans.toString(2)
// 轉成二進位字串
// "1110"

到這邊為止,所有計算的重點都已經搞定,接下來就是把計算方式和介面串接起來。直接參考上面的 CodePen 吧。

訂閱 IT-Monk

訂閱最新文章的發布消息! 😚😚😚
Loading

作者介紹 - 欣迪

欣迪

從設計到寫程式,發現自己有追求前端技巧的自虐傾向。不斷的踩坑,再從坑裡爬出來,慢慢對攀岩有點心得。 目前在多間公司擔任網站設計顧問。 同時也是網站架設公司負責人。