Swift - Program to print and repeat message based on counter - swift

I have a work related learning course and struck with a hands-on question on Swift programming - Control Transfer Statements like break, continue, fallthrough, return, & throw.
Write a function named printMessage that takes two parameters - a string message and an integer count. The message should print and repeat the message as specified in the count parameter.
Message:"Hello , How are You"
For instance take Count as 8
This should print Message:"Hello , How are You" 8 times consecutively.
So far I got the below code working fine on Xcode, should use control transfer Statements, so tried this. But some extra eyes/other best practice way would help. As I am stuck with this hands-on and it is stopping me to complete the course. The way its designed is it gets input on the text box on the web page and runs the code on the coding area and gets output, if it matches the expected output, it let you submit, but that does not means I am successful as it tests the code with their answer key and my code don't match the answer key and I am failing. Please help
func printMessage(message: String, count: Int){
for i in 0...count{
if( i == count){
break;
} else {
print(message);
continue;
}
}
}
let message: String = readLine()!;
let c = readLine();
let count: Int = Int(c!)!;
printMessage(message: message, count: count);

The following piece of code works as it is meant to, in a while loop and also incorporates the Control Transfer Statements, like you asked:
func printMessage(message: String, count: Int) {
var i: Int = 0
while true {
if i < count {
print(message)
i += 1
} else { break }
}
}
let message: String = "Hello!"
let count: Int = 3
printMessage(message: message, count: count)
If there are any more specifications, let me know. Also, it would be helpful to have a link to the lesson/tutorial. Hope this helps! :)

If you want to do it with for loop:
func PrintMessage (message: String, count: Int) {
for _ in 0..<count {
print(message)
}
}
let message = readLine()
let count = Int(readLine()!)
PrintMessage(message: message!, count: count!);

Try this one, Hope this will help you :)
func printMessage(message: String, count: Int) {
var localCount = 1
while localCount <= count {
print(message)
localCount = localCount + 1
}
}
printMessage(message: "Hello", count: 8)

Related

Combine if statement and for loop such that loop only gets executed once per every execution of if statement in swift

I'm trying to understand swift and therefore try to come up with simple command line games: in this game a player has to guess a secret word within 6 attempts by typing something in the command line, but every time he gets it wrong, a statement prints the number of his wrong attempts:
let response = readLine()
if response != "secret word" {
for n in 1...6 {
print(n)
}
}
else {
print("you are right!")
}
Now I know that my code will print all lines once the condition is not true, but I'm looking for a way to only print one item out of the four loop for every if statement consecutively.
I think a while loop works pretty well. Maybe something like this:
print("Welcome to the input game!\n\n\n\n")
var remainingTries = 5
let dictionary = ["apple", "grape", "pear", "banana"]
let secretWord = dictionary.randomElement()
print("Please guess a fruit")
while remainingTries > 0 {
remainingTries -= 1
let response = readLine()
if response == secretWord {
print("You got it!")
remainingTries = 0
} else if remainingTries <= 0 {
print("Too bad, you lose!")
remainingTries = 0
} else {
print("Incorrect. Tries remaining: \(remainingTries)")
}
}

Minimum Window Substring in Swift

