In-class-6

Class: CSCE-314

mport System.Random (mkStdGen, randomRs)

-- Q2.1 primes. Infinite Primes (Sieve of Erasthenes)
primes :: [Int]
primes = sieve [2..]
    where sieve (p:xs) = p : sieve [x | x <- xs, x `mod` p /= 0 ]
-- I’d like the 1000th–1010th prime numbers.
primes1000to1010 = take 11 (drop 999 primes)

-- Q2.2 Fibonacci. Give me Fibonacci numbers 200–209 (inclusive).
-- 4. Fibonacci Sequence (Self-referential definition)
fibs :: [Integer]  -- Note using Int, overflows because it can’t hold values that big.
fibs = 0 : 1 : zipWith (+) fibs (tail fibs)
-- Take 10 fibonacci numbers starting from 200th
fibs200to209 = take 10 (drop 200 fibs)

-- Q2.3 Triangular Numbers. Show the triangular numbers 500–509.
-- 1. Infinite List: Naturals
naturals :: [Integer]
naturals = [0..]
-- Infinite triangulars
triangulars :: [Integer]
triangulars = scanl1 (+) naturals
-- Output: Triangular numbers positions 21-30
demoTriangulars = take 10 (drop 501 triangulars)

-- Q2.4 primes mod 4 = 1. Show 10 primes congruent to 1 mod 4 starting at the 1000th such prime.
-- Primes ≡ 1 (mod 4)
primes1mod4 :: [Int]
primes1mod4 = filter (\p -> p `mod` 4 == 1) primes
-- Take 10 starting from 1000th
congruents = take 10 (drop 999 primes1mod4)

-------------------------------------------

-- Q3.1 fibs + triangulars: Create the series h = fibs + triangulars (elementwise), then give h[100..109].
h :: [Integer]
h = zipWith (+) fibs triangulars
-- Elements h[100..109]
h100to109 = take 10 (drop 100 h)

-- Q3.2 noisy Fibonacci: Make a ‘noisy Fibonacci’ by adding a random stream mod 100 (seed 31415) to fibs. Show 10 values starting at index 50.
-- Random stream (mod 100) with seed 31415
noise :: [Integer]
noise = map toInteger (randomRs (0,99) (mkStdGen 31415) :: [Int])
    -- randomRs needs an explicit type context,
-- Noisy Fibonacci = fibs + noise
noisyFibs :: [Integer]
noisyFibs = zipWith (+) fibs noise
-- Values 50..59 (10 elements starting at index 50)
noisy50to59 = take 10 (drop 50 noisyFibs)

-- Q3.3: Take evens and odds, compute their elementwise maximum with zipWith max, and return items 100..109.
-- Infinite streams
evens :: [Integer]
evens = [0,2..]
odds :: [Integer]
odds = [1,3..]
-- Elementwise maximum
maxEvensOdds :: [Integer]
maxEvensOdds = zipWith max evens odds
-- Items 100..109
max100to109 = take 10 (drop 100 maxEvensOdds)

-- Q3.4 Deal cards: Deal a 13-card hand from a standard deck using a deterministic ‘shuffle’
-- Define suits and ranks
suits :: [String]
suits = ["Spades", "Hearts", "Diamonds", "Clubs"]
ranks :: [String]
ranks = ["A","2","3","4","5","6","7","8","9","10","J","Q","K"]
-- Store a full deck of cards:
deck :: [String]
deck = [r ++ s | s <- suits, r <- ranks]
    -- Appending a rank and a suite and adding that to deck
-- Getting random indices (number for each card) based on a seed (deterministic)
indices :: [Int]
indices = randomRs (0, length deck - 1) (mkStdGen 31415)
-- Shuffle using zipWith
shuffle :: [a] -> [a]
shuffle xs = zipWith (!!) (repeat xs) indices
    -- (!!) means "List index" -> picks element at index from xs
    -- 'repeat xs' repeats the deck infinitely
    -- We could isntead use: "map (xs !!) indices"
-- Deal 13 cards
dealHand :: [String]
dealHand = take 13 (shuffle deck)