Part of Swift with Copilot

Swift: Create a random list of 5 numbers between 1 to 100

Sandy LaneSandy Lane

Video: Swift: Create a random list of 5 numbers between 1 to 100 by Taught by Celeste AI - AI Coding Coach

Take the quiz on the full lesson page
Test what you've read · interactive walkthrough

Swift with Copilot: Random List of 5 Numbers 1–100

Same as episode 2, slightly different framing. (1...5).map { _ in Int.random(in: 1...100) } — five random integers in [1, 100]. The "5 from 100" exercise that turns up everywhere.

A short episode that revisits the random-array idiom from episode 2. The takeaways below stretch a bit further.

The Copilot prompt

// Generate a list of 5 random numbers between 1 and 100

Copilot completes:

let numbers = (1...5).map { _ in Int.random(in: 1...100) }
print(numbers)
// [42, 87, 13, 56, 91]

Same one-liner as episode 2. See that for the breakdown of (1...5), .map { _ in ... }, and Int.random(in:).

Distribution

Int.random(in: 1...100) is uniform over [1, 100] — 100 values, each equally likely. Implemented via the platform's secure random source.

For 5 samples from 100 values, collisions are likely (~10% chance of at least one duplicate per call):

// Quick collision check
var collisions = 0
for _ in 1...10000 {
  let nums = (1...5).map { _ in Int.random(in: 1...100) }
  if Set(nums).count < 5 {
    collisions += 1
  }
}
print(Double(collisions) / 10000.0)    // ~0.10

Without duplicates

let unique = Array(1...100).shuffled().prefix(5)
print(Array(unique))

Steps: 1. Array(1...100)[1, 2, 3, ..., 100]. 2. .shuffled() — random order. 3. .prefix(5) — first 5.

For 5 from 100, this is fast. For 5 from millions, it's wasteful (allocates the full array). For huge ranges:

var picks = Set<Int>()
while picks.count < 5 {
  picks.insert(Int.random(in: 1...1_000_000_000))
}
let result = Array(picks).sorted()

Reservoir sampling for streams (when you don't know N in advance) is more advanced.

Sorted output

let sorted = (1...5).map { _ in Int.random(in: 1...100) }.sorted()
// [13, 42, 56, 87, 91]

map then sorted(). Or build sorted directly:

let unique = Array(1...100).shuffled().prefix(5).sorted()
// 5 unique values, sorted

Generic helper

func randomInts(_ n: Int, in range: ClosedRange<Int>) -> [Int] {
  (1...n).map { _ in Int.random(in: range) }
}

let xs = randomInts(5, in: 1...100)
let ys = randomInts(10, in: 0...255)

Now you have a one-line "give me N randoms from this range."

For unique = true:

func randomInts(_ n: Int, in range: ClosedRange<Int>, unique: Bool = false) -> [Int] {
  if unique {
    precondition(n <= range.count, "asked for more uniques than available")
    return Array(Array(range).shuffled().prefix(n))
  }
  return (1...n).map { _ in Int.random(in: range) }
}

precondition traps if the request is impossible.

Seeded randomness

Int.random(in:) uses the system random source — no seeding. For reproducibility:

import GameKit

let rng = GKMersenneTwisterRandomSource(seed: 42)
let nums = (1...5).map { _ in rng.nextInt(upperBound: 100) + 1 }

GameKit is iOS/macOS only. For server-side or cross-platform: third-party swift-numerics, swift-random, or roll your own LCG.

Random doubles

let pcts = (1...5).map { _ in Double.random(in: 0...1) }
// [0.42, 0.87, 0.13, 0.56, 0.91]

Double.random(in:) is uniform over the range.

For Gaussian (normal distribution), use GKGaussianDistribution:

import GameKit
let g = GKGaussianDistribution(randomSource: GKLinearCongruentialRandomSource(),
                                lowestValue: 0,
                                highestValue: 100)
let samples = (1...100).map { _ in g.nextInt() }

Random elements from a collection

let names = ["Alice", "Bob", "Charlie", "Diana", "Eve"]
let one = names.randomElement()              // Optional<String>
let three = (1...3).map { _ in names.randomElement()! }

randomElement() returns nil for empty collections. Force-unwrap is OK if you know the array isn't empty.

For 3 unique:

let three = Array(names.shuffled().prefix(3))

Common stumbles

Off-by-one. 1...100 includes both ends. 1..<100 is [1, 99]. Match what you mean.

Force-unwrap on potentially empty. [].randomElement()! crashes. Default with ??.

map for side effects. (1...5).map { _ in print("hi") } works but the [Void] array is wasted. Use for _ in 1...5 { print("hi") }.

Reproducibility. Default Int.random(in:) can't be seeded. Use GameKit for that.

Performance with huge ranges. Array(1...10_000_000).shuffled() allocates 80MB. For huge N or sparse uniques, use a Set-based loop or reservoir sampling.

What's next

Episode 11: How many days in December 2023? Calendar arithmetic.

Recap

(1...5).map { _ in Int.random(in: 1...100) } — five random Ints in [1, 100]. For unique: Array(1...100).shuffled().prefix(5). For sorted: append .sorted(). For seeded reproducibility: GameKit.GKMersenneTwisterRandomSource. randomElement() picks one (returns optional).

Next episode: days in a month.

Ready? Take the quiz on the full lesson page →
Test what you've learned. Watch the lesson and try the interactive quiz on the same page.