I am trying to learn swift by solving interview questions. One of the question that I am trying to solve is as follows.
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).
Example:
Input: S = "ADOBECODEBANC", T = "ABC"
Output: "BANC"
My implementation is as follows which holds t string characters and its corresponding index retrieved from s.
func minimumWindowSubstring(_ s: String, _ t: String) -> String{
let sChar = [Character](s)
let tChar = [Character](t)
var indexTemp = [[Character:Int]()]
for tc in tChar
{
for (j, sc) in sChar.enumerated()
{
if sc == tc
{
indexTemp.append([tc:j])
}
}
}
return ""
}
what I have in indexTemp array is as follows
Now I wonder how could I able to use this array to find the minimumwindow, I stuck.
I thought it was an interesting problem so I gave it a shot. Instead of using a dictionary I used a simple class to store the range of characters found, as well as a String that stores which characters haven't been found.
It only goes through the main string once, so it should be O(n).
You can run this in the playground.
(I know you wanted help in fixing your code and my answer doesn't do that, but I'm hoping it will provide enough insight for you to adjust your own code)
import Foundation
let string = "ADOBECODEBANC"
let sub = "ABC"
// Create a class to hold the start and end index of the current search range, as well as a remaining variable
// that will store which characters from sub haven't been found
class Container {
var start: Int
var end: Int?
var remaining: String
// Consume will attempt to find a given character within our remaining string, if it has found all of them,
// it will store the end index
func consume(character: Character, at index: Int) {
// If remaining is empty, we're done
guard remaining != "" else { return }
// We're assuming that sub won't have repeating characters. If it does we'll have to chage this
remaining = remaining.replacingOccurrences(of: String(character), with: "")
if remaining == "" {
end = index
}
}
init(start: Int, remaining: String) {
self.start = start
self.remaining = remaining
}
}
// ClosedContainer is similar to Container, but it can only be initialized by an existing container. If the existing
// container doesn't have an end value, the initialization will fail and return nil. This way we can weed out containers
// for ranges where we didn't find all characters.
class ClosedContainer {
let start: Int
let end: Int
init?(container: Container) {
guard let end = container.end else { return nil }
self.start = container.start
self.end = end
}
var length: Int {
return end - start
}
}
var containers = [Container]()
// Go through each character of the string
string.enumerated().forEach { index, character in
// Look for matches in sub
if sub.contains(character) {
// Allow each existing container to attempt to consume the character
containers.forEach { container in
container.consume(character: character, at: index)
}
// Create a new container starting on this index. It's remaining value will be the sub string without the
// character we just found
let container = Container(start: index, remaining: sub.replacingOccurrences(of: String(character), with: ""))
containers.append(container)
}
}
// Convert Containers into ClosedContainers using compactMap, then find the one with the shortest length
let closedContainers = containers.compactMap(ClosedContainer.init)
let maybeShortest = closedContainers.min { $0.length < $1.length }
if let shortest = maybeShortest {
// Convert int to String indices
let start = string.index(string.startIndex, offsetBy: shortest.start)
let end = string.index(string.startIndex, offsetBy: shortest.end)
// Get the result string
let result = string[start...end]
print("Shortest substring of", string, "that contains", sub, "is", result)
} else {
// No range was found that had all characters in sub
print(string, "doesn't contain all characters in", sub)
}

Shuffle functions not shuffling cards

So I've been having a few problems with this shuffling code and posted a few questions on it, and now everything seems to be working, except the actual shuffling doesn't appear to be working.
I have been asked to rewrite this question repeatedly, first with the Swift 3 version of the shuffle code located here as well as now the Swift 4 code. I am on Swift 3.2, and I was getting warnings with the Swift 3 code. I can include them if desired, however I've added and deleted them several times already because a user keeps asking me to change my question
I've tried this:
func displayOfferCards() -> Void {
var offerCards = allOfferCards()
offerCards.shuffle()
for (index, offerCard) in offerCards.enumerated() {
let delay = Double(index) * 0.2
offerCard.display(delay: delay)
}
}
Here's also this for how the cards are being generated:
func allOfferCards() -> [OfferCard]{
guard dataSource != nil else {
return []
}
let numberOfCards = self.dataSource!.kolodaNumberOfCards(self)
var offerCards = [OfferCard]()
for i in 0..<numberOfCards {
let offerCard = viewForCard(at: i)
if let offerCard = offerCard {
offerCards.append(offerCard as! OfferCard)
}
}
return offerCards
}
And here's the shuffle function:
extension MutableCollection {
/// Shuffles the contents of this collection.
mutating func shuffle() {
let c = count
guard c > 1 else { return }
for (firstUnshuffled, unshuffledCount) in zip(indices, stride(from: c, to: 1, by: -1)) {
let d: IndexDistance = numericCast(arc4random_uniform(numericCast(unshuffledCount)))
let i = index(firstUnshuffled, offsetBy: d)
swapAt(firstUnshuffled, i)
}
}
}
An example, before and after:
print("DEBUG TOP " + offerCards[0].offer.title)
offerCards.shuffle()
print("DEBUG BOTTOM " + offerCards[0].offer.title)
Using the method removeFirst() is working:
offerCards.removeFirst()
So it is definitely something to do with the shuffle function itself I think.
And with PhilipMillis' suggestion:
DEBUG TOP Apple Music
DEBUG Swapping 0 with 0
DEBUG Swapping 1 with 2
DEBUG BOTTOM Apple Music
DEBUG TOP Apple Music
DEBUG Swapping 0 with 1
DEBUG Swapping 1 with 2
DEBUG BOTTOM Nielsen Rewards

