Squashed commit of the following: commit cec03384fa88ae8f74adee81491ea40865aa2f3f Author: AKP <abi@tdpain.net> Date: Thu Oct 26 13:42:15 2023 +0100 Question 5 commit 11aa1f2e3b4ed9410c88c5fc19a23963e4f4722e Author: AKP <abi@tdpain.net> Date: Thu Oct 26 13:21:41 2023 +0100 Question 4 commit e6aaadb45869c3d5cc57a69bcc0862be883834e8 Author: AKP <abi@tdpain.net> Date: Thu Oct 26 13:13:04 2023 +0100 Question 3.2 commit f74fd8d782a283596bdbca21d28b2522b9ff29fc Author: AKP <abi@tdpain.net> Date: Thu Oct 26 12:29:41 2023 +0100 Question 3.1 commit d3e03478ba3a54bada957c5b3ec45cbd0ee8e5d9 Author: AKP <abi@tdpain.net> Date: Thu Oct 26 12:23:53 2023 +0100 Question two commit 6f9d44a0a3439abf12010eab9bb06a9a93dcb943 Author: AKP <abi@tdpain.net> Date: Thu Oct 26 12:11:59 2023 +0100 Question 1
98 lines
3.4 KiB
Haskell
98 lines
3.4 KiB
Haskell
-- setting the "warn-incomplete-patterns" flag asks GHC to warn you
|
|
-- about possible missing cases in pattern-matching definitions
|
|
{-# OPTIONS_GHC -fwarn-incomplete-patterns #-}
|
|
|
|
-- see https://wiki.haskell.org/Safe_Haskell
|
|
{-# LANGUAGE Safe #-}
|
|
|
|
module PracticeTest ( checkParity
|
|
, substitution
|
|
, largestPrimeBetween
|
|
, strongPrimes
|
|
, executeCommands
|
|
, babylonianPalindromes) where
|
|
|
|
import Types
|
|
|
|
---------------------------------------------------------------------------------
|
|
---------------- DO **NOT** MAKE ANY CHANGES ABOVE THIS LINE --------------------
|
|
---------------------------------------------------------------------------------
|
|
|
|
{- Question 1 -}
|
|
|
|
checkParity :: String -> Bool
|
|
checkParity instr = if not ((length instr) `mod` 8 == 0) then False else
|
|
if ((foldl (\cursor val -> if val == '1' then cursor + 1 else cursor) 0 instr) `mod` 2 == 0) then True else False
|
|
|
|
{- Question 2 -}
|
|
|
|
substitution :: String -> String -> String
|
|
substitution plaintext key = map
|
|
(\ch -> if isLetter ch then
|
|
let charIndex = charLabel ch in
|
|
let cipherChar = key!!charIndex in
|
|
if isUpper ch then
|
|
toUpper cipherChar
|
|
else
|
|
toLower cipherChar
|
|
else
|
|
ch
|
|
)
|
|
plaintext
|
|
|
|
{- Question 3 -}
|
|
|
|
largestPrimeBetween :: Int -> Int
|
|
largestPrimeBetween n = head (filter isPrime (reverse [n+1..(n*2)-1]))
|
|
|
|
_isStrongPrimeSet :: (Int, Int, Int) -> Bool
|
|
_isStrongPrimeSet (x, y, z) = (realToFrac y) > ((realToFrac (x + z)) / 2)
|
|
|
|
_takeFirst :: Int -> [a] -> [a]
|
|
_takeFirst _ [] = []
|
|
_takeFirst n (x:xs) = if n <= 0 then [] else x:_takeFirst (n - 1) xs
|
|
|
|
strongPrimes :: Int -> [Int]
|
|
strongPrimes n = let primes = [x :: Int | x <- [1..], isPrime x] in
|
|
let primeSets = [(primes!!(i-1), primes!!i, primes!!(i+1)) | i <- [1..]] in
|
|
let strongPrimeSets = [x | x <- primeSets, _isStrongPrimeSet x] in
|
|
let strongPrimes = [x | (_, x, _) <- strongPrimeSets] in
|
|
_takeFirst n strongPrimes
|
|
|
|
{- Question 4 -}
|
|
|
|
_applyCommand :: Command -> (Int, Int) -> (Int, Int)
|
|
_applyCommand (dir, mag) (posx, posy) = if mag == 0 then (posx, posy) else
|
|
let newCmd = (dir, mag-1) in
|
|
if dir == 0 then
|
|
(_applyCommand newCmd (posx - 1, posy))
|
|
else if dir == 1 then
|
|
(_applyCommand newCmd (posx + 1, posy))
|
|
else if dir == 2 then
|
|
(_applyCommand newCmd (posx, posy + 1))
|
|
else if dir == 3 then
|
|
(_applyCommand newCmd (posx, posy - 1))
|
|
else (0, 0)
|
|
|
|
executeCommands :: [Command] -> (Int, Int) -> (Int, Int)
|
|
executeCommands cmds startPos = foldl
|
|
(\currentPos cmd -> _applyCommand cmd currentPos)
|
|
startPos
|
|
cmds
|
|
|
|
{- Question 5 -}
|
|
|
|
_convToBaseSixty :: Integer -> [Integer]
|
|
_convToBaseSixty 0 = []
|
|
_convToBaseSixty v = (_convToBaseSixty (v `div` 60)) ++ [v `mod` 60]
|
|
|
|
_isPalindromic :: [Integer] -> Bool
|
|
_isPalindromic xs = if (length xs) < 2 then False else
|
|
let midpoint = (length xs) `div` 2 in
|
|
if (length xs) `mod` 2 == 0 then -- is even length
|
|
(_takeFirst midpoint xs) == (_takeFirst midpoint (reverse xs))
|
|
else -- is odd length
|
|
(_takeFirst (midpoint + 1) xs) == (_takeFirst (midpoint + 1) (reverse xs))
|
|
|
|
babylonianPalindromes :: [Integer]
|
|
babylonianPalindromes = [x | x <- [0..], (_isPalindromic (_convToBaseSixty x))]
|