I Have a series of tests that need to pass one of them includes deleting the buffer between the defined region (which is between the marker and cursor) and inserting the cut text in the paste. I then need to set the cursor and marker to the beginning of the cut text (see below code for a better understanding)
class Buffer(s: String) {
import scala.collection.mutable.StringBuilder
import scala.io.StdIn
private var buffer: StringBuilder = new StringBuilder(s)
private var cursor: Int = 0 // cursor is in between characters
private var marker: Int = 0 // marker is in between characters
private var paste: String = ""
private def end: Int = buffer.length // the end of the line
private def lwr: Int = Math.min(marker, cursor)
private def upr: Int = Math.max(marker, cursor)
/*
* Accessor methods to return aspects of the state
*/
def getCursor: Int = cursor
def getMarker: Int = marker
def getString: String = buffer.toString
def getPaste: String = paste
Delete the contents of the defined region and save the cut string in the paste
buffer. This operation re-sets the cursor and the marker to the start of the
cut text. For example:
B U F F E R marker = 1
^ ^ cursor = 4
Then perform xd()
B E R marker = 1
^ cursor = 1
*/
I have written some code:
def xd() {
paste = buffer.substring(lwr, upr)
buffer = buffer.delete(lwr, upr)
cursor = end
marker = end
}
this seems to pass the other tests but does not set the marker and cursor.
Any suggestions please?
First in Scala you would try to have no mutable state (var).
Here is a solution for cut and paste that is immutable:
case class Buffer(s: String, paste: String, private val cursor: Int = 0, private val marker: Int = 0) {
def mark(str: String): Buffer = {
val startIndex = s.indexOf(str)
val endIndex = startIndex + str.length
Buffer(s, startIndex, endIndex)
}
def cut(): Buffer = {
Buffer(s.take(cursor) + s.drop(marker), // rest of the String
s.take(marker).drop(cursor)) // paste of the String
}
}
You can use it like this:
Buffer("hello there") // > Buffer(hello there,,0,0)
.mark("o t") // > Buffer(hello there,,4,7)
.cut() // > Buffer(hellhere,o t,0,0)
You see the result of each line.
Let me know if you need more support or if I misunderstood you.
Related
I am writing a Caesar Cipher in Scala 3, I am writing an expression/function that iterates through each character of a string. Upon each iteration each character is converted to a ascii value, shifted, then converted back to character. The function prints, however the output terminates in "()" ...
import scala.io.StdIn.readLine
var message: String = "";
var shift: Int = 1;
def encrypt(messageToDecrypt: String, shiftAmt: Int): Unit =
var msgLen = messageToDecrypt.length
var dcrytArray = messageToDecrypt.toCharArray
var i : Int = 0
var shiftedCharArray = for i <- dcrytArray do print(((i.toInt + shiftAmt - 97) % 26 + 97).toChar)
#main def CeasarCipher(args: String*): Unit =
println("enter a phrase to encrypt: ")
var message = readLine()
var encryptedmessage = encrypt(message, shift)
println(encryptedmessage)
Why is the output terminating with "( )"? and how can I resolve?
Please don't use vars, arrays, mutable structures, and procedural loops, it hurts my eyes :( If you are going to spend time learning scala, might as well learn using it in the right way.
def shift(amt: Int)(x: Char) = ((x + amt - 97)%26+97).toChar
println(encryptedMessage.map(shift(shiftAmt)))
i got it, you have to use "yield" rather than "do" in the for loop
import scala.io.StdIn.readLine
var message: String = "";
var shift: Int = 1;
def encrypt(messageToDecrypt: String, shiftAmt: Int): String =
var msgLen = messageToDecrypt.length
var dcrytArray = messageToDecrypt.toCharArray
var i : Int = 1
var shiftedCharArray = for i <- dcrytArray yield ((i.toInt + shiftAmt - 97) % 26 + 97).toChar
shiftedCharArray.mkString("")
#main def CeasarCipher(args: String*): Unit =
println("enter a phrase to encrypt: ")
var message = readLine()
var encryptedmessage = encrypt(message, shift)
println(encryptedmessage)
class Buffer(s: String) {
import scala.collection.mutable.StringBuilder
import scala.io.StdIn
private var buffer: StringBuilder = new StringBuilder(s)
private var cursor: Int = 0 // cursor is in between characters
private var marker: Int = 0 // marker is in between characters
private var paste: String = ""
private def end: Int = buffer.length // the end of the line
private def lwr: Int = Math.min(marker, cursor)
private def upr: Int = Math.max(marker, cursor)
/*
* Accessor methods to return aspects of the state
*/
def getCursor: Int = cursor
def getMarker: Int = marker
def getString: String = buffer.toString
def getPaste: String = paste
/**
* Delete Duplicate characters. Within the defined region, for each character,
* if it occurs once then keep it, but if it occurs multiple times then keep
* only the first occurrence. The characters to the left and right of the
* defined region remain unchanged, but within the defined region the duplicates
* are removed. This operation does not affect the paste buffer. The cursor is
* placed finally at the lower end of the defined region and the marker is placed
* finally at the upper end of the (probably reduced) defined region. For example:
*
* m i s s i s s i p p i marker = 1
* ^ ^ cursor = 10
*
* Then perform sc('a', 'X')
*
* m i s p i marker = 1
* ^ ^ cursor = 4
*/
def dd()
{
var droppedchars: Int = 0;
for (x <- lwr until upr)
{
var c = buffer.charAt(x)
for (i <- lwr until upr)
{
if (buffer.charAt(i) == c)
{
buffer.deleteCharAt(i)
droppedchars += 1
}
}
marker = lwr
cursor = upr - droppedchars
}
}
Need some help with this one too, doesn't appear to work
function needs to drop any duplicate chars it finds, move the marker back to the start of the new defined region and the cursor to the end of the new defined region, not asking for somebody to write this for me just guide me in the right direction
Why not just:
scala> "mississippi".distinct
res22: String = misp
What you're trying to do takes O(n^2) that is not very good from performance perspective...
Imo, a better one solution is use only one loop over the buffer and within it an each character c you should check with a set of characters (declared outside the for-loop):
val chars = scala.collection.mutable.Set[Char]()
...
for (x <- lwr until upr) {
var c = buffer.charAt(x)
if (chars contains c) buffer.deleteCharAt(x) else chars += c
}
cursor = marker + chars.size
My code is as follows:
class HuffmanNode(val chars: String, val occurrences: Int) {
override def toString: String = "{" + chars + "|" + occurrences + "}"
def absoluteValue: Int = occurrences
def getChars: String = chars
def getOccurrences: String = occurrences.toString
}
object HuffmanNode {
def apply(chars: String, occurrences: Int): HuffmanNode = {
new HuffmanNode(chars, occurrences)
}
}
I'm trying to create a list of HuffmanNode, e.g.:
val PQ: List[HuffmanNode] = List(HuffmanNode("a", 3), HuffmanNode("b", 3))
How do I access the methods inside the HuffmanNode?
I tried doing this:
PQ(0).getChars
But I get an error saying, unable to resolve symbol getChars.
What could the problem be?
Your code does not compile. If I would hazard a guess I would imagine that you are using a list of the singleton instead of an instance of the class (the singleton does not have a getChars method, only the apply).
If you change code as I suggested in edit, there is no problem to invoke getChars method:
class HuffmanNode(val chars: String, val occurrences: Int) {
override def toString: String = "{" + chars + "|" + occurrences + "}"
def absoluteValue: Int = occurrences
def getChars: String = chars
def getOccurrences: String = occurrences.toString
}
object HuffmanNode {
def apply(chars: String, occurrences: Int): HuffmanNode = {
new HuffmanNode(chars, occurrences)
}
}
val PQ: List[HuffmanNode] = List(HuffmanNode("a", 3), HuffmanNode("b", 3))
PQ(1).getChars
I got:
PQ: List[HuffmanNode] = List({a|3}, {b|3})
res0: String = b
However I needed (just to test) remove keyword override from absoluteValue method.
As pointed out by #Assaf Mendelson you refer to the singleton object instead of instance of the class.
In order to fix you code you should create instance of the class instead like:
val PQ = List(HuffmanNode("blabla", 2))
val chars = PQ(0).getChars // now compiles
I want to delete duplicate char in my string with using deleteCharAt method but it's giving me an exception
def removeDuplicate(str: String): String={
var sb = new StringBuilder(str);
for(i <-0 until str.length ){
for(z <- i+1 until str.length ){
if(str(i)==str(z)){
sb.deleteCharAt(i);
}
}
}
return sb.toString;}
As the error suggested, when i = str.length - 1, z = str.length which is out of index. And there is another problem with your code, which is you are removing character from a string while looping through it. It is usually not a good practice to do so since the string length changes every time you delete a character, and you need to keep track of that. An alternative and more intuitive way is to build a new string and add only characters that have not appeared in the new string:
def removeDuplicate(str: String):String = {
var sb = ""
for(i <- 0 until str.length) {
if(! (sb contains str(i))) {
sb += str(i)
}}
sb
}
scala> removeDuplicate("abbccssds")
res13: String = abcsd
scala> removeDuplicate("abbeedsff")
res14: String = abedsf
scala> removeDuplicate("abbeedsffgg")
res15: String = abedsfg
I want to take input from the user. Can you please tell me how to ask for user input as a string in Scala?
In Scala 2.11 use
scala.io.StdIn.readLine()
instead of the deprecated Console.readLine.
Here is a standard way to read Integer values
val a = scala.io.StdIn.readInt()
println("The value of a is " + a)
similarly
def readBoolean(): Boolean
Reads a Boolean value from an entire line from stdin.
def readByte(): Byte
Reads a Byte value from an entire line from stdin.
def readChar(): Char
Reads a Char value from an entire line from stdin.
def readDouble(): Double
Reads a Double value from an entire line from stdin.
def readFloat(): Float
Reads a Float value from an entire line from stdin.
def readInt(): Int
Reads an Int value from an entire line from stdin.
def readLine(text: String, args: Any*): String
Prints formatted text to stdout and reads a full line from stdin.
def readLine(): String
Reads a full line from stdin.
def readLong(): Long
Reads a Long value from an entire line from stdin.
def readShort(): Short
Reads a Short value from an entire line from stdin.
def readf(format: String): List[Any]
Reads in structured input from stdin as specified by the format specifier.
def readf1(format: String): Any
Reads in structured input from stdin as specified by the format specifier, returning
only the first value extracted, according to the format specification.
def readf2(format: String): (Any, Any)
Reads in structured input from stdin as specified by the format specifier, returning
only the first two values extracted, according to the format specification.
def readf3(format: String): (Any, Any, Any)
Reads in structured input from stdin as specified by the format specifier, returning
only the first three values extracted, according to the format specification.
Similarly if you want to read multiple user inputs from the same line ex: name, age, weight you can use the Scanner object
import java.util.Scanner
// simulated input
val input = "Joe 33 200.0"
val line = new Scanner(input)
val name = line.next
val age = line.nextInt
val weight = line.nextDouble
abridged from Scala Cookbook: Recipes for Object-Oriented and Functional Programming by Alvin Alexander
From the Scala maling list (formatting and links were updated):
Short answer:
readInt
Long answer:
If you want to read from the terminal, check out Console.scala.
You can use these functions like so:
Console.readInt
Also, for your convenience, Predef.scala
automatically defines some shortcuts to functions in Console. Since
stuff in Predef is always and everywhere imported automatically, you
can use them like so:
readInt
object InputTest extends App{
println("Type something : ")
val input = scala.io.StdIn.readLine()
println("Did you type this ? " + input)
}
This way you can ask input.
scala.io.StdIn.readLine()
You can take a user String input using readLine().
import scala.io.StdIn._
object q1 {
def main(args:Array[String]):Unit={
println("Enter your name : ")
val a = readLine()
println("My name is : "+a)
}
}
Or you can use the scanner class to take user input.
import java.util.Scanner;
object q1 {
def main(args:Array[String]):Unit={
val scanner = new Scanner(System.in)
println("Enter your name : ")
val a = scanner.nextLine()
println("My name is : "+a)
}
}
Simple Example for Reading Input from User
val scanner = new java.util.Scanner(System.in)
scala> println("What is your name") What is your name
scala> val name = scanner.nextLine()
name: String = VIRAJ
scala> println(s"My Name is $name")
My Name is VIRAJ
Also we can use Read Line
val name = readLine("What is your name ")
What is your name name: String = Viraj
In Scala 2:
import java.io._
object Test {
// Read user input, output
def main(args: Array[String]) {
// create a file writer
var writer = new PrintWriter(new File("output.txt"))
// read an int from standard input
print("Enter the number of lines to read in: ")
val x: Int = scala.io.StdIn.readLine.toInt
// read in x number of lines from standard input
var i=0
while (i < x) {
var str: String = scala.io.StdIn.readLine
writer.write(str + "\n")
i = i + 1
}
// close the writer
writer.close
}
}
This code gets input from user and outputs it:
[input] Enter the number of lines to read in: 2
one
two
[output] output.txt
one
two
Using a thread to poll the input-readLine:
// keystop1.sc
// In Scala- or SBT console/Quick-REPL: :load keystop1.sc
// As Script: scala -savecompiled keystop1.sc
#volatile var isRunning = true
#volatile var isPause = false
val tInput: Thread = new Thread {
override def run: Unit = {
var status = ""
while (isRunning) {
this.synchronized {
status = scala.io.StdIn.readLine()
status match {
case "s" => isRunning = false
case "p" => isPause = true
case "r" => isRunning = true;isPause = false
case _ => isRunning = false;isPause = false
}
println(s"New status is: $status")
}
}
}
}
tInput.start
var count = 0
var pauseCount = 0
while (isRunning && count < 10){
println(s"still running long lasting job! $count")
if (count % 3 == 0) println("(Please press [each + ENTER]: s to stop, p to pause, r to run again!)")
count += 1
Thread sleep(2000) // simulating heavy computation
while (isPause){
println(s"Taking a break ... $pauseCount")
Thread sleep(1000)
pauseCount += 1
if (pauseCount >= 10){
isPause = false
pauseCount = 0
println(s"Taking a break ... timeout occurred!")
}
}
}
isRunning = false
println(s"Computation stopped, please press Enter!")
tInput.join()
println(s"Ok, thank you, good bye!")
readLine() lets you prompt the user and read their input as a String
val name = readLine("What's your name? ")
please try
scala> readint
please try this method