2

I am trying to get only 20 random values out of 26 from the lettersthat also have to include elements from the array name. finalArray would look like: ["S", "A", "M", "A", "N", "T", "H", "A", "I", "J", "K", "L", "S", "N", "O","P","Q", "R", "S", "A"](randomly)

So far:

var letters: [String] = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O","P","Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]


var name: [String] = ["S", "A", "M", "A", "N","T","H","A"]


//Create finalArray elements

var availableLetters = letters.filter { value in
    !contains(name, value)
}

var finalArray = availableLetters + name

I tried to do:

    //get 20 objects
var length = name.utf16Count

var beforeArray = finalArray[0...19]

//minus length of the word

var letterCount = beforeArray.count - length

// add missing letters
beforeArray = letters[0...letterCount] + name

Which is obviously wrong and the results are very unstable. What could I use as a simple workaround? How could I implement it?

Nicholas Bear
  • 71
  • 1
  • 5

1 Answers1

2

It seems from your example that you want to take name, and then right-pad it with random letters from the alphabet up to a length of 20. Since it looks like you don’t mind about repeating the random letters, this makes things a lot easier.

The tricky part is generating a sequence of n random numbers up to a maximum. If you have this, you can use these numbers as indices into your alphabet array to pick the random characters. Here’s one way to generate that sequence:

// Struct representing a sequence of count
// random numbers in range 0..<max
struct RandomSequence: SequenceType {
    let count: Int
    let max: Int
    func generate() -> GeneratorOf<Int> {
        var i = 0
        return GeneratorOf {
            i++ < self.count
              ? Int(arc4random_uniform(UInt32(self.max)))
              : nil
        }
    }
}

Once you have this, it can be used to generate the padding:

let name = Array("SAMANTHA")
let alphabet = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

let targetCount = 20
let paddingCount = targetCount - name.count

let ranseq = RandomSequence(count: paddingCount, max: alphabet.count)
let padding = map(ranseq) { alphabet[$0] }

let padded = name + padding
// padded = ["S", "A", "M", "A", "N", "T", "H", "A", "W", "O", "C", "M", "L", "B", "L", "A", "N", "H", "I", "I"]

If you actually want the name shuffled in with the random letters afterwards, look at the top answer to this question. But it’s probably easiest to do this as a second step to the above technique rather than try and combine both steps together.

It’s worth noting that if name is a string, and you want the result to end up as a string, you don’t need to put in an array for this approach to work:

let name = "SAMANTHA"
let alphabet = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

let targetCount = 20
let paddingCount = targetCount - count(name)

let ranseq = RandomSequence(count: paddingCount, max: alphabet.count)
let padding = map(ranseq) { alphabet[$0] }

let padded = name + padding
// padded = "SAMANTHASLHMPRDYRHFC"
Community
  • 1
  • 1
Airspeed Velocity
  • 40,491
  • 8
  • 113
  • 118