fatal error with a simple swift program

import UIKit
import Foundation
func randomnumber (low:Int,high:Int )->Int
{
let range = high - (low-1)
return (Int (arc4random()) % range ) + ( low - 1)
}
let answer = randomnumber(low: 0, high: 100)
var turn = 1
while (true)
{
print ("Guess #\(turn): enter a number between 0 and 100")
let userinput = readLine();
if let guess:Int = Int(userinput!)
{
if( guess<answer )
{
print("choose a higher number")
}
if ( guess>answer )
{
print ("choose a smaller number")
}
if( guess==answer)
{
print("wohoo you won")
break;
}
}
}
this code is about a simple game using swift , by having a random number and then putting an input and if this input is bigger than the random number we have to choose smaller number and the opposite if we choose a smaller number and its still not equal to the random number and if it's equal to the random number you win.
this error appears :
fatal error: unexpectedly found nil while unwrapping an Optional value
As Tristan Beaton pointed out, readLine() doesn't work on playground hence your userInput is always nil.
CREATE A COMMAND LINE TOOL APPLICATION
CHOSE SWIFT WHEN YOU SAVE
COPY AN PASTE YOUR CODE
RUN AND PLAY
Also be really careful when you force unwrapping. That's always a crash waiting to happen ;) You can read this tutorial
I have tested this in a Command Line Tool and it worked. Also don't force unwrap optionals since you can just check if they have data without crashing the app.
I have added continue statements within your other if statements. Although it isn't really needed in this case, it is good practice to have it so that any code after the continue doesn't get executed. It just saves a bit of computing power.
import Foundation
func randomnumber(low: Int, high: Int) - >Int {
let range = high - (low-1)
return (Int(arc4random()) % range) + (low - 1)
}
let answer = randomnumber(low: 0, high: 100)
var turn = 1
while (true) {
print("Guess #\(turn): enter a number between 0 and 100")
if let userinput = readLine() {
if let guess:Int = Int(userinput) {
// Putting this here will only increase the guess count if their input in a number.
turn += 1
if guess < answer {
print("choose a higher number")
continue
}
if guess > answer {
print ("choose a smaller number")
continue
}
if guess == answer {
print("wohoo you won")
break
}
}
}
}
This is the console output

Swift readLine! is causing fatal error "execution was interrupted"

I have this piece of code
func sell() throws{
while(true)
{
var choice : String?
print("Please press a number from 1 to 3\n")
let product = readLine(stripNewline: true)!
switch product
{
case "1":
//
case "2":
//
case "3":
//
default:
choice = "Invalid"
try sell()
}
}
try sell()
And it gives me the error
execution was interrupted reason exc_bad_instruction
I realized that the ! is causing the error. If I remove it I have a problem with the comparisons inside switch.
Anyone knows what is the problem?
func foo()->Int {
print("Please press a number from 1 to 3")
while true {
if let l = readLine(),
let i = Int(l) {
if (1..<4).contains(i) {
return i
} else {
print("Number must be in range from 1 to 3")
}
} else {
print("Please press a number")
}
}
}
let r = foo()
print("You chose", r)
an example of ...
Please press a number from 1 to 3
u
Please press a number
7
Number must be in range from 1 to 3
45
Number must be in range from 1 to 3
h76
Please press a number
1
You chose 1
Program ended with exit code: 0
How about create one if let to check if this contains value or is it nil
let product = readLine(stripNewline: true)
if let productNo = product {
switch productNo {
//your same code in switch
}