Skip to content

Commit ce13ba2

Browse files
cawpatCallum Gibbonspivovarit
authored
SCALA-728: Find Twos Complement of Number (#1242)
* SCALA-728: Find Twos Complement of Number * SCALA-728: Corrected variable name * SCALA-728: Corrected variable name * Update TwosComplementTest.scala * Update TwosComplementTest.scala --------- Co-authored-by: Callum Gibbons <[email protected]> Co-authored-by: Grzegorz Piwowarek <[email protected]>
1 parent 8614a01 commit ce13ba2

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package com.baeldung.scala.twoscomplement
2+
3+
import scala.annotation.tailrec
4+
5+
object TwosComplement {
6+
def convertWithFold(bin: String): String = {
7+
addOneWithFold(onesComplement(bin))
8+
}
9+
10+
def convertUsingRecursion(bin: String): String = {
11+
addOneWithRec(onesComplement(bin))
12+
}
13+
14+
private def onesComplement(bin: String): String = {
15+
bin.map {
16+
case '1' => '0'
17+
case '0' => '1'
18+
}
19+
}
20+
21+
private def addOneWithFold(bin: String): String = {
22+
bin.reverse
23+
.foldLeft((true, ""))((added, bit) => {
24+
val (needsAdding, acc) = added
25+
if (needsAdding) {
26+
if (bit == '0') (false, acc + '1') else (true, acc + '0')
27+
} else {
28+
(false, acc + bit)
29+
}
30+
})
31+
._2
32+
.reverse
33+
}
34+
35+
private def addOneWithRec(bin: String): String = {
36+
@tailrec
37+
def addOne(needsAdding: Boolean, acc: String)(binString: String): String = {
38+
if (needsAdding) {
39+
binString match
40+
case "" => acc
41+
case _ => {
42+
val (bit, tail) = binString.splitAt(1)
43+
if (bit == "0") addOne(false, acc + '1')(tail.mkString)
44+
else addOne(true, acc + '0')(tail.mkString)
45+
}
46+
} else {
47+
acc + binString
48+
}
49+
}
50+
51+
addOne(true, "")(bin.reverse).reverse
52+
}
53+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package com.baeldung.scala.twoscomplement
2+
3+
import org.scalatest.flatspec.AnyFlatSpec
4+
import org.scalatest.matchers.should.Matchers
5+
6+
class TwosComplementTest extends AnyFlatSpec with Matchers {
7+
8+
val testExamples = List(
9+
("00110100", "11001100"),
10+
("00110101", "11001011"),
11+
("01111101", "10000011"),
12+
("00000000", "00000000"),
13+
("01111111", "10000001")
14+
)
15+
16+
"convertWithFold" should "convert binary to twos complement" in {
17+
val comparer = compare(TwosComplement.convertWithFold)
18+
comparer(testExamples)
19+
}
20+
21+
"convertUsingRecursion" should "convert binary to twos complement" in {
22+
val comparer = compare(TwosComplement.convertUsingRecursion)
23+
comparer(testExamples)
24+
}
25+
26+
private def compare(
27+
fn: String => String
28+
)(tests: List[(String, String)]): Unit = {
29+
tests.foreach((input, expected) => fn(input) shouldBe expected)
30+
}
31+
}

0 commit comments

Comments
 (0)