You are on page 1of 22

Question 1

We define a function named maxProduct that takes an array of integers nums as input

and returns an integer as output.

We first check if the input array nums is empty. If it is, we return 0, as there's no valid

computation to perform on an empty array.

We initialize three variables: var_out, var_a, and var_i to the first element of the nums

array.

We then iterate through the nums array starting from the second element (index 1).

Inside the loop, we check if the current element nums[i] is less than 0. If it is, we swap

the values of var_a and var_i. This step is used to handle negative numbers in the

array.

We calculate the maximum product ending at the current element nums[i] and update

var_a with the maximum of the current element and the product of var_a and nums[i].

This step ensures that var_a stores the maximum product ending at the current position.

Similarly, we calculate the minimum product ending at the current element nums[i] and

update var_i with the minimum of the current element and the product of var_i and
nums[i]. This step ensures that var_i stores the minimum product ending at the current

position.

We update var_out with the maximum of var_out and var_a. This step ensures that

var_out stores the maximum product among all possible products ending at different

positions in the array.

After the loop is complete, we return the final value of var_out, which represents the

maximum product of a subarray within the nums array.

We define an input array input and call the maxProduct function with this input array.

Finally, we print the result, which is the maximum product of the subarray.

Question 1a

import UIKit

func maxProduct(_ nums: [Int]) -> Int {

if nums.isEmpty {

return 0

var var_out = nums[0]

var var_a = nums[0]


var var_i = nums[0]

for i in 1..<nums.count {

if nums[i] < 0 {

swap(&var_a, &var_i)

var_a = max(nums[i], var_a * nums[i])

var_i = min(nums[i], var_i * nums[i])

var_out = max(var_out, var_a)

return var_out

let input: [Int] = [-5, 2, 3, 5, 7, -1, 3, 1, -3, 15]

let output = maxProduct(input)

print(output) // Output will be 28350 (2*3*5*7*-1*3*1*-3*15)

Part b

import UIKit

// Function to calculate the maximum product of a subarray of integers


func calculateMaxProduct(_ nums: [Int]) -> Int {

// Check if the input array is empty

if nums.isEmpty {

return 0

// Initialize variables to track the maximum product

var maxProduct = nums[0] // Maximum product

var maxEndingHere = nums[0] // Maximum product ending at the current index

var minEndingHere = nums[0] // Minimum product ending at the current index

// Iterate through the array

for i in 1..<nums.count {

// Store the current value

let currentNum = nums[i]

// Calculate the new maximum and minimum products

let tempMax = maxEndingHere

maxEndingHere = max(currentNum, currentNum * maxEndingHere, currentNum *

minEndingHere)

minEndingHere = min(currentNum, currentNum * tempMax, currentNum *

minEndingHere)

// Update the overall maximum product


maxProduct = max(maxProduct, maxEndingHere)

// Return the maximum product

return maxProduct

// Input array of integers

let input: [Int] = [-5, 2, 3, 5, 7, -1, 3, 1, -3, 15]

// Calculate and print the maximum product of a subarray

let output = calculateMaxProduct(input)

print("Maximum Product:", output) // Output will be 28350 (2*3*5*7*-1*3*1*-3*15)

Question 1b

The function initializes three variables: maxProduct, maxEndingHere, and

minEndingHere to track the maximum product overall, the maximum product ending at

the current index, and the minimum product ending at the current index, respectively.

It iterates through the input array nums starting from the second element (index 1).

For each element at index i, it calculates the new maxEndingHere and minEndingHere

values based on the current element and the previous values.


It updates the maxProduct with the maximum value between the current maxProduct

and maxEndingHere.

The loop continues until it processes all elements in the input array.

Finally, the function returns the maxProduct, which represents the maximum product of

a subarray.

Here is the code

import UIKit

// Function to calculate the maximum product of a subarray of integers

func calculateMaxProduct(_ nums: [Int]) -> Int {

// Check if the input array is empty

if nums.isEmpty {

return 0

// Initialize variables to track the maximum product

var maxProduct = nums[0] // Maximum product

var maxEndingHere = nums[0] // Maximum product ending at the current index

var minEndingHere = nums[0] // Minimum product ending at the current index


// Iterate through the array

for i in 1..<nums.count {

// Store the current value

let currentNum = nums[i]

// Calculate the new maximum and minimum products

let tempMax = maxEndingHere

maxEndingHere = max(currentNum, currentNum * maxEndingHere, currentNum *

minEndingHere)

minEndingHere = min(currentNum, currentNum * tempMax, currentNum *

minEndingHere)

// Update the overall maximum product

maxProduct = max(maxProduct, maxEndingHere)

// Return the maximum product

return maxProduct

// Input array of integers

let input: [Int] = [-5, 2, 3, 5, 7, -1, 3, 1, -3, 15]

// Calculate and print the maximum product of a subarray


let output = calculateMaxProduct(input)

print("Maximum Product:", output) // Output will be 28350 (2*3*5*7*-1*3*1*-3*15)

// Example 2

let inputExample: [Int] = [2, 3, 4, 5, -2]

// Calculate and print the maximum product of a subarray for the second example

let outputExample = calculateMaxProduct(inputExample)

print("Maximum Product (Example 2):", outputExample) // Output will be 10000

(2*3*4*5)

Question 2

Code

import UIKit

// Define a structure to represent client information

struct Client {

let userID: UInt32 // Unique 32-bit positive integer

var name: String

var age: Int

var balance: Double

}
// Create an empty array to store client information

var clientDatabase: [Client] = []

// Function to add a new client to the database

func addClient(userID: UInt32, name: String, age: Int, balance: Double) {

// Check if the client already exists based on userID

if let _ = clientDatabase.first(where: { $0.userID == userID }) {

print("Client with userID \(userID) already exists.")

} else {

// Create a new client and add it to the database

let newClient = Client(userID: userID, name: name, age: age, balance: balance)

clientDatabase.append(newClient)

print("Client with userID \(userID) added successfully.")

// Function to update client information based on userID

func updateClient(userID: UInt32, name: String?, age: Int?, balance: Double?) {

if let index = clientDatabase.firstIndex(where: { $0.userID == userID }) {

// Client found, update the provided fields if not nil

if let newName = name {

clientDatabase[index].name = newName
}

if let newAge = age {

clientDatabase[index].age = newAge

if let newBalance = balance {

clientDatabase[index].balance = newBalance

print("Client with userID \(userID) updated successfully.")

} else {

print("Client with userID \(userID) not found.")

// Function to retrieve client information based on userID

func getClient(userID: UInt32) -> Client? {

if let client = clientDatabase.first(where: { $0.userID == userID }) {

return client

} else {

print("Client with userID \(userID) not found.")

return nil

}
// Function to display all clients in the database

func displayAllClients() {

print("Client Database:")

for client in clientDatabase {

print("UserID: \(client.userID), Name: \(client.name), Age: \(client.age), Balance: $\

(client.balance)")

// Example usage

addClient(userID: 123456, name: "John Doe", age: 30, balance: 5000.0)

addClient(userID: 789012, name: "Alice Smith", age: 25, balance: 7500.0)

displayAllClients()

updateClient(userID: 123456, name: "John M. Doe", age: nil, balance: 5500.0)

if let client = getClient(userID: 123456) {

print("Retrieved Client: UserID: \(client.userID), Name: \(client.name), Age: \

(client.age), Balance: $\(client.balance)")

Explanation

The Client struct defines the structure of client information.

An empty array clientDatabase is created to store client records.


Functions are provided to add, update, retrieve, and display client information.

An example usage is demonstrated with two clients added, one client's information

updated, and client details displayed.

Question 2a

userID:

Data Type: UInt32

Explanation: The userID is described as a unique 32-bit positive integer. Therefore, it

should be represented using the UInt32 (unsigned 32-bit integer) data type. Using an

unsigned integer ensures that the userID is always positive.

name:

Data Type: String

Explanation: The client's name is a text-based field and should be represented using the

String data type. This allows for the storage of variable-length strings, accommodating

full names.

age:

Data Type: Int

Explanation: The client's age is represented as an integer value. The Int data type is

suitable for storing whole numbers, including positive and negative values. Since age
should always be a non-negative integer, you might consider using UInt (unsigned

integer) to enforce that constraint, but Int is commonly used for age.

balance:

Data Type: Double or Decimal

Explanation: The client's account balance is typically represented as a floating-point

number to accommodate decimal values. You can use the Double data type for

balance. However, for financial calculations where precision is crucial, consider using

the Decimal data type, which provides high precision for decimal arithmetic. Using

Decimal is a good practice to avoid rounding errors in financial applications.

Question 2b

To store client data and efficiently perform functions such as checking and updating the

balance with a given userID, you can consider different data structures in Swift. The

choice of data structure depends on the specific requirements and performance

characteristics of your application. Here are some recommended data structures:

Dictionary:

Use Case: If you need fast access to client information based on their userID.

Recommendation: Create a dictionary where userID serves as the key, and the client

data (e.g., name, age, balance) is stored as the associated value. This allows for quick

retrieval and updates based on userID.


var clientData: [UInt32: (name: String, age: Int, balance: Decimal)] = [:]

To check the balance with a given userID, you can use clientData[userID]?.balance.

To update the balance for a given userID, you can use clientData[userID]?.balance =

newBalance.

Array of Structs or Tuples:

Use Case: If you need to maintain an ordered list of clients and perform operations that

involve iterating through the list.

Recommendation: Create an array where each element represents a client as a struct

or tuple containing userID, name, age, and balance. This allows you to maintain a client

list in order and perform sequential operations.

struct Client {

let userID: UInt32

let name: String

var age: Int

var balance: Decimal

var clients: [Client] = []


To check the balance with a given userID, you can iterate through the clients array and

find the matching client.

To update the balance for a given userID, you can iterate through the clients array,

locate the client by userID, and update the balance.

Core Data or Database:

Use Case: If you need to manage a large number of clients and require data

persistence and advanced querying capabilities.

Recommendation: Use a database system like Core Data or SQLite. These systems

allow you to create client entities with attributes for userID, name, age, and balance.

You can perform efficient queries and updates based on various criteria, including

userID.

You would define a database schema that includes a client table with columns for each

client attribute.

Queries and updates would be performed using database-specific query languages or

Swift APIs.

Question 2c
import Foundation

// Define a Client struct to store client information

struct Client {

let userID: UInt32

var name: String

var age: Int

var balance: Decimal

// Create an array to store client data (you can initialize it with your test data)

var clients: [Client] = [

Client(userID: 1, name: "Alice", age: 30, balance: 1000.0),

Client(userID: 2, name: "Bob", age: 25, balance: 1500.0),

// Add more clients here...

// Function to transfer money from one userID to another

func transferMoney(senderID: UInt32, receiverID: UInt32, amount: Decimal) -> Bool {

// Find the sender and receiver clients based on their userID

guard var senderIndex = clients.firstIndex(where: { $0.userID == senderID }),

var receiverIndex = clients.firstIndex(where: { $0.userID == receiverID }) else {

// Either sender or receiver does not exist


return false

// Check if the sender has sufficient balance

if clients[senderIndex].balance >= amount {

// Deduct the amount from the sender's balance

clients[senderIndex].balance -= amount

// Add the amount to the receiver's balance

clients[receiverIndex].balance += amount

// Transaction successful

return true

} else {

// Insufficient balance in the sender's account

return false

// Function to display the final balance of a client based on their userID

func displayBalance(userID: UInt32) {

if let index = clients.firstIndex(where: { $0.userID == userID }) {

let client = clients[index]


print("UserID: \(client.userID), Name: \(client.name), Final Balance: \

(client.balance)")

} else {

print("Client with userID \(userID) not found.")

// Example: Transfer money from userID 1 to userID 2

let senderID: UInt32 = 1

let receiverID: UInt32 = 2

let transferAmount: Decimal = 500.0

if transferMoney(senderID: senderID, receiverID: receiverID, amount: transferAmount) {

print("Money transferred successfully.")

displayBalance(userID: senderID)

displayBalance(userID: receiverID)

} else {

print("Money transfer failed. Insufficient balance or invalid userID.")

explanation

Client is defined as a struct to store client information.


The transferMoney function finds the sender and receiver clients based on their userID,

checks the sender's balance, deducts the amount from the sender, and adds it to the

receiver if the sender has sufficient balance.

The displayBalance function displays the final balance of a client based on their userID.

An example transaction is performed from userID 1 to userID 2 with a transfer amount

of $500. The result is printed, along with the final balances of both sender and receiver.

Question 3b

1. User Registration and Login:

When a user opens the app for the first time, they are presented with a registration form

where they can create an account by providing details like name, age, and choosing a

unique user ID.

Upon successful registration, the user's profile is created, and they can log in using their

credentials.

2. Home Screen:

After logging in, users are taken to the home screen, which serves as the app's main

dashboard.

The home screen displays the user's current location on a map, allows them to start and

stop activities, and shows their activity statistics.

3. Activity Tracking:
When the user clicks the "Start Activity" button, the app begins tracking their location

using Core Location.

The app calculates the distance traveled, updates the user's activity statistics, and

rewards them with points based on their activity.

4. Activity Statistics:

The app displays real-time activity statistics, including distance traveled and points

earned, while the activity is in progress.

5. Points System:

Points are earned based on the user's activity. The app tracks the user's progress and

updates their point balance accordingly.

6. Gift Store:

Users can access the gift store from the home screen or a dedicated view controller.

The gift store displays available gifts, their point values, and allows users to redeem

gifts using their earned points.

7. Money Transfer (Optional):

If the money transfer feature is implemented, users can initiate transfers to other users

by specifying the recipient's user ID and the number of points to transfer.

The app validates the transfer and updates both users' point balances.

8. User Profile:
Users can access their profile information, including name, age, and point balance,

through the app's settings or profile view.

9. User Logout:

Users can log out of their accounts, and their session is terminated.

10. Persistence:

- User profiles, points, and activity history are stored persistently, so users can access

their data even after closing the app.

11. Server Integration (Optional):

- If a backend server is used, the app communicates with the server for user

authentication, data storage, and transaction processing.

To achieve these features, different UIViews and UIControls are used in various view

controllers. Here's a brief overview of how some of the features are designed:

- MapView: The MapView is used to display the user's current location. It utilizes the

MapKit framework to show the map and annotate the user's position.

- Buttons (Start, Stop, Redeem): UIButtons are used to trigger actions such as

starting/stopping activities and redeeming gifts. Their actions are linked to

corresponding methods in the view controller.


- Text Labels: UILabels are used to display information like activity statistics, distances,

and point balances.

- Text Fields: UITextFields are used for user input during registration and, if applicable,

for money transfer.

- UITableView: UITableViews can be used to display lists of gifts in the gift store and

user profiles.

- Core Location: Core Location framework is used to access the device's GPS for

tracking the user's location during activities.

- User Defaults: UserDefaults can be used for storing small amounts of user data

persistently.

- Networking (Optional): URLSession or other networking libraries are used to

communicate with a backend server for features like registration, login, and data

synchronization.

- CoreData (Optional): CoreData framework can be used for local data storage and

retrieval, particularly for user profiles, points, and activity history.

You might also like