1
\$\begingroup\$

I've solved this question. Wasn't sure if I was suppose to use a dictionary in this case, as the question was to use a dynamic array, but I didnt know how else to do it. Was wondering if I can get feedback on my code or if there's a better way to approach it:

enter image description here

import Foundation

// reads input for N(number of sequences) and Q(number of queries)
let input = readLine()!.componentsSeparatedByString(" ").map { Int($0)! }
let numOfSequences = input[0]
let numOfQueries = input[1]
var lastAns = 0
var seqDictionary = [Int: [Int]]()

// loop through numOfQueries
for _ in 0..<numOfQueries {
    // each query is given in format [1, x, y] or [2, x, y]
    let query = readLine()!.componentsSeparatedByString(" ").map { Int($0)! }
    // check to see if query[0] is 1 or 2
    switch query[0] {
    case 1:
        // formula for seqDictionaryIndex
        // ^ is the XOR operator
        let seqDictionaryIndex = ((query[1] ^ lastAns) % numOfSequences)
        // since we initalized an empty dictionary, we gotta set the first key to a value to start the array so we can start appending
        guard seqDictionary[seqDictionaryIndex] != nil else { seqDictionary[seqDictionaryIndex] = [query[2]] ; continue }
        seqDictionary[seqDictionaryIndex]?.append(query[2])
    case 2:
        let seqDictionaryIndex = ((query[1] ^ lastAns) % numOfSequences)
        // calculate the size of the particular sequence in seqDictionary
        let size = seqDictionary[seqDictionaryIndex]?.count
        // formula for finding index in particular sequence in seqDictionary
        let index = query[2] % size!
        // set last answer to that element at the index calculated above
        lastAns = seqDictionary[seqDictionaryIndex]![index]
        print(lastAns)
    default: break
    }
}
\$\endgroup\$
1
\$\begingroup\$

The task is about dynamic arrays, and using an array (instead of a dictionary, as you did) simplifies things considerably.

If you start with an array of numOfSequences empty arrays:

var seqList = [[Int]](count: numOfSequences, repeatedValue: [])

then the 1 x y query simplifies to

let seqIndex = ((x ^ lastAns) % numOfSequences)
seqList[seqIndex].append(y)

without the need to check for an empty dictionary value.

Some more suggestions:

Reading a list of integers occurs at two places in the program, that justifies a separate function:

func readIntegers() -> [Int] {
    return readLine()!.componentsSeparatedByString(" ").map { Int($0)! }
}

(Remark: Usually, forced unwrapping with ! should be avoided, but here we have a programming challenge with well-defined input data.)

To increase the legibility of the code, I would assign the three parameters of a query to variables type, x, y. The code then becomes almost self-explaining.

The entire code then looks like this:

func readIntegers() -> [Int] {
    return readLine()!.componentsSeparatedByString(" ").map { Int($0)! }
}

// Read  N(number of sequences) and Q(number of queries):
let input = readIntegers()
let (numOfSequences, numOfQueries) = (input[0], input[1])

var lastAns = 0
// Array of `numOfSequences` empty arrays:
var seqList = [[Int]](count: numOfSequences, repeatedValue: [])

for _ in 0..<numOfQueries {
    let input = readIntegers()
    let (type, x, y) = (input[0], input[1], input[2])

    switch type {
    case 1:
        let seqIndex = ((x ^ lastAns) % numOfSequences)
        seqList[seqIndex].append(y)
    case 2:
        let seqIndex = ((x ^ lastAns) % numOfSequences)
        let index = y % seqList[seqIndex].count
        lastAns = seqList[seqIndex][index]
        print(lastAns)
    default:
        fatalError("Unexpected query")
    }
}
\$\endgroup\$
  • \$\begingroup\$ Thanks Martin! Your solution is amazing, well explained, and clear to understand \$\endgroup\$ – Clefairy Jul 22 '16 at 7:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.