Prompt:
(**Check if in given list of numbers, are any two numbers closer to each other than
 * given threshold.
 * >>> has_close_elements [1.0; 2.0; 3.0] 0.5
 * false
 * >>> has_close_elements [1.0; 2.8; 3.0; 4.0; 5.0; 2.0] 0.3
 * true
*)
let has_close_elements (numbers : float list) (threshold : float) : bool =


Prompt:
(**Input to this function is a string containing multiple groups of nested parentheses. Your goal is to
 * separate those group into separate strings and return the list of those.
 * Separate groups are balanced (each open brace is properly closed) and not nested within each other
 * Ignore any spaces in the input string.
 * >>> separate_paren_groups "( ) (( )) (( )( ))"
 * ["()"; "(())"; "(()())"]
*)
let separate_paren_groups (paren_string : string) : string list =


Prompt:
(**Given a positive floating point number, it can be decomposed into
 * and integer part (largest integer smaller than given number) and decimals
 * (leftover part always smaller than 1).
 * Return the decimal part of the number.
 * >>> truncate_number 3.5
 * 0.5
*)
let truncate_number (number : float) : float =

let assertions =
 let candidate = truncate_number in
  (assert ((candidate 3.5) = 0.5));
  (assert ((candidate 1.25) = 0.25));
  (assert ((candidate 123.0) = 0.0));
  ()


Prompt:
(**You're given a list of deposit and withdrawal operations on a bank account that starts with
 * zero balance. Your task is to detect if at any point the balance of account fallls below zero, and
 * at that point function should return true. Otherwise it should return false.
 * >>> below_zero [1; 2; 3]
 * false
 * >>> below_zero [1; 2; (~4); 5]
 * true
*)
let below_zero (operations : int list) : bool =


Prompt:
(**For a given list of input numbers, calculate Mean Absolute Deviation
 * around the mean of this dataset.
 * Mean Absolute Deviation is the average absolute difference between each
 * element and a centerpoint (mean in this case):
 * MAD = average | x - x_mean |
 * >>> mean_absolute_deviation [1.0; 2.0; 3.0; 4.0]
 * 1.0
*)
let mean_absolute_deviation (numbers : float list) : float =

let assertions =
 let candidate = mean_absolute_deviation in
  (assert ((candidate [1.0; 2.0]) = 0.5));
  (assert ((candidate [1.0; 2.0; 3.0; 4.0]) = 1.0));
  (assert ((candidate [1.0; 2.0; 3.0; 4.0; 5.0]) = 1.2));
  ()


Prompt:
(**Insert a number 'delimeter' between every two consecutive elements of input list `numbers'
 * >>> intersperse [] 4
 * []
 * >>> intersperse [1; 2; 3] 4
 * [1; 4; 2; 4; 3]
*)
let intersperse (numbers : int list) (delimeter : int) : int list =

let assertions =
 let candidate = intersperse in
  (assert ((candidate [] 7) = []));
  (assert ((candidate [5; 6; 3; 2] 8) = [5; 8; 6; 8; 3; 8; 2]));
  (assert ((candidate [2; 2; 2] 2) = [2; 2; 2; 2; 2]));
  ()


Prompt:
(**Input to this function is a string represented multiple groups for nested parentheses separated by spaces.
 * For each of the group, output the deepest level of nesting of parentheses.
 * E.g. (()()) has maximum two levels of nesting while ((())) has three.
 * >>> parse_nested_parens "(()()) ((())) () ((())()())"
 * [2; 3; 1; 3]
*)
let parse_nested_parens (paren_string : string) : int list =


Prompt:
(**Filter an input list of strings only for ones that contain given substring
 * >>> filter_by_substring [] "a"
 * []
 * >>> filter_by_substring ["abc"; "bacd"; "cde"; "array"] "a"
 * ["abc"; "bacd"; "array"]
*)
let filter_by_substring (strings : string list) (substring : string) : string list =

let assertions =
 let candidate = filter_by_substring in
  (assert ((candidate [] "john") = []));
  (assert ((candidate ["xxx"; "asd"; "xxy"; "john doe"; "xxxAAA"; "xxx"] "xxx") = ["xxx"; "xxxAAA"; "xxx"]));
  (assert ((candidate ["xxx"; "asd"; "aaaxxy"; "john doe"; "xxxAAA"; "xxx"] "xx") = ["xxx"; "aaaxxy"; "xxxAAA"; "xxx"]));
  (assert ((candidate ["grunt"; "trumpet"; "prune"; "gruesome"] "run") = ["grunt"; "prune"]));
  ()


Prompt:
(**For a given list of integers, return a tuple consisting of a sum and a product of all the integers in a list.
 * Empty sum should be equal to 0 and empty product should be equal to 1.
 * >>> sum_product []
 * (0, 1)
 * >>> sum_product [1; 2; 3; 4]
 * (10, 24)
*)
let sum_product (numbers : int list) :  int * int =

let assertions =
 let candidate = sum_product in
  (assert ((candidate []) = (0, 1)));
  (assert ((candidate [1; 1; 1]) = (3, 1)));
  (assert ((candidate [100; 0]) = (100, 0)));
  (assert ((candidate [3; 5; 7]) = (15, 105)));
  (assert ((candidate [10]) = (10, 10)));
  ()


Prompt:
(**From a given list of integers, generate a list of rolling maximum element found until given moment
 * in the sequence.
 * >>> rolling_max [1; 2; 3; 2; 3; 4; 2]
 * [1; 2; 3; 3; 3; 4; 4]
*)
let rolling_max (numbers : int list) : int list =


Prompt:
(**Find the shortest palindrome that begins with a supplied string.
 * Algorithm idea is simple:
 * - Find the longest postfix of supplied string that is a palindrome.
 * - Append to the end of the string reverse of a string prefix that comes before the palindromic suffix.
 * >>> make_palindrome ""
 * ""
 * >>> make_palindrome "cat"
 * "catac"
 * >>> make_palindrome "cata"
 * "catac"
*)
let make_palindrome (string : string) : string =

let assertions =
 let candidate = make_palindrome in
  (assert ((candidate "") = ""));
  (assert ((candidate "x") = "x"));
  (assert ((candidate "xyz") = "xyzyx"));
  (assert ((candidate "xyx") = "xyx"));
  (assert ((candidate "jerry") = "jerryrrej"));
  ()


Prompt:
(**Input are two strings a and b consisting only of 1s and 0s.
 * Perform binary XOR on these inputs and return result also as a string.
 * >>> string_xor "010" "110"
 * "100"
*)
let string_xor (a : string) (b : string) : string =

let assertions =
 let candidate = string_xor in
  (assert ((candidate "111000" "101010") = "010010"));
  (assert ((candidate "1" "1") = "0"));
  (assert ((candidate "0101" "0000") = "0101"));
  ()


Prompt:
(**Out of list of strings, return the longest one. Return the first one in case of multiple
 * strings of the same length. Return None in case the input list is empty.
 * >>> longest []
 * Some(None)
 * >>> longest ["a"; "b"; "c"]
 * Some("a")
 * >>> longest ["a"; "bb"; "ccc"]
 * Some("ccc")
*)
let longest (strings : string list) : string option =

let assertions =
 let candidate = longest in
  (assert ((candidate []) = Some(None)));
  (assert ((candidate ["x"; "y"; "z"]) = Some("x")));
  (assert ((candidate ["x"; "yyy"; "zzzz"; "www"; "kkkk"; "abc"]) = Some("zzzz")));
  ()


Prompt:
(**Return a greatest common divisor of two integers a and b
 * >>> greatest_common_divisor 3 5
 * 1
 * >>> greatest_common_divisor 25 15
 * 5
*)
let greatest_common_divisor (a : int) (b : int) : int =

let assertions =
 let candidate = greatest_common_divisor in
  (assert ((candidate 3 7) = 1));
  (assert ((candidate 10 15) = 5));
  (assert ((candidate 49 14) = 7));
  (assert ((candidate 144 60) = 12));
  ()


Prompt:
(**Return list of all prefixes from shortest to longest of the input string
 * >>> all_prefixes "abc"
 * ["a"; "ab"; "abc"]
*)
let all_prefixes (string : string) : string list =

let assertions =
 let candidate = all_prefixes in
  (assert ((candidate "") = []));
  (assert ((candidate "asdfgh") = ["a"; "as"; "asd"; "asdf"; "asdfg"; "asdfgh"]));
  (assert ((candidate "WWW") = ["W"; "WW"; "WWW"]));
  ()


Prompt:
(**Return a string containing space-delimited numbers starting from 0 upto n inclusive.
 * >>> string_sequence 0
 * "0"
 * >>> string_sequence 5
 * "0 1 2 3 4 5"
*)
let string_sequence (n : int) : string =

let assertions =
 let candidate = string_sequence in
  (assert ((candidate 0) = "0"));
  (assert ((candidate 3) = "0 1 2 3"));
  (assert ((candidate 10) = "0 1 2 3 4 5 6 7 8 9 10"));
  ()


Prompt:
(**Given a string, find out how many distinct characters (regardless of case) does it consist of
 * >>> count_distinct_characters "xyzXYZ"
 * 3
 * >>> count_distinct_characters "Jerry"
 * 4
*)
let count_distinct_characters (string : string) : int =

let assertions =
 let candidate = count_distinct_characters in
  (assert ((candidate "") = 0));
  (assert ((candidate "abcde") = 5));
  (assert ((candidate "abcdecadeCADE") = 5));
  (assert ((candidate "aaaaAAAAaaaa") = 1));
  (assert ((candidate "Jerry jERRY JeRRRY") = 5));
  ()


Prompt:
(**Input to this function is a string representing musical notes in a special ASCII format.
 * Your task is to parse this string and return list of integers corresponding to how many beats does each
 * not last.
 * Here is a legend:
 * 'o' - whole note, lasts four beats
 * 'o|' - half note, lasts two beats
 * '.|' - quater note, lasts one beat
 * >>> parse_music "o o| .| o| o| .| .| .| .| o o"
 * [4; 2; 1; 2; 2; 1; 1; 1; 1; 4; 4]
*)
let parse_music (music_string : string) : int list =


Prompt:
(**Find how many times a given substring can be found in the original string. Count overlaping cases.
 * >>> how_many_times "" "a"
 * 0
 * >>> how_many_times "aaa" "a"
 * 3
 * >>> how_many_times "aaaa" "aa"
 * 3
*)
let how_many_times (string : string) (substring : string) : int =

let assertions =
 let candidate = how_many_times in
  (assert ((candidate "" "x") = 0));
  (assert ((candidate "xyxyxyx" "x") = 4));
  (assert ((candidate "cacacacac" "cac") = 4));
  (assert ((candidate "john doe" "john") = 1));
  ()


Prompt:
(**Input is a space-delimited string of numberals from 'zero' to 'nine'.
 * Valid choices are 'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight' and 'nine'.
 * Return the string with numbers sorted from smallest to largest
 * >>> sort_numbers "three one five"
 * "one three five"
*)
let sort_numbers (numbers : string) : string =

let assertions =
 let candidate = sort_numbers in
  (assert ((candidate "") = ""));
  (assert ((candidate "three") = "three"));
  (assert ((candidate "three five nine") = "three five nine"));
  (assert ((candidate "five zero four seven nine eight") = "zero four five seven eight nine"));
  (assert ((candidate "six five four three two one zero") = "zero one two three four five six"));
  ()


Prompt:
(**From a supplied list of numbers (of length at least two) select and return two that are the closest to each
 * other and return them in order (smaller number, larger number).
 * >>> find_closest_elements [1.0; 2.0; 3.0; 4.0; 5.0; 2.2]
 * (2.0, 2.2)
 * >>> find_closest_elements [1.0; 2.0; 3.0; 4.0; 5.0; 2.0]
 * (2.0, 2.0)
*)
let find_closest_elements (numbers : float list) :  float * float =


Prompt:
(**Given list of numbers (of at least two elements), apply a linear transform to that list,
 * such that the smallest number will become 0 and the largest will become 1
 * >>> rescale_to_unit [1.0; 2.0; 3.0; 4.0; 5.0]
 * [0.0; 0.25; 0.5; 0.75; 1.0]
*)
let rescale_to_unit (numbers : float list) : float list =


Prompt:
(**Return length of given string
 * >>> strlen ""
 * 0
 * >>> strlen "abc"
 * 3
*)
let strlen (string : string) : int =

let assertions =
 let candidate = strlen in
  (assert ((candidate "") = 0));
  (assert ((candidate "x") = 1));
  (assert ((candidate "asdasnakj") = 9));
  ()


Prompt:
(**For a given number n, find the largest number that divides n evenly, smaller than n
 * >>> largest_divisor 15
 * 5
*)
let largest_divisor (n : int) : int =

let assertions =
 let candidate = largest_divisor in
  (assert ((candidate 3) = 1));
  (assert ((candidate 7) = 1));
  (assert ((candidate 10) = 5));
  (assert ((candidate 100) = 50));
  (assert ((candidate 49) = 7));
  ()


Prompt:
(**Return list of prime factors of given integer in the order from smallest to largest.
 * Each of the factors should be listed number of times corresponding to how many times it appeares in factorization.
 * Input number should be equal to the product of all factors
 * >>> factorize 8
 * [2; 2; 2]
 * >>> factorize 25
 * [5; 5]
 * >>> factorize 70
 * [2; 5; 7]
*)
let factorize (n : int) : int list =


Prompt:
(**From a list of integers, remove all elements that occur more than once.
 * Keep order of elements left the same as in the input.
 * >>> remove_duplicates [1; 2; 3; 2; 4]
 * [1; 3; 4]
*)
let remove_duplicates (numbers : int list) : int list =

let assertions =
 let candidate = remove_duplicates in
  (assert ((candidate []) = []));
  (assert ((candidate [1; 2; 3; 4]) = [1; 2; 3; 4]));
  (assert ((candidate [1; 2; 3; 2; 4; 3; 5]) = [1; 4; 5]));
  ()


Prompt:
(**For a given string, flip lowercase characters to uppercase and uppercase to lowercase.
 * >>> flip_case "Hello"
 * "hELLO"
*)
let flip_case (string : string) : string =

let assertions =
 let candidate = flip_case in
  (assert ((candidate "") = ""));
  (assert ((candidate "Hello!") = "hELLO!"));
  (assert ((candidate "These violent delights have violent ends") = "tHESE VIOLENT DELIGHTS HAVE VIOLENT ENDS"));
  ()


Prompt:
(**Concatenate list of strings into a single string
 * >>> concatenate []
 * ""
 * >>> concatenate ["a"; "b"; "c"]
 * "abc"
*)
let concatenate (strings : string list) : string =

let assertions =
 let candidate = concatenate in
  (assert ((candidate []) = ""));
  (assert ((candidate ["x"; "y"; "z"]) = "xyz"));
  (assert ((candidate ["x"; "y"; "z"; "w"; "k"]) = "xyzwk"));
  ()


Prompt:
(**Filter an input list of strings only for ones that start with a given prefix.
 * >>> filter_by_prefix [] "a"
 * []
 * >>> filter_by_prefix ["abc"; "bcd"; "cde"; "array"] "a"
 * ["abc"; "array"]
*)
let filter_by_prefix (strings : string list) (prefix : string) : string list =

let assertions =
 let candidate = filter_by_prefix in
  (assert ((candidate [] "john") = []));
  (assert ((candidate ["xxx"; "asd"; "xxy"; "john doe"; "xxxAAA"; "xxx"] "xxx") = ["xxx"; "xxxAAA"; "xxx"]));
  ()


Prompt:
(**Return only positive numbers in the list.
 * >>> get_positive [(~1); 2; (~4); 5; 6]
 * [2; 5; 6]
 * >>> get_positive [5; 3; (~5); 2; (~3); 3; 9; 0; 123; 1; (~10)]
 * [5; 3; 2; 3; 9; 123; 1]
*)
let get_positive (l : int list) : int list =


Prompt:
(**Return true if a given number is prime, and false otherwise.
 * >>> is_prime 6
 * false
 * >>> is_prime 101
 * true
 * >>> is_prime 11
 * true
 * >>> is_prime 13441
 * true
 * >>> is_prime 61
 * true
 * >>> is_prime 4
 * false
 * >>> is_prime 1
 * false
*)
let is_prime (n : int) : bool =

let assertions =
 let candidate = is_prime in
  (assert ((candidate 6) = false));
  (assert ((candidate 101) = true));
  (assert ((candidate 11) = true));
  (assert ((candidate 13441) = true));
  (assert ((candidate 61) = true));
  (assert ((candidate 4) = false));
  (assert ((candidate 1) = false));
  (assert ((candidate 5) = true));
  (assert ((candidate 11) = true));
  (assert ((candidate 17) = true));
  (assert ((candidate 85) = false));
  (assert ((candidate 77) = false));
  (assert ((candidate 255379) = false));
  ()


Prompt:
(**This function takes a list l and returns a list l' such that
 * l' is identical to l in the indicies that are not divisible by three, while its values at the indicies that are divisible by three are equal
 * to the values of the corresponding indicies of l, but sorted.
 * >>> sort_third [1; 2; 3]
 * [1; 2; 3]
 * >>> sort_third [5; 6; 3; 4; 8; 9; 2]
 * [2; 6; 3; 4; 8; 9; 5]
*)
let sort_third (l : int list) : int list =


Prompt:
(**Return sorted unique elements in a list
 * >>> unique [5; 3; 5; 2; 3; 3; 9; 0; 123]
 * [0; 2; 3; 5; 9; 123]
*)
let unique (l : int list) : int list =

let assertions =
 let candidate = unique in
  (assert ((candidate [5; 3; 5; 2; 3; 3; 9; 0; 123]) = [0; 2; 3; 5; 9; 123]));
  ()


Prompt:
(**Return maximum element in the list.
 * >>> max_element [1; 2; 3]
 * 3
 * >>> max_element [5; 3; (~5); 2; (~3); 3; 9; 0; 123; 1; (~10)]
 * 123
*)
let max_element (l : int list) : int =

let assertions =
 let candidate = max_element in
  (assert ((candidate [1; 2; 3]) = 3));
  (assert ((candidate [5; 3; (~5); 2; (~3); 3; 9; 0; 124; 1; (~10)]) = 124));
  ()


Prompt:
(**Return the number of times the digit 7 appears in integers less than n which are divisible by 11 or 13.
 * >>> fizz_buzz 50
 * 0
 * >>> fizz_buzz 78
 * 2
 * >>> fizz_buzz 79
 * 3
*)
let fizz_buzz (n : int) : int =

let assertions =
 let candidate = fizz_buzz in
  (assert ((candidate 50) = 0));
  (assert ((candidate 78) = 2));
  (assert ((candidate 79) = 3));
  (assert ((candidate 100) = 3));
  (assert ((candidate 200) = 6));
  (assert ((candidate 4000) = 192));
  (assert ((candidate 10000) = 639));
  (assert ((candidate 100000) = 8026));
  ()


Prompt:
(**This function takes a list l and returns a list l' such that
 * l' is identical to l in the odd indicies, while its values at the even indicies are equal
 * to the values of the even indicies of l, but sorted.
 * >>> sort_even [1; 2; 3]
 * [1; 2; 3]
 * >>> sort_even [5; 6; 3; 4]
 * [3; 6; 5; 4]
*)
let sort_even (l : int list) : int list =


Prompt:
(**prime_fib returns n-th number that is a Fibonacci number and it's also prime.
 * >>> prime_fib 1
 * 2
 * >>> prime_fib 2
 * 3
 * >>> prime_fib 3
 * 5
 * >>> prime_fib 4
 * 13
 * >>> prime_fib 5
 * 89
*)
let prime_fib (n : int) : int =

let assertions =
 let candidate = prime_fib in
  (assert ((candidate 1) = 2));
  (assert ((candidate 2) = 3));
  (assert ((candidate 3) = 5));
  (assert ((candidate 4) = 13));
  (assert ((candidate 5) = 89));
  (assert ((candidate 6) = 233));
  (assert ((candidate 7) = 1597));
  (assert ((candidate 8) = 28657));
  (assert ((candidate 9) = 514229));
  (assert ((candidate 10) = 433494437));
  ()


Prompt:
(**triples_sum_to_zero takes a list of integers as an input.
 * it returns true if there are three distinct elements in the list that
 * sum to zero, and false otherwise.
 * >>> triples_sum_to_zero [1; 3; 5; 0]
 * false
 * >>> triples_sum_to_zero [1; 3; (~2); 1]
 * true
 * >>> triples_sum_to_zero [1; 2; 3; 7]
 * false
 * >>> triples_sum_to_zero [2; 4; (~5); 3; 9; 7]
 * true
 * >>> triples_sum_to_zero [1]
 * false
*)
let triples_sum_to_zero (l : int list) : bool =

let assertions =
 let candidate = triples_sum_to_zero in
  (assert ((candidate [1; 3; 5; 0]) = false));
  (assert ((candidate [1; 3; 5; (~1)]) = false));
  (assert ((candidate [1; 3; (~2); 1]) = true));
  (assert ((candidate [1; 2; 3; 7]) = false));
  (assert ((candidate [1; 2; 5; 7]) = false));
  (assert ((candidate [2; 4; (~5); 3; 9; 7]) = true));
  (assert ((candidate [1]) = false));
  (assert ((candidate [1; 3; 5; (~100)]) = false));
  (assert ((candidate [100; 3; 5; (~100)]) = false));
  ()


Prompt:
(**Imagine a road that's a perfectly straight infinitely long line.
 * n cars are driving left to right;  simultaneously, a different set of n cars
 * are driving right to left.   The two sets of cars start out being very far from
 * each other.  All cars move in the same speed.  Two cars are said to collide
 * when a car that's moving left to right hits a car that's moving right to left.
 * However, the cars are infinitely sturdy and strong; as a result, they continue moving
 * in their trajectory as if they did not collide.
 * This function outputs the number of such collisions.
*)
let car_race_collision (n : int) : int =

let assertions =
 let candidate = car_race_collision in
  (assert ((candidate 2) = 4));
  (assert ((candidate 3) = 9));
  (assert ((candidate 4) = 16));
  (assert ((candidate 8) = 64));
  (assert ((candidate 10) = 100));
  ()


Prompt:
(**Return list with elements incremented by 1.
 * >>> incr_list [1; 2; 3]
 * [2; 3; 4]
 * >>> incr_list [5; 3; 5; 2; 3; 3; 9; 0; 123]
 * [6; 4; 6; 3; 4; 4; 10; 1; 124]
*)
let incr_list (l : int list) : int list =


Prompt:
(**pairs_sum_to_zero takes a list of integers as an input.
 * it returns true if there are two distinct elements in the list that
 * sum to zero, and false otherwise.
 * >>> pairs_sum_to_zero [1; 3; 5; 0]
 * false
 * >>> pairs_sum_to_zero [1; 3; (~2); 1]
 * false
 * >>> pairs_sum_to_zero [1; 2; 3; 7]
 * false
 * >>> pairs_sum_to_zero [2; 4; (~5); 3; 5; 7]
 * true
 * >>> pairs_sum_to_zero [1]
 * false
*)
let pairs_sum_to_zero (l : int list) : bool =

let assertions =
 let candidate = pairs_sum_to_zero in
  (assert ((candidate [1; 3; 5; 0]) = false));
  (assert ((candidate [1; 3; (~2); 1]) = false));
  (assert ((candidate [1; 2; 3; 7]) = false));
  (assert ((candidate [2; 4; (~5); 3; 5; 7]) = true));
  (assert ((candidate [1]) = false));
  (assert ((candidate [(~3); 9; (~1); 3; 2; 30]) = true));
  (assert ((candidate [(~3); 9; (~1); 3; 2; 31]) = true));
  (assert ((candidate [(~3); 9; (~1); 4; 2; 30]) = false));
  (assert ((candidate [(~3); 9; (~1); 4; 2; 31]) = false));
  ()


Prompt:
(**Change numerical base of input number x to base.
 * return string representation after the conversion.
 * base numbers are less than 10.
 * >>> change_base 8 3
 * "22"
 * >>> change_base 8 2
 * "1000"
 * >>> change_base 7 2
 * "111"
*)
let change_base (x : int) (base : int) : string =

let assertions =
 let candidate = change_base in
  (assert ((candidate 8 3) = "22"));
  (assert ((candidate 9 3) = "100"));
  (assert ((candidate 234 2) = "11101010"));
  (assert ((candidate 16 2) = "10000"));
  (assert ((candidate 8 2) = "1000"));
  (assert ((candidate 7 2) = "111"));
  (assert ((candidate 2 3) = "2"));
  (assert ((candidate 3 4) = "3"));
  (assert ((candidate 4 5) = "4"));
  (assert ((candidate 5 6) = "5"));
  (assert ((candidate 6 7) = "6"));
  (assert ((candidate 7 8) = "7"));
  ()


Prompt:
(**Given length of a side and high return area for a triangle.
 * >>> triangle_area 5 3
 * 7.5
*)
let triangle_area (a : int) (h : int) : float =

let assertions =
 let candidate = triangle_area in
  (assert ((candidate 5 3) = 7.5));
  (assert ((candidate 2 2) = 2.0));
  (assert ((candidate 10 8) = 40.0));
  ()


Prompt:
(**The Fib4 number sequence is a sequence similar to the Fibbonacci sequnece that's defined as follows:
 * fib4(0) -> 0
 * fib4(1) -> 0
 * fib4(2) -> 2
 * fib4(3) -> 0
 * fib4(n) -> fib4(n-1) + fib4(n-2) + fib4(n-3) + fib4(n-4).
 * Please write a function to efficiently compute the n-th element of the fib4 number sequence.  Do not use recursion.
 * >>> fib4 5
 * 4
 * >>> fib4 6
 * 8
 * >>> fib4 7
 * 14
*)
let fib4 (n : int) : int =

let assertions =
 let candidate = fib4 in
  (assert ((candidate 5) = 4));
  (assert ((candidate 8) = 28));
  (assert ((candidate 10) = 104));
  (assert ((candidate 12) = 386));
  ()


Prompt:
(**Return median of elements in the list l.
 * >>> median [3; 1; 2; 4; 5]
 * 3.0
 * >>> median [(~10); 4; 6; 1000; 10; 20]
 * 15.0
*)
let median (l : int list) : float =


Prompt:
(**Checks if given string is a palindrome
 * >>> is_palindrome ""
 * true
 * >>> is_palindrome "aba"
 * true
 * >>> is_palindrome "aaaaa"
 * true
 * >>> is_palindrome "zbcd"
 * false
*)
let is_palindrome (text : string) : bool =

let assertions =
 let candidate = is_palindrome in
  (assert ((candidate "") = true));
  (assert ((candidate "aba") = true));
  (assert ((candidate "aaaaa") = true));
  (assert ((candidate "zbcd") = false));
  (assert ((candidate "xywyx") = true));
  (assert ((candidate "xywyz") = false));
  (assert ((candidate "xywzx") = false));
  ()


Prompt:
(**Return 2^n modulo p (be aware of numerics).
 * >>> modp 3 5
 * 3
 * >>> modp 1101 101
 * 2
 * >>> modp 0 101
 * 1
 * >>> modp 3 11
 * 8
 * >>> modp 100 101
 * 1
*)
let modp (n : int) (p : int) : int =

let assertions =
 let candidate = modp in
  (assert ((candidate 3 5) = 3));
  (assert ((candidate 1101 101) = 2));
  (assert ((candidate 0 101) = 1));
  (assert ((candidate 3 11) = 8));
  (assert ((candidate 100 101) = 1));
  (assert ((candidate 30 5) = 4));
  (assert ((candidate 31 5) = 3));
  ()


Prompt:
(**remove_vowels is a function that takes string and returns string without vowels.
 * >>> remove_vowels ""
 * ""
 * >>> remove_vowels "abcdef"
 * "bcdf"
 * >>> remove_vowels "aaaaa"
 * ""
 * >>> remove_vowels "aaBAA"
 * "B"
 * >>> remove_vowels "zbcd"
 * "zbcd"
*)
let remove_vowels (text : string) : string =

let assertions =
 let candidate = remove_vowels in
  (assert ((candidate "") = ""));
  (assert ((candidate "abcdef
ghijklm") = "bcdf
ghjklm"));
  (assert ((candidate "fedcba") = "fdcb"));
  (assert ((candidate "eeeee") = ""));
  (assert ((candidate "acBAA") = "cB"));
  (assert ((candidate "EcBOO") = "cB"));
  (assert ((candidate "ybcd") = "ybcd"));
  ()


Prompt:
(**Return true if all numbers in the list l are below threshold t.
 * >>> below_threshold [1; 2; 4; 10] 100
 * true
 * >>> below_threshold [1; 20; 4; 10] 5
 * false
*)
let below_threshold (l : int list) (t : int) : bool =

let assertions =
 let candidate = below_threshold in
  (assert ((candidate [1; 2; 4; 10] 100) = true));
  (assert ((candidate [1; 20; 4; 10] 5) = false));
  (assert ((candidate [1; 20; 4; 10] 21) = true));
  (assert ((candidate [1; 20; 4; 10] 22) = true));
  (assert ((candidate [1; 8; 4; 10] 11) = true));
  (assert ((candidate [1; 8; 4; 10] 10) = false));
  ()


Prompt:
(**Add two numbers x and y
 * >>> add 2 3
 * 5
 * >>> add 5 7
 * 12
*)
let add (x : int) (y : int) : int =

let assertions =
 let candidate = add in
  (assert ((candidate 0 1) = 1));
  (assert ((candidate 1 0) = 1));
  (assert ((candidate 2 3) = 5));
  (assert ((candidate 5 7) = 12));
  (assert ((candidate 7 5) = 12));
  ()


Prompt:
(**Check if two words have the same characters.
 * >>> same_chars "eabcdzzzz" "dddzzzzzzzddeddabc"
 * true
 * >>> same_chars "abcd" "dddddddabc"
 * true
 * >>> same_chars "dddddddabc" "abcd"
 * true
 * >>> same_chars "eabcd" "dddddddabc"
 * false
 * >>> same_chars "abcd" "dddddddabce"
 * false
 * >>> same_chars "eabcdzzzz" "dddzzzzzzzddddabc"
 * false
*)
let same_chars (s0 : string) (s1 : string) : bool =

let assertions =
 let candidate = same_chars in
  (assert ((candidate "eabcdzzzz" "dddzzzzzzzddeddabc") = true));
  (assert ((candidate "abcd" "dddddddabc") = true));
  (assert ((candidate "dddddddabc" "abcd") = true));
  (assert ((candidate "eabcd" "dddddddabc") = false));
  (assert ((candidate "abcd" "dddddddabcf") = false));
  (assert ((candidate "eabcdzzzz" "dddzzzzzzzddddabc") = false));
  (assert ((candidate "aabb" "aaccc") = false));
  ()


Prompt:
(**Return n-th Fibonacci number.
 * >>> fib 10
 * 55
 * >>> fib 1
 * 1
 * >>> fib 8
 * 21
*)
let fib (n : int) : int =

let assertions =
 let candidate = fib in
  (assert ((candidate 10) = 55));
  (assert ((candidate 1) = 1));
  (assert ((candidate 8) = 21));
  (assert ((candidate 11) = 89));
  (assert ((candidate 12) = 144));
  ()


Prompt:
(**brackets is a string of "<" and ">".
 * return true if every opening bracket has a corresponding closing bracket.
 * >>> correct_bracketing "<"
 * false
 * >>> correct_bracketing "<>"
 * true
 * >>> correct_bracketing "<<><>>"
 * true
 * >>> correct_bracketing "><<>"
 * false
*)
let correct_bracketing (brackets : string) : bool =

let assertions =
 let candidate = correct_bracketing in
  (assert ((candidate "<>") = true));
  (assert ((candidate "<<><>>") = true));
  (assert ((candidate "<><><<><>><>") = true));
  (assert ((candidate "<><><<<><><>><>><<><><<>>>") = true));
  (assert ((candidate "<<<><>>>>") = false));
  (assert ((candidate "><<>") = false));
  (assert ((candidate "<") = false));
  (assert ((candidate "<<<<") = false));
  (assert ((candidate ">") = false));
  (assert ((candidate "<<>") = false));
  (assert ((candidate "<><><<><>><>><<>") = false));
  (assert ((candidate "<><><<><>><>>><>") = false));
  ()


Prompt:
(**Return true is list elements are monotonically increasing or decreasing.
 * >>> monotonic [1; 2; 4; 20]
 * true
 * >>> monotonic [1; 20; 4; 10]
 * false
 * >>> monotonic [4; 1; 0; (~10)]
 * true
*)
let monotonic (l : int list) : bool =

let assertions =
 let candidate = monotonic in
  (assert ((candidate [1; 2; 4; 10]) = true));
  (assert ((candidate [1; 2; 4; 20]) = true));
  (assert ((candidate [1; 20; 4; 10]) = false));
  (assert ((candidate [4; 1; 0; (~10)]) = true));
  (assert ((candidate [4; 1; 1; 0]) = true));
  (assert ((candidate [1; 2; 3; 2; 5; 60]) = false));
  (assert ((candidate [1; 2; 3; 4; 5; 60]) = true));
  (assert ((candidate [9; 9; 9; 9]) = true));
  ()


Prompt:
(**Return sorted unique common elements for two lists.
 * >>> common [1; 4; 3; 34; 653; 2; 5] [5; 7; 1; 5; 9; 653; 121]
 * [1; 5; 653]
 * >>> common [5; 3; 2; 8] [3; 2]
 * [2; 3]
*)
let common (l1 : int list) (l2 : int list) : int list =


Prompt:
(**Return the largest prime factor of n. Assume n > 1 and is not a prime.
 * >>> largest_prime_factor 13195
 * 29
 * >>> largest_prime_factor 2048
 * 2
*)
let largest_prime_factor (n : int) : int =

let assertions =
 let candidate = largest_prime_factor in
  (assert ((candidate 15) = 5));
  (assert ((candidate 27) = 3));
  (assert ((candidate 63) = 7));
  (assert ((candidate 330) = 11));
  (assert ((candidate 13195) = 29));
  ()


Prompt:
(**sum_to_n is a function that sums numbers from 1 to n.
 * >>> sum_to_n 30
 * 465
 * >>> sum_to_n 100
 * 5050
 * >>> sum_to_n 5
 * 15
 * >>> sum_to_n 10
 * 55
 * >>> sum_to_n 1
 * 1
*)
let sum_to_n (n : int) : int =

let assertions =
 let candidate = sum_to_n in
  (assert ((candidate 1) = 1));
  (assert ((candidate 6) = 21));
  (assert ((candidate 11) = 66));
  (assert ((candidate 30) = 465));
  (assert ((candidate 100) = 5050));
  ()


Prompt:
(**brackets is a string of "(" and ")".
 * return true if every opening bracket has a corresponding closing bracket.
 * >>> correct_bracketing "("
 * false
 * >>> correct_bracketing "()"
 * true
 * >>> correct_bracketing "(()())"
 * true
 * >>> correct_bracketing ")(()"
 * false
*)
let correct_bracketing (brackets : string) : bool =

let assertions =
 let candidate = correct_bracketing in
  (assert ((candidate "()") = true));
  (assert ((candidate "(()())") = true));
  (assert ((candidate "()()(()())()") = true));
  (assert ((candidate "()()((()()())())(()()(()))") = true));
  (assert ((candidate "((()())))") = false));
  (assert ((candidate ")(()") = false));
  (assert ((candidate "(") = false));
  (assert ((candidate "((((") = false));
  (assert ((candidate ")") = false));
  (assert ((candidate "(()") = false));
  (assert ((candidate "()()(()())())(()") = false));
  (assert ((candidate "()()(()())()))()") = false));
  ()


Prompt:
(**xs represent coefficients of a polynomial.
 * xs[0] + xs[1] * x + xs[2] * x^2 + ....
 * Return derivative of this polynomial in the same form.
 * >>> derivative [3; 1; 2; 4; 5]
 * [1; 4; 12; 20]
 * >>> derivative [1; 2; 3]
 * [2; 6]
*)
let derivative (xs : int list) : int list =


Prompt:
(**The FibFib number sequence is a sequence similar to the Fibbonacci sequnece that's defined as follows:
 * fibfib(0) == 0
 * fibfib(1) == 0
 * fibfib(2) == 1
 * fibfib(n) == fibfib(n-1) + fibfib(n-2) + fibfib(n-3).
 * Please write a function to efficiently compute the n-th element of the fibfib number sequence.
 * >>> fibfib 1
 * 0
 * >>> fibfib 5
 * 4
 * >>> fibfib 8
 * 24
*)
let fibfib (n : int) : int =

let assertions =
 let candidate = fibfib in
  (assert ((candidate 2) = 1));
  (assert ((candidate 1) = 0));
  (assert ((candidate 5) = 4));
  (assert ((candidate 8) = 24));
  (assert ((candidate 10) = 81));
  (assert ((candidate 12) = 274));
  (assert ((candidate 14) = 927));
  ()


Prompt:
(**Write a function vowels_count which takes a string representing
 * a word as input and returns the number of vowels in the string.
 * Vowels in this case are 'a', 'e', 'i', 'o', 'u'. Here, 'y' is also a
 * vowel, but only when it is at the end of the given word.
 * Example:
 * >>> vowels_count "abcde"
 * 2
 * >>> vowels_count "ACEDY"
 * 3
*)
let vowels_count (s : string) : int =

let assertions =
 let candidate = vowels_count in
  (assert ((candidate "abcde") = 2));
  (assert ((candidate "Alone") = 3));
  (assert ((candidate "key") = 2));
  (assert ((candidate "bye") = 1));
  (assert ((candidate "keY") = 2));
  (assert ((candidate "bYe") = 1));
  (assert ((candidate "ACEDY") = 3));
  ()


Prompt:
(**Circular shift the digits of the integer x, shift the digits right by shift
 * and return the result as a string.
 * If shift > number of digits, return digits reversed.
 * >>> circular_shift 12 1
 * "21"
 * >>> circular_shift 12 2
 * "12"
*)
let circular_shift (x : int) (shift : int) : string =

let assertions =
 let candidate = circular_shift in
  (assert ((candidate 100 2) = "001"));
  (assert ((candidate 12 2) = "12"));
  (assert ((candidate 97 8) = "79"));
  (assert ((candidate 12 1) = "21"));
  (assert ((candidate 11 101) = "11"));
  ()


Prompt:
(**Task
 * Write a function that takes a string as input and returns the sum of the upper characters only'
 * ASCII codes.
 * Examples:
 * >>> digitSum ""
 * 0
 * >>> digitSum "abAB"
 * 131
 * >>> digitSum "abcCd"
 * 67
 * >>> digitSum "helloE"
 * 69
 * >>> digitSum "woArBld"
 * 131
 * >>> digitSum "aAaaaXa"
 * 153
*)
let digitSum (s : string) : int =

let assertions =
 let candidate = digitSum in
  (assert ((candidate "") = 0));
  (assert ((candidate "abAB") = 131));
  (assert ((candidate "abcCd") = 67));
  (assert ((candidate "helloE") = 69));
  (assert ((candidate "woArBld") = 131));
  (assert ((candidate "aAaaaXa") = 153));
  (assert ((candidate " How are yOu?") = 151));
  (assert ((candidate "You arE Very Smart") = 327));
  ()


Prompt:
(**In this task, you will be given a string that represents a number of apples and oranges
 * that are distributed in a basket of fruit this basket contains
 * apples, oranges, and mango fruits. Given the string that represents the total number of
 * the oranges and apples and an integer that represent the total number of the fruits
 * in the basket return the number of the mango fruits in the basket.
 * for examble:
 * >>> fruit_distribution "5 apples and 6 oranges" 19
 * 8
 * >>> fruit_distribution "0 apples and 1 oranges" 3
 * 2
 * >>> fruit_distribution "2 apples and 3 oranges" 100
 * 95
 * >>> fruit_distribution "100 apples and 1 oranges" 120
 * 19
*)
let fruit_distribution (s : string) (n : int) : int =

let assertions =
 let candidate = fruit_distribution in
  (assert ((candidate "5 apples and 6 oranges" 19) = 8));
  (assert ((candidate "5 apples and 6 oranges" 21) = 10));
  (assert ((candidate "0 apples and 1 oranges" 3) = 2));
  (assert ((candidate "1 apples and 0 oranges" 3) = 2));
  (assert ((candidate "2 apples and 3 oranges" 100) = 95));
  (assert ((candidate "2 apples and 3 oranges" 5) = 0));
  (assert ((candidate "1 apples and 100 oranges" 120) = 19));
  ()


Prompt:
(**"Given a list representing a branch of a tree that has non-negative integer nodes
 * your task is to pluck one of the nodes and return it.
 * The plucked node should be the node with the smallest even value.
 * If multiple nodes with the same smallest even value are found return the node that has smallest index.
 * The plucked node should be returned in a list, [ smalest_value, its index ],
 * If there are no even values or the given list is empty, return [].
 * Example 1:
 * >>> pluck [4; 2; 3]
 * [2; 1]
 * Explanation: 2 has the smallest even value, and 2 has the smallest index.
 * Example 2:
 * >>> pluck [1; 2; 3]
 * [2; 1]
 * Explanation: 2 has the smallest even value, and 2 has the smallest index.
 * Example 3:
 * >>> pluck []
 * []
 * Example 4:
 * >>> pluck [5; 0; 3; 0; 4; 2]
 * [0; 1]
 * Explanation: 0 is the smallest value, but  there are two zeros,
 * so we will choose the first zero, which has the smallest index.
 * Constraints:
 * * 1 <= nodes.length <= 10000
 * * 0 <= node.value
*)
let pluck (arr : int list) : int list =


Prompt:
(**You are given a non-empty list of positive integers. Return the greatest integer that is greater than
 * zero, and has a frequency greater than or equal to the value of the integer itself.
 * The frequency of an integer is the number of times it appears in the list.
 * If no such a value exist, return -1.
 * Examples:
 * >>> search [4; 1; 2; 2; 3; 1]
 * 2
 * >>> search [1; 2; 2; 3; 3; 3; 4; 4; 4]
 * 3
 * >>> search [5; 5; 4; 4; 4]
 * (~1)
*)
let search (lst : int list) : int =


Prompt:
(**Given list of integers, return list in strange order.
 * Strange sorting, is when you start with the minimum value,
 * then maximum of the remaining integers, then minimum and so on.
 * Examples:
 * >>> strange_sort_list [1; 2; 3; 4]
 * [1; 4; 2; 3]
 * >>> strange_sort_list [5; 5; 5; 5]
 * [5; 5; 5; 5]
 * >>> strange_sort_list []
 * []
*)
let strange_sort_list (lst : int list) : int list =


Prompt:
(**Given the lengths of the three sides of a triangle. Return the area of
 * the triangle rounded to 2 decimal points if the three sides form a valid triangle.
 * Otherwise return -1
 * Three sides make a valid triangle when the sum of any two sides is greater
 * than the third side.
 * Example:
 * >>> triangle_area 3 4 5
 * 6.0
 * >>> triangle_area 1 2 10
 * (~1).0
*)
let triangle_area (a : int) (b : int) (c : int) : float =

let assertions =
 let candidate = triangle_area in
  (assert ((candidate 3 4 5) = 6.0));
  (assert ((candidate 1 2 10) = (~1).0));
  (assert ((candidate 4 8 5) = 8.18));
  (assert ((candidate 2 2 2) = 1.73));
  (assert ((candidate 1 2 3) = (~1).0));
  (assert ((candidate 10 5 7) = 16.25));
  (assert ((candidate 2 6 3) = (~1).0));
  (assert ((candidate 1 1 1) = 0.43));
  (assert ((candidate 2 2 10) = (~1).0));
  ()


Prompt:
(**Write a function that returns true if the object q will fly, and false otherwise.
 * The object q will fly if it's balanced (it is a palindromic list) and the sum of its elements is less than or equal the maximum possible weight w.
 * Example:
 * >>> will_it_fly [1; 2] 5
 * false
 * # 1+2 is less than the maximum possible weight, but it's unbalanced.
 * >>> will_it_fly [3; 2; 3] 1
 * false
 * # it's balanced, but 3+2+3 is more than the maximum possible weight.
 * >>> will_it_fly [3; 2; 3] 9
 * true
 * # 3+2+3 is less than the maximum possible weight, and it's balanced.
 * >>> will_it_fly [3] 5
 * true
 * # 3 is less than the maximum possible weight, and it's balanced.
*)
let will_it_fly (q : int list) (w : int) : bool =

let assertions =
 let candidate = will_it_fly in
  (assert ((candidate [3; 2; 3] 9) = true));
  (assert ((candidate [1; 2] 5) = false));
  (assert ((candidate [3] 5) = true));
  (assert ((candidate [3; 2; 3] 1) = false));
  (assert ((candidate [1; 2; 3] 6) = false));
  (assert ((candidate [5] 5) = true));
  ()


Prompt:
(**Given a list arr of integers, find the minimum number of elements that
 * need to be changed to make the list palindromic. A palindromic list is a list that
 * is read the same backwards and forwards. In one change, you can change one element to any other element.
 * For example:
 * >>> smallest_change [1; 2; 3; 5; 4; 7; 9; 6]
 * 4
 * >>> smallest_change [1; 2; 3; 4; 3; 2; 2]
 * 1
 * >>> smallest_change [1; 2; 3; 2; 1]
 * 0
*)
let smallest_change (arr : int list) : int =

let assertions =
 let candidate = smallest_change in
  (assert ((candidate [1; 2; 3; 5; 4; 7; 9; 6]) = 4));
  (assert ((candidate [1; 2; 3; 4; 3; 2; 2]) = 1));
  (assert ((candidate [1; 4; 2]) = 1));
  (assert ((candidate [1; 4; 4; 2]) = 1));
  (assert ((candidate [1; 2; 3; 2; 1]) = 0));
  (assert ((candidate [3; 1; 1; 3]) = 0));
  (assert ((candidate [1]) = 0));
  (assert ((candidate [0; 1]) = 1));
  ()


Prompt:
(**Write a function that accepts two lists of strings and returns the list that has
 * total number of chars in the all strings of the list less than the other list.
 * if the two lists have the same number of chars, return the first list.
 * Examples
 * >>> total_match [] []
 * []
 * >>> total_match ["hi"; "admin"] ["hI"; "Hi"]
 * ["hI"; "Hi"]
 * >>> total_match ["hi"; "admin"] ["hi"; "hi"; "admin"; "project"]
 * ["hi"; "admin"]
 * >>> total_match ["hi"; "admin"] ["hI"; "hi"; "hi"]
 * ["hI"; "hi"; "hi"]
 * >>> total_match ["4"] ["1"; "2"; "3"; "4"; "5"]
 * ["4"]
*)
let total_match (lst1 : string list) (lst2 : string list) : string list =

let assertions =
 let candidate = total_match in
  (assert ((candidate [] []) = []));
  (assert ((candidate ["hi"; "admin"] ["hi"; "hi"]) = ["hi"; "hi"]));
  (assert ((candidate ["hi"; "admin"] ["hi"; "hi"; "admin"; "project"]) = ["hi"; "admin"]));
  (assert ((candidate ["4"] ["1"; "2"; "3"; "4"; "5"]) = ["4"]));
  (assert ((candidate ["hi"; "admin"] ["hI"; "Hi"]) = ["hI"; "Hi"]));
  (assert ((candidate ["hi"; "admin"] ["hI"; "hi"; "hi"]) = ["hI"; "hi"; "hi"]));
  (assert ((candidate ["hi"; "admin"] ["hI"; "hi"; "hii"]) = ["hi"; "admin"]));
  (assert ((candidate [] ["this"]) = []));
  (assert ((candidate ["this"] []) = []));
  ()


Prompt:
(**Write a function that returns true if the given number is the multiplication of 3 prime numbers
 * and false otherwise.
 * Knowing that (a) is less then 100.
 * Example:
 * >>> is_multiply_prime 30
 * true
 * 30 = 2 * 3 * 5
*)
let is_multiply_prime (a : int) : bool =

let assertions =
 let candidate = is_multiply_prime in
  (assert ((candidate 5) = false));
  (assert ((candidate 30) = true));
  (assert ((candidate 8) = true));
  (assert ((candidate 10) = false));
  (assert ((candidate 125) = true));
  (assert ((candidate 105) = true));
  (assert ((candidate 126) = false));
  (assert ((candidate 729) = false));
  (assert ((candidate 891) = false));
  (assert ((candidate 1001) = true));
  ()


Prompt:
(**Your task is to write a function that returns true if a number x is a simple
 * power of n and false in other cases.
 * x is a simple power of n if n**int=x
 * For example:
 * >>> is_simple_power 1 4
 * true
 * >>> is_simple_power 2 2
 * true
 * >>> is_simple_power 8 2
 * true
 * >>> is_simple_power 3 2
 * false
 * >>> is_simple_power 3 1
 * false
 * >>> is_simple_power 5 3
 * false
*)
let is_simple_power (x : int) (n : int) : bool =

let assertions =
 let candidate = is_simple_power in
  (assert ((candidate 16 2) = true));
  (assert ((candidate 143214 16) = false));
  (assert ((candidate 4 2) = true));
  (assert ((candidate 9 3) = true));
  (assert ((candidate 16 4) = true));
  (assert ((candidate 24 2) = false));
  (assert ((candidate 128 4) = false));
  (assert ((candidate 12 6) = false));
  (assert ((candidate 1 1) = true));
  (assert ((candidate 1 12) = true));
  ()


Prompt:
(**Write a function that takes an integer a and returns true
 * if this ingeger is a cube of some integer number.
 * Note: you may assume the input is always valid.
 * Examples:
 * >>> iscube 1
 * true
 * >>> iscube 2
 * false
 * >>> iscube (~1)
 * true
 * >>> iscube 64
 * true
 * >>> iscube 0
 * true
 * >>> iscube 180
 * false
*)
let iscube (a : int) : bool =

let assertions =
 let candidate = iscube in
  (assert ((candidate 1) = true));
  (assert ((candidate 2) = false));
  (assert ((candidate (~1)) = true));
  (assert ((candidate 64) = true));
  (assert ((candidate 180) = false));
  (assert ((candidate 1000) = true));
  (assert ((candidate 0) = true));
  (assert ((candidate 1729) = false));
  ()


Prompt:
(**You have been tasked to write a function that receives
 * a hexadecimal number as a string and counts the number of hexadecimal
 * digits that are primes (prime number, or a prime, is a natural number
 * greater than 1 that is not a product of two smaller natural numbers).
 * Hexadecimal digits are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F.
 * Prime numbers are 2, 3, 5, 7, 11, 13, 17,...
 * So you have to determine a number of the following digits: 2, 3, 5, 7,
 * B (=decimal 11), D (=decimal 13).
 * Note: you may assume the input is always correct or empty string,
 * and symbols A,B,C,D,E,F are always uppercase.
 * Examples:
 * >>> hex_key "AB"
 * 1
 * >>> hex_key "1077E"
 * 2
 * >>> hex_key "ABED1A33"
 * 4
 * >>> hex_key "123456789ABCDEF0"
 * 6
 * >>> hex_key "2020"
 * 2
*)
let hex_key (num : string) : int =

let assertions =
 let candidate = hex_key in
  (assert ((candidate "AB") = 1));
  (assert ((candidate "1077E") = 2));
  (assert ((candidate "ABED1A33") = 4));
  (assert ((candidate "2020") = 2));
  (assert ((candidate "123456789ABCDEF0") = 6));
  (assert ((candidate "112233445566778899AABBCCDDEEFF00") = 12));
  ()


Prompt:
(**You will be given a number in decimal form and your task is to convert it to
 * binary format. The function should return a string, with each character representing a binary
 * number. Each character in the string will be '0' or '1'.
 * There will be an extra couple of characters 'db' at the beginning and at the end of the string.
 * The extra characters are there to help with the format.
 * Examples:
 * >>> decimal_to_binary 15
 * "db1111db"
 * >>> decimal_to_binary 32
 * "db100000db"
*)
let decimal_to_binary (decimal : int) : string =

let assertions =
 let candidate = decimal_to_binary in
  (assert ((candidate 0) = "db0db"));
  (assert ((candidate 32) = "db100000db"));
  (assert ((candidate 103) = "db1100111db"));
  (assert ((candidate 15) = "db1111db"));
  ()


Prompt:
(**You are given a string s.
 * Your task is to check if the string is hapml or not.
 * A string is hapml if its length is at least 3 and every 3 consecutive letters are distinct
 * For example:
 * >>> is_happy "a"
 * false
 * >>> is_happy "aa"
 * false
 * >>> is_happy "abcd"
 * true
 * >>> is_happy "aabb"
 * false
 * >>> is_happy "adb"
 * true
 * >>> is_happy "xyy"
 * false
*)
let is_happy (s : string) : bool =

let assertions =
 let candidate = is_happy in
  (assert ((candidate "a") = false));
  (assert ((candidate "aa") = false));
  (assert ((candidate "abcd") = true));
  (assert ((candidate "aabb") = false));
  (assert ((candidate "adb") = true));
  (assert ((candidate "xyy") = false));
  (assert ((candidate "iopaxpoi") = true));
  (assert ((candidate "iopaxioi") = false));
  ()


Prompt:
(**It is the last week of the semester and the teacher has to give the grades
 * to students. The teacher has been making her own algorithm for grading.
 * The only problem is, she has lost the code she used for grading.
 * She has given you a list of GPAs for some students and you have to write
 * a function that can output a list of letter grades using the following table:
 * GPA       |    Letter grade
 * 4.0                A+
 * > 3.7                A
 * > 3.3                A-
 * > 3.0                B+
 * > 2.7                B
 * > 2.3                B-
 * > 2.0                C+
 * > 1.7                C
 * > 1.3                C-
 * > 1.0                D+
 * > 0.7                D
 * > 0.0                D-
 * 0.0                E
 * Example:
 * >>> grade_equation [4.0; 3; 1.7; 2; 3.5]
 * ["A+"; "B"; "C-"; "C"; "A-"]
*)
let numerical_letter_grade (grades : float list) : string list =


Prompt:
(**Write a function that takes a string and returns true if the string
 * length is a prime number or false otherwise
 * Examples
 * >>> prime_length "Hello"
 * true
 * >>> prime_length "abcdcba"
 * true
 * >>> prime_length "kittens"
 * true
 * >>> prime_length "orange"
 * false
*)
let prime_length (string : string) : bool =

let assertions =
 let candidate = prime_length in
  (assert ((candidate "Hello") = true));
  (assert ((candidate "abcdcba") = true));
  (assert ((candidate "kittens") = true));
  (assert ((candidate "orange") = false));
  (assert ((candidate "wow") = true));
  (assert ((candidate "world") = true));
  (assert ((candidate "MadaM") = true));
  (assert ((candidate "Wow") = true));
  (assert ((candidate "") = false));
  (assert ((candidate "HI") = true));
  (assert ((candidate "go") = true));
  (assert ((candidate "gogo") = false));
  (assert ((candidate "aaaaaaaaaaaaaaa") = false));
  (assert ((candidate "Madam") = true));
  (assert ((candidate "M") = false));
  (assert ((candidate "0") = false));
  ()


Prompt:
(**Given a positive integer n, return the count of the numbers of n-digit
 * positive integers that start or end with 1.
*)
let starts_one_ends (n : int) : int =

let assertions =
 let candidate = starts_one_ends in
  (assert ((candidate 1) = 1));
  (assert ((candidate 2) = 18));
  (assert ((candidate 3) = 180));
  (assert ((candidate 4) = 1800));
  (assert ((candidate 5) = 18000));
  ()


Prompt:
(**Given a positive integer N, return the total sum of its digits in binary.
 * Example
 * >>> solve 1000
 * "1"
 * >>> solve 150
 * "110"
 * >>> solve 147
 * "1100"
 * Variables:
 * @N integer
 * Constraints: 0 ≤ N ≤ 10000.
 * Output:
 * a string of binary number
*)
let solve (N : int) : string =

let assertions =
 let candidate = solve in
  (assert ((candidate 1000) = "1"));
  (assert ((candidate 150) = "110"));
  (assert ((candidate 147) = "1100"));
  (assert ((candidate 333) = "1001"));
  (assert ((candidate 963) = "10010"));
  ()


Prompt:
(**Given a non-empty list of integers lst. add the even elements that are at odd indices..
 * Examples:
 * >>> add [4; 2; 6; 7]
 * 2
*)
let add (lst : int list) : int =

let assertions =
 let candidate = add in
  (assert ((candidate [4; 88]) = 88));
  (assert ((candidate [4; 5; 6; 7; 2; 122]) = 122));
  (assert ((candidate [4; 0; 6; 7]) = 0));
  (assert ((candidate [4; 4; 6; 8]) = 12));
  ()


Prompt:
(**Write a function that takes a string and returns an ordered version of it.
 * Ordered version of string, is a string where all words (separated by space)
 * are replaced by a new word where all the characters arranged in
 * ascending order based on ascii value.
 * Note: You should keep the order of words and blank spaces in the sentence.
 * For example:
 * >>> anti_shuffle "Hi"
 * "Hi"
 * >>> anti_shuffle "hello"
 * "ehllo"
 * >>> anti_shuffle "Hello World!!!"
 * "Hello !!!Wdlor"
*)
let anti_shuffle (s : string) : string =

let assertions =
 let candidate = anti_shuffle in
  (assert ((candidate "Hi") = "Hi"));
  (assert ((candidate "hello") = "ehllo"));
  (assert ((candidate "number") = "bemnru"));
  (assert ((candidate "abcd") = "abcd"));
  (assert ((candidate "Hello World!!!") = "Hello !!!Wdlor"));
  (assert ((candidate "") = ""));
  (assert ((candidate "Hi. My name is Mister Robot. How are you?") = ".Hi My aemn is Meirst .Rboot How aer ?ouy"));
  ()


Prompt:
(**You are given a 2 dimensional data, as a nested lists,
 * which is similar to matrix, however, unlike matrices,
 * each row may contain a different number of columns.
 * Given lst, and integer x, find integers x in the list,
 * and return list of tuples, [(x1, y1), (x2, y2) ...] such that
 * each tuple is a coordinate - (row, columns), starting with 0.
 * Sort coordinates initially by rows in ascending order.
 * Also, sort coordinates of the row by columns in descending order.
 * Examples:
 * >>> get_row [[1; 2; 3; 4; 5; 6]; [1; 2; 3; 4; 1; 6]; [1; 2; 3; 4; 5; 1]] 1
 * [(0, 0); (1, 4); (1, 0); (2, 5); (2, 0)]
 * >>> get_row [] 1
 * []
 * >>> get_row [[]; [1]; [1; 2; 3]] 3
 * [(2, 2)]
*)
let get_row (lst : int list list) (x : int) :  int * int list =


Prompt:
(**Given a list of non-negative integers, return a coml of the given list after sorting,
 * you will sort the given list in ascending order if the sum( first index value, last index value) is odd,
 * or sort it in descending order if the sum( first index value, last index value) is even.
 * Note:
 * * don't change the given list.
 * Examples:
 * >>> sort_array []
 * []
 * >>> sort_array [5]
 * [5]
 * >>> sort_array [2; 4; 3; 0; 1; 5]
 * [0; 1; 2; 3; 4; 5]
 * >>> sort_array [2; 4; 3; 0; 1; 5; 6]
 * [6; 5; 4; 3; 2; 1; 0]
*)
let sort_array (array : int list) : int list =


Prompt:
(**Create a function encrypt that takes a string as an argument and
 * returns a string encrypted with the alphabet being rotated.
 * The alphabet should be rotated in a manner such that the letters
 * shift down by two multiplied to two places.
 * For example:
 * >>> encrypt "hi"
 * "lm"
 * >>> encrypt "asdfghjkl"
 * "ewhjklnop"
 * >>> encrypt "gf"
 * "kj"
 * >>> encrypt "et"
 * "ix"
*)
let encrypt (s : string) : string =

let assertions =
 let candidate = encrypt in
  (assert ((candidate "hi") = "lm"));
  (assert ((candidate "asdfghjkl") = "ewhjklnop"));
  (assert ((candidate "gf") = "kj"));
  (assert ((candidate "et") = "ix"));
  (assert ((candidate "faewfawefaewg") = "jeiajeaijeiak"));
  (assert ((candidate "hellomyfriend") = "lippsqcjvmirh"));
  (assert ((candidate "dxzdlmnilfuhmilufhlihufnmlimnufhlimnufhfucufh") = "hbdhpqrmpjylqmpyjlpmlyjrqpmqryjlpmqryjljygyjl"));
  (assert ((candidate "a") = "e"));
  ()


Prompt:
(**You are given a list of integers.
 * Write a function next_smallest() that returns the 2nd smallest element of the list.
 * Return None if there is no such element.
 * >>> next_smallest [1; 2; 3; 4; 5]
 * Some(2)
 * >>> next_smallest [5; 1; 4; 3; 2]
 * Some(2)
 * >>> next_smallest []
 * Some(None)
 * >>> next_smallest [1; 1]
 * Some(None)
*)
let next_smallest (lst : int list) : int option =

let assertions =
 let candidate = next_smallest in
  (assert ((candidate [1; 2; 3; 4; 5]) = Some(2)));
  (assert ((candidate [5; 1; 4; 3; 2]) = Some(2)));
  (assert ((candidate []) = Some(None)));
  (assert ((candidate [1; 1]) = Some(None)));
  (assert ((candidate [1; 1; 1; 1; 0]) = Some(1)));
  (assert ((candidate [1; 1]) = Some(None)));
  (assert ((candidate [(~35); 34; 12; (~45)]) = Some((~35))));
  ()


Prompt:
(**You'll be given a string of words, and your task is to count the number
 * of boredoms. A boredom is a sentence that starts with the word "I".
 * Sentences are delimited by '.', '?' or '!'.
 * For example:
 * >>> is_bored "Hello world"
 * 0
 * >>> is_bored "The sky is blue. The sun is shining. I love this weather"
 * 1
*)
let is_bored (S : string) : int =

let assertions =
 let candidate = is_bored in
  (assert ((candidate "Hello world") = 0));
  (assert ((candidate "Is the sky blue?") = 0));
  (assert ((candidate "I love It !") = 1));
  (assert ((candidate "bIt") = 0));
  (assert ((candidate "I feel good today. I will be productive. will kill It") = 2));
  (assert ((candidate "You and I are going for a walk") = 0));
  ()


Prompt:
(**Create a function that takes 3 numbers.
 * Returns true if one of the numbers is equal to the sum of the other two, and all numbers are integers.
 * Returns false in any other cases.
 * Examples
 * >>> any_int 5 2 7
 * true
 * >>> any_int 3 2 2
 * false
 * >>> any_int 3 (~2) 1
 * true
 * >>> any_int 3.6 -2.2 2
 * false
*)
let any_int (x : float) (y : float) (z : float) : bool =

let assertions =
 let candidate = any_int in
  (assert ((candidate 2.0 3.0 1.0) = true));
  (assert ((candidate 2.5 2.0 3.0) = false));
  (assert ((candidate 1.5 5.0 3.5) = false));
  (assert ((candidate 2.0 6.0 2.0) = false));
  (assert ((candidate 4.0 2.0 2.0) = true));
  (assert ((candidate 2.2 2.2 2.2) = false));
  (assert ((candidate (~4).0 6.0 2.0) = true));
  (assert ((candidate 2.0 1.0 1.0) = true));
  (assert ((candidate 3.0 4.0 7.0) = true));
  (assert ((candidate 3.0 4.0 7.0) = false));
  ()


Prompt:
(**Write a function that takes a message, and encodes in such a
 * way that it swaps case of all letters, replaces all vowels in
 * the message with the letter that appears 2 places ahead of that
 * vowel in the english alphabet.
 * Assume only letters.
 * Examples:
 * >>> encode "test"
 * "TGST"
 * >>> encode "This is a message"
 * "tHKS KS C MGSSCGG"
*)
let encode (message : string) : string =

let assertions =
 let candidate = encode in
  (assert ((candidate "TEST") = "tgst"));
  (assert ((candidate "Mudasir") = "mWDCSKR"));
  (assert ((candidate "YES") = "ygs"));
  (assert ((candidate "This is a message") = "tHKS KS C MGSSCGG"));
  (assert ((candidate "I DoNt KnOw WhAt tO WrItE") = "k dQnT kNqW wHcT Tq wRkTg"));
  ()


Prompt:
(**You are given a list of integers.
 * You need to find the largest prime value and return the sum of its digits.
 * Examples:
 * >>> skjkasdkd [0; 3; 2; 1; 3; 5; 7; 4; 5; 5; 5; 2; 181; 32; 4; 32; 3; 2; 32; 324; 4; 3]
 * 10
 * >>> skjkasdkd [1; 0; 1; 8; 2; 4597; 2; 1; 3; 40; 1; 2; 1; 2; 4; 2; 5; 1]
 * 25
 * >>> skjkasdkd [1; 3; 1; 32; 5107; 34; 83278; 109; 163; 23; 2323; 32; 30; 1; 9; 3]
 * 13
 * >>> skjkasdkd [0; 724; 32; 71; 99; 32; 6; 0; 5; 91; 83; 0; 5; 6]
 * 11
 * >>> skjkasdkd [0; 81; 12; 3; 1; 21]
 * 3
 * >>> skjkasdkd [0; 8; 1; 2; 1; 7]
 * 7
*)
let skjkasdkd (lst : int list) : int =


Prompt:
(**Given an association list, return true if all keys are strings in lower
 * case or all keys are strings in upper case, else return false.
 * The function should return false is the given association list is empty.
 * Examples:
 * >>> check_dict_case [("a", "apple"); ("b", "banana")]
 * true
 * >>> check_dict_case [("a", "apple"); ("A", "banana"); ("B", "banana")]
 * false
 * >>> check_dict_case [("a", "apple"); (8, "banana"); ("a", "apple")]
 * false
 * >>> check_dict_case [("Name", "John"); ("Age", "36"); ("City", "Houston")]
 * false
 * >>> check_dict_case [("STATE", "NC"); ("ZIP", "12345")]
 * true
*)
let check_dict_case (dict : (string, string) list) : bool =

let assertions =
 let candidate = check_dict_case in
  (assert ((candidate [("p", "pineapple"); ("b", "banana")]) = true));
  (assert ((candidate [("p", "pineapple"); ("A", "banana"); ("B", "banana")]) = false));
  (assert ((candidate [("p", "pineapple"); ("5", "banana"); ("a", "apple")]) = false));
  (assert ((candidate [("Name", "John"); ("Age", "36"); ("City", "Houston")]) = false));
  (assert ((candidate [("STATE", "NC"); ("ZIP", "12345")]) = true));
  (assert ((candidate [("fruit", "Orange"); ("taste", "Sweet")]) = true));
  (assert ((candidate []) = false));
  ()


Prompt:
(**Implement a function that takes an non-negative integer and returns a list of the first n
 * integers that are prime numbers and less than n.
 * for example:
 * >>> count_up_to 5
 * [2; 3]
 * >>> count_up_to 11
 * [2; 3; 5; 7]
 * >>> count_up_to 0
 * []
 * >>> count_up_to 20
 * [2; 3; 5; 7; 11; 13; 17; 19]
 * >>> count_up_to 1
 * []
 * >>> count_up_to 18
 * [2; 3; 5; 7; 11; 13; 17]
*)
let count_up_to (n : int) : int list =


Prompt:
(**Complete the function that takes two integers and returns
 * the product of their unit digits.
 * Assume the input is always valid.
 * Examples:
 * >>> multiply 148 412
 * 16
 * >>> multiply 19 28
 * 72
 * >>> multiply 2020 1851
 * 0
 * >>> multiply 14 (~15)
 * 20
*)
let multiply (a : int) (b : int) : int =

let assertions =
 let candidate = multiply in
  (assert ((candidate 148 412) = 16));
  (assert ((candidate 19 28) = 72));
  (assert ((candidate 2020 1851) = 0));
  (assert ((candidate 14 (~15)) = 20));
  (assert ((candidate 76 67) = 42));
  (assert ((candidate 17 27) = 49));
  (assert ((candidate 0 1) = 0));
  (assert ((candidate 0 0) = 0));
  ()


Prompt:
(**Given a string s, count the number of uppercase vowels in even indices.
 * For example:
 * >>> count_upper "aBCdEf"
 * 1
 * >>> count_upper "abcdefg"
 * 0
 * >>> count_upper "dBBE"
 * 0
*)
let count_upper (s : string) : int =

let assertions =
 let candidate = count_upper in
  (assert ((candidate "aBCdEf") = 1));
  (assert ((candidate "abcdefg") = 0));
  (assert ((candidate "dBBE") = 0));
  (assert ((candidate "B") = 0));
  (assert ((candidate "U") = 1));
  (assert ((candidate "") = 0));
  (assert ((candidate "EEEE") = 2));
  ()


Prompt:
(**Create a function that takes a value (string) representing a number
 * and returns the closest integer to it. If the number is equidistant
 * from two integers, round it away from zero.
 * Examples
 * >>> closest_integer "10"
 * 10
 * >>> closest_integer "15.3"
 * 15
 * Note:
 * Rounding away from zero means that if the given number is equidistant
 * from two integers, the one you should return is the one that is the
 * farthest from zero. For example closest_integer("14.5") should
 * return 15 and closest_integer("-14.5") should return -15.
*)
let closest_integer (value : string) : int =

let assertions =
 let candidate = closest_integer in
  (assert ((candidate "10") = 10));
  (assert ((candidate "14.5") = 15));
  (assert ((candidate "-15.5") = (~16)));
  (assert ((candidate "15.3") = 15));
  (assert ((candidate "0") = 0));
  ()


Prompt:
(**Given a positive integer n, you have to make a pile of n levels of stones.
 * The first level has n stones.
 * The number of stones in the next level is:
 * - the next odd number if n is odd.
 * - the next even number if n is even.
 * Return the number of stones in each level in a list, where element at index
 * i represents the number of stones in the level (i+1).
 * Examples:
 * >>> make_a_pile 3
 * [3; 5; 7]
*)
let make_a_pile (n : int) : int list =


Prompt:
(**You will be given a string of words separated by commas or spaces. Your task is
 * to split the string into words and return a list of the words.
 * For example:
 * >>> words_string "Hi, my name is John"
 * ["Hi"; "my"; "name"; "is"; "John"]
 * >>> words_string "One, two, three, four, five, six"
 * ["One"; "two"; "three"; "four"; "five"; "six"]
*)
let words_string (s : string) : string list =

let assertions =
 let candidate = words_string in
  (assert ((candidate "Hi, my name is John") = ["Hi"; "my"; "name"; "is"; "John"]));
  (assert ((candidate "One, two, three, four, five, six") = ["One"; "two"; "three"; "four"; "five"; "six"]));
  (assert ((candidate "Hi, my name") = ["Hi"; "my"; "name"]));
  (assert ((candidate "One,, two, three, four, five, six,") = ["One"; "two"; "three"; "four"; "five"; "six"]));
  (assert ((candidate "") = []));
  (assert ((candidate "ahmed     , gamal") = ["ahmed"; "gamal"]));
  ()


Prompt:
(**This function takes two positive numbers x and y and returns the
 * biggest even integer number that is in the range [x, y] inclusive. If
 * there's no such number, then the function should return -1.
 * For example:
 * >>> choose_num 12 15
 * 14
 * >>> choose_num 13 12
 * (~1)
*)
let choose_num (x : int) (y : int) : int =

let assertions =
 let candidate = choose_num in
  (assert ((candidate 12 15) = 14));
  (assert ((candidate 13 12) = (~1)));
  (assert ((candidate 33 12354) = 12354));
  (assert ((candidate 5234 5233) = (~1)));
  (assert ((candidate 6 29) = 28));
  (assert ((candidate 27 10) = (~1)));
  (assert ((candidate 7 7) = (~1)));
  (assert ((candidate 546 546) = 546));
  ()


Prompt:
(**Given a list of positive integers x. return a sorted list of all
 * elements that hasn't any even digit.
 * Note: Returned list should be sorted in increasing order.
 * For example:
 * >>> unique_digits [15; 33; 1422; 1]
 * [1; 15; 33]
 * >>> unique_digits [152; 323; 1422; 10]
 * []
*)
let unique_digits (x : int list) : int list =


Prompt:
(**Given a list of integers, sort the integers that are between 1 and 9 inclusive,
 * reverse the resulting list, and then replace each digit by its corresponding name from
 * "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine".
 * For example:
 * >>> by_length [2; 1; 1; 4; 5; 8; 2; 3]
 * ["Eight"; "Five"; "Four"; "Three"; "Two"; "Two"; "One"; "One"]
 * If the list is empty, return an empty list:
 * >>> by_length []
 * []
 * If the list has any strange number ignore it:
 * >>> by_length [1; (~1); 55]
 * ["One"]
*)
let by_length (arr : int list) : string list =

let assertions =
 let candidate = by_length in
  (assert ((candidate [2; 1; 1; 4; 5; 8; 2; 3]) = ["Eight"; "Five"; "Four"; "Three"; "Two"; "Two"; "One"; "One"]));
  (assert ((candidate []) = []));
  (assert ((candidate [1; (~1); 55]) = ["One"]));
  (assert ((candidate [1; (~1); 3; 2]) = ["Three"; "Two"; "One"]));
  (assert ((candidate [9; 4; 8]) = ["Nine"; "Eight"; "Four"]));
  ()


Prompt:
(**Implement the function f that takes n as a parameter,
 * and returns a list of size n, such that the value of the element at index i is the factorial of i if i is even
 * or the sum of numbers from 1 to i otherwise.
 * i starts from 1.
 * the factorial of i is the multiplication of the numbers from 1 to i (1 * 2 * ... * i).
 * Example:
 * >>> f 5
 * [1; 2; 6; 24; 15]
*)
let f (n : int) : int list =

let assertions =
 let candidate = f in
  (assert ((candidate 5) = [1; 2; 6; 24; 15]));
  (assert ((candidate 7) = [1; 2; 6; 24; 15; 720; 28]));
  (assert ((candidate 1) = [1]));
  (assert ((candidate 3) = [1; 2; 6]));
  ()


Prompt:
(**Given a positive integer n, return a tuple that has the number of even and odd
 * integer palindromes that fall within the range(1, n), inclusive.
 * Example 1:
 * >>> even_odd_palindrome 3
 * (1, 2)
 * Explanation:
 * Integer palindrome are 1, 2, 3. one of them is even, and two of them are odd.
 * Example 2:
 * >>> even_odd_palindrome 12
 * (4, 6)
 * Explanation:
 * Integer palindrome are 1, 2, 3, 4, 5, 6, 7, 8, 9, 11. four of them are even, and 6 of them are odd.
 * Note:
 * 1. 1 <= n <= 10^3
 * 2. returned tuple has the number of even and odd integer palindromes respectively.
*)
let even_odd_palindrome (n : int) :  int * int =

let assertions =
 let candidate = even_odd_palindrome in
  (assert ((candidate 123) = (8, 13)));
  (assert ((candidate 12) = (4, 6)));
  (assert ((candidate 3) = (1, 2)));
  (assert ((candidate 63) = (6, 8)));
  (assert ((candidate 25) = (5, 6)));
  (assert ((candidate 19) = (4, 6)));
  (assert ((candidate 9) = (4, 5)));
  (assert ((candidate 1) = (0, 1)));
  ()


Prompt:
(**Write a function count_nums which takes a list of integers and returns
 * the number of elements which has a sum of digits > 0.
 * If a number is negative, then its first signed digit will be negative:
 * e.g. -123 has signed digits -1, 2, and 3.
 * >>> count_nums []
 * 0
 * >>> count_nums [(~1); 11; (~11)]
 * 1
 * >>> count_nums [1; 1; 2]
 * 3
*)
let count_nums (arr : int list) : int =


Prompt:
(**We have a list 'arr' of N integers arr[1], arr[2], ..., arr[N].The
 * numbers in the list will be randomly ordered. Your task is to determine if
 * it is possible to get a list sorted in non-decreasing order by performing
 * the following operation on the given list:
 * You are allowed to perform right shift operation any number of times.
 * One right shift operation means shifting all elements of the list by one
 * position in the right direction. The last element of the list will be moved to
 * the starting position in the list i.e. 0th index.
 * If it is possible to obtain the sorted list by performing the above operation
 * then return true else return false.
 * If the given list is empty then return true.
 * Note: The given list is guaranteed to have unique elements.
 * For Example:
 * >>> move_one_ball [3; 4; 5; 1; 2]
 * true
 * Explanation: By performin 2 right shift operations, non-decreasing order can
 * be achieved for the given list.
 * >>> move_one_ball [3; 5; 4; 1; 2]
 * false
 * Explanation:It is not possible to get non-decreasing order for the given
 * list by performing any number of right shift operations.
*)
let move_one_ball (arr : int list) : bool =

let assertions =
 let candidate = move_one_ball in
  (assert ((candidate [3; 4; 5; 1; 2]) = true));
  (assert ((candidate [3; 5; 10; 1; 2]) = true));
  (assert ((candidate [4; 3; 1; 2]) = false));
  (assert ((candidate [3; 5; 4; 1; 2]) = false));
  (assert ((candidate []) = true));
  ()


Prompt:
(**In this problem, you will implement a function that takes two lists of numbers,
 * and determines whether it is possible to perform an exchange of elements
 * between them to make lst1 a list of only even numbers.
 * There is no limit on the number of exchanged elements between lst1 and lst2.
 * If it is possible to exchange elements between the lst1 and lst2 to make
 * all the elements of lst1 to be even, return "YES".
 * Otherwise, return "NO".
 * For example:
 * >>> exchange [1; 2; 3; 4] [1; 2; 3; 4]
 * "YES"
 * >>> exchange [1; 2; 3; 4] [1; 5; 3; 4]
 * "NO"
 * It is assumed that the input lists will be non-empty.
*)
let exchange (lst1 : int list) (lst2 : int list) : string =


Prompt:
(**Given a string representing a space separated lowercase letters, return an association list
 * of the letter with the most repetition and containing the corresponding count.
 * If several letters have the same occurrence, return all of them.
 * Example:
 * >>> histogram "a b c"
 * [("a", 1); ("b", 1); ("c", 1)]
 * >>> histogram "a b b a"
 * [("a", 2); ("b", 2)]
 * >>> histogram "a b c a b"
 * [("a", 2); ("b", 2)]
 * >>> histogram "b b b b a"
 * [("b", 4)]
 * >>> histogram ""
 * []
*)
let histogram (test : string) : (string, int) list =


Prompt:
(**Task
 * We are given two strings s and c, you have to deleted all the characters in s that are equal to any character in c
 * then check if the result string is palindrome.
 * A string is called palindrome if it reads the same backward as forward.
 * You should return a tuple containing the result string and true/false for the check.
 * Example
 * >>> reverse_delete "abcde" "ae"
 * ("bcd", false)
 * >>> reverse_delete "abcdef" "b"
 * ("acdef", false)
 * >>> reverse_delete "abcdedcba" "ab"
 * ("cdedc", true)
*)
let reverse_delete (s : string) (c : string) :  string * bool =

let assertions =
 let candidate = reverse_delete in
  (assert ((candidate "abcde" "ae") = ("bcd", false)));
  (assert ((candidate "abcdef" "b") = ("acdef", false)));
  (assert ((candidate "abcdedcba" "ab") = ("cdedc", true)));
  (assert ((candidate "dwik" "w") = ("dik", false)));
  (assert ((candidate "a" "a") = ("", true)));
  (assert ((candidate "abcdedcba" "") = ("abcdedcba", true)));
  (assert ((candidate "abcdedcba" "v") = ("abcdedcba", true)));
  (assert ((candidate "vabba" "v") = ("abba", true)));
  (assert ((candidate "mamma" "mia") = ("", true)));
  ()


Prompt:
(**Given a list of strings, where each string consists of only digits, return a list.
 * Each element i of the output should be "the number of odd elements in the
 * string i of the input." where all the i's should be replaced by the number
 * of odd digits in the i'th string of the input.
 * >>> odd_count ["1234567"]
 * ["the number of odd elements 4n the str4ng 4 of the 4nput."]
 * >>> odd_count ["3"; "11111111"]
 * ["the number of odd elements 1n the str1ng 1 of the 1nput."; "the number of odd elements 8n the str8ng 8 of the 8nput."]
*)
let odd_count (lst : string list) : string list =

let assertions =
 let candidate = odd_count in
  (assert ((candidate ["1234567"]) = ["the number of odd elements 4n the str4ng 4 of the 4nput."]));
  (assert ((candidate ["3"; "11111111"]) = ["the number of odd elements 1n the str1ng 1 of the 1nput."; "the number of odd elements 8n the str8ng 8 of the 8nput."]));
  (assert ((candidate ["271"; "137"; "314"]) = ["the number of odd elements 2n the str2ng 2 of the 2nput."; "the number of odd elements 3n the str3ng 3 of the 3nput."; "the number of odd elements 2n the str2ng 2 of the 2nput."]));
  ()


Prompt:
(**Given a list of integers nums, find the minimum sum of any non-empty sub-list
 * of nums.
 * Example
 * >>> minSubArraySum [2; 3; 4; 1; 2; 4]
 * 1
 * >>> minSubArraySum [(~1); (~2); (~3)]
 * (~6)
*)
let minSubArraySum (nums : int list) : int =


Prompt:
(**You are given a rectangular grid of wells. Each row represents a single well,
 * and each 1 in a row represents a single unit of water.
 * Each well has a corresponding bucket that can be used to extract water from it,
 * and all buckets have the same capacity.
 * Your task is to use the buckets to empty the wells.
 * Output the number of times you need to lower the buckets.
 * Example 1:
 * >>> max_fill [[0; 0; 1; 0]; [0; 1; 0; 0]; [1; 1; 1; 1]] 1
 * 6
 * Example 2:
 * >>> max_fill [[0; 0; 1; 1]; [0; 0; 0; 0]; [1; 1; 1; 1]; [0; 1; 1; 1]] 2
 * 5
 * Example 3:
 * >>> max_fill [[0; 0; 0]; [0; 0; 0]] 5
 * 0
 * Constraints:
 * * all wells have the same length
 * * 1 <= grid.length <= 10^2
 * * 1 <= grid[:,1].length <= 10^2
 * * grid[i][j] -> 0 | 1
 * * 1 <= capacity <= 10
*)
let max_fill (grid : int list list) (capacity : int) : int =


Prompt:
(**In this Kata, you have to sort a list of non-negative integers according to
 * number of ones in their binary representation in ascending order.
 * For similar number of ones, sort based on decimal value.
 * It must be implemented like this:
 * >>> sort_array [1; 5; 2; 3; 4]
 * [1; 2; 3; 4; 5]
 * >>> sort_array [(~2); (~3); (~4); (~5); (~6)]
 * [(~6); (~5); (~4); (~3); (~2)]
 * >>> sort_array [1; 0; 2; 3; 4]
 * [0; 1; 2; 3; 4]
*)
let sort_array (arr : int list) : int list =


Prompt:
(**Given a string s and a natural number n, you have been tasked to implement
 * a function that returns a list of all words from string s that contain exactly
 * n consonants, in order these words appear in the string s.
 * If the string s is empty then the function should return an empty list.
 * Note: you may assume the input string contains only letters and spaces.
 * Examples:
 * >>> select_words "Mary had a little lamb" 4
 * ["little"]
 * >>> select_words "Mary had a little lamb" 3
 * ["Mary"; "lamb"]
 * >>> select_words "simple white space" 2
 * []
 * >>> select_words "Hello world" 4
 * ["world"]
 * >>> select_words "Uncle sam" 3
 * ["Uncle"]
*)
let select_words (s : string) (n : int) : string list =

let assertions =
 let candidate = select_words in
  (assert ((candidate "Mary had a little lamb" 4) = ["little"]));
  (assert ((candidate "Mary had a little lamb" 3) = ["Mary"; "lamb"]));
  (assert ((candidate "simple white space" 2) = []));
  (assert ((candidate "Hello world" 4) = ["world"]));
  (assert ((candidate "Uncle sam" 3) = ["Uncle"]));
  (assert ((candidate "" 4) = []));
  (assert ((candidate "a b c d e f" 1) = ["b"; "c"; "d"; "f"]));
  ()


Prompt:
(**You are given a word. Your task is to find the closest vowel that stands between
 * two consonants from the right side of the word (case sensitive).
 * Vowels in the beginning and ending doesn't count. Return empty string if you didn't
 * find any vowel met the above condition.
 * You may assume that the given string contains English letter only.
 * Example:
 * >>> get_closest_vowel "yogurt"
 * "u"
 * >>> get_closest_vowel "FULL"
 * "U"
 * >>> get_closest_vowel "quick"
 * ""
 * >>> get_closest_vowel "ab"
 * ""
*)
let get_closest_vowel (word : string) : string =

let assertions =
 let candidate = get_closest_vowel in
  (assert ((candidate "yogurt") = "u"));
  (assert ((candidate "full") = "u"));
  (assert ((candidate "easy") = ""));
  (assert ((candidate "eAsy") = ""));
  (assert ((candidate "ali") = ""));
  (assert ((candidate "bad") = "a"));
  (assert ((candidate "most") = "o"));
  (assert ((candidate "ab") = ""));
  (assert ((candidate "ba") = ""));
  (assert ((candidate "quick") = ""));
  (assert ((candidate "anime") = "i"));
  (assert ((candidate "Asia") = ""));
  (assert ((candidate "Above") = "o"));
  ()


Prompt:
(**You are given a list of two strings, both strings consist of open
 * parentheses '(' or close parentheses ')' only.
 * Your job is to check if it is possible to concatenate the two strings in
 * some order, that the resulting string will be good.
 * A string S is considered to be good if and only if all parentheses in S
 * are balanced. For example: the string '(())()' is good, while the string
 * '())' is not.
 * Return 'Yes' if there's a way to make a good string, and return 'No' otherwise.
 * Examples:
 * >>> match_parens ["()("; ")"]
 * "Yes"
 * >>> match_parens [")"; ")"]
 * "No"
*)
let match_parens (lst : string list) : string =


Prompt:
(**Given a list arr of integers and a positive integer k, return a sorted list
 * of length k with the maximum k numbers in arr.
 * Example 1:
 * >>> maximum [(~3); (~4); 5] 3
 * [(~4); (~3); 5]
 * Example 2:
 * >>> maximum [4; (~4); 4] 2
 * [4; 4]
 * Example 3:
 * >>> maximum [(~3); 2; 1; 2; (~1); (~2); 1] 1
 * [2]
 * Note:
 * 1. The length of the list will be in the range of [1, 1000].
 * 2. The elements in the list will be in the range of [-1000, 1000].
 * 3. 0 <= k <= len(arr)
*)
let maximum (arr : int list) (k : int) : int list =


Prompt:
(**Given a non-empty list of integers, return the sum of all of the odd elements that are in even positions.
 * Examples
 * >>> solution [5; 8; 7; 1]
 * 12
 * >>> solution [3; 3; 3; 3; 3]
 * 9
 * >>> solution [30; 13; 24; 321]
 * 0
*)
let solution (lst : int list) : int =

let assertions =
 let candidate = solution in
  (assert ((candidate [5; 8; 7; 1]) = 12));
  (assert ((candidate [3; 3; 3; 3; 3]) = 9));
  (assert ((candidate [30; 13; 24; 321]) = 0));
  (assert ((candidate [5; 9]) = 5));
  (assert ((candidate [2; 4; 8]) = 0));
  (assert ((candidate [30; 13; 23; 32]) = 23));
  (assert ((candidate [3; 13; 2; 9]) = 3));
  ()


Prompt:
(**Given a non-empty list of integers arr and an integer k, return
 * the sum of the elements with at most two digits from the first k elements of arr.
 * Example:
 * >>> add_elements [111; 21; 3; 4000; 5; 6; 7; 8; 9] 4
 * 24
 * Constraints:
 * 1. 1 <= len(arr) <= 100
 * 2. 1 <= k <= len(arr)
*)
let add_elements (arr : int list) (k : int) : int =


Prompt:
(**Given a positive integer n, return a sorted list that has the odd numbers in collatz sequence.
 * The Collatz conjecture is a conjecture in mathematics that concerns a sequence defined
 * as follows: start with any positive integer n. Then each term is obtained from the
 * previous term as follows: if the previous term is even, the next term is one half of
 * the previous term. If the previous term is odd, the next term is 3 times the previous
 * term plus 1. The conjecture is that no matter what value of n, the sequence will always reach 1.
 * Note:
 * 1. Collatz(1) is [1].
 * 2. returned list sorted in increasing order.
 * For example:
 * get_odd_collatz(5) returns [1, 5] # The collatz sequence for 5 is [5, 16, 8, 4, 2, 1], so the odd numbers are only 1, and 5.
 * >>> get_odd_collatz 5
 * [1; 5]
*)
let get_odd_collatz (n : int) : int list =

let assertions =
 let candidate = get_odd_collatz in
  (assert ((candidate 14) = [1; 5; 7; 11; 13; 17]));
  (assert ((candidate 5) = [1; 5]));
  (assert ((candidate 12) = [1; 3; 5]));
  (assert ((candidate 1) = [1]));
  ()


Prompt:
(**You have to write a function which validates a given date string and
 * returns true if the date is valid otherwise false.
 * The date is valid if all of the following rules are satisfied:
 * 1. The date string is not empty.
 * 2. The number of days is not less than 1 or higher than 31 days for months 1,3,5,7,8,10,12. And the number of days is not less than 1 or higher than 30 days for months 4,6,9,11. And, the number of days is not less than 1 or higher than 29 for the month 2.
 * 3. The months should not be less than 1 or higher than 12.
 * 4. The date should be in the format: mm-dd-yyyy
 * >>> valid_date "03-11-2000"
 * true
 * >>> valid_date "15-01-2012"
 * false
 * >>> valid_date "04-0-2040"
 * false
 * >>> valid_date "06-04-2020"
 * true
 * >>> valid_date "06/04/2020"
 * false
*)
let valid_date (date : string) : bool =

let assertions =
 let candidate = valid_date in
  (assert ((candidate "03-11-2000") = true));
  (assert ((candidate "15-01-2012") = false));
  (assert ((candidate "04-0-2040") = false));
  (assert ((candidate "06-04-2020") = true));
  (assert ((candidate "01-01-2007") = true));
  (assert ((candidate "03-32-2011") = false));
  (assert ((candidate "") = false));
  (assert ((candidate "04-31-3000") = false));
  (assert ((candidate "06-06-2005") = true));
  (assert ((candidate "21-31-2000") = false));
  (assert ((candidate "04-12-2003") = true));
  (assert ((candidate "04122003") = false));
  (assert ((candidate "20030412") = false));
  (assert ((candidate "2003-04") = false));
  (assert ((candidate "2003-04-12") = false));
  (assert ((candidate "04-2003") = false));
  ()


Prompt:
(**Given a list of numbers, return whether or not they are sorted
 * in ascending order. If list has more than 1 duplicate of the same
 * number, return false. Assume no negative numbers and only integers.
 * Examples
 * >>> is_sorted [5]
 * true
 * >>> is_sorted [1; 2; 3; 4; 5]
 * true
 * >>> is_sorted [1; 3; 2; 4; 5]
 * false
 * >>> is_sorted [1; 2; 3; 4; 5; 6]
 * true
 * >>> is_sorted [1; 2; 3; 4; 5; 6; 7]
 * true
 * >>> is_sorted [1; 3; 2; 4; 5; 6; 7]
 * false
 * >>> is_sorted [1; 2; 2; 3; 3; 4]
 * true
 * >>> is_sorted [1; 2; 2; 2; 3; 4]
 * false
*)
let is_sorted (lst : int list) : bool =

let assertions =
 let candidate = is_sorted in
  (assert ((candidate [5]) = true));
  (assert ((candidate [1; 2; 3; 4; 5]) = true));
  (assert ((candidate [1; 3; 2; 4; 5]) = false));
  (assert ((candidate [1; 2; 3; 4; 5; 6]) = true));
  (assert ((candidate [1; 2; 3; 4; 5; 6; 7]) = true));
  (assert ((candidate [1; 3; 2; 4; 5; 6; 7]) = false));
  (assert ((candidate []) = true));
  (assert ((candidate [1]) = true));
  (assert ((candidate [3; 2; 1]) = false));
  (assert ((candidate [1; 2; 2; 2; 3; 4]) = false));
  (assert ((candidate [1; 2; 3; 3; 3; 4]) = false));
  (assert ((candidate [1; 2; 2; 3; 3; 4]) = true));
  (assert ((candidate [1; 2; 3; 4]) = true));
  ()


Prompt:
(**You are given two intervals,
 * where each interval is a pair of integers. For example, interval = (start, end) = (1, 2).
 * The given intervals are closed which means that the interval (start, end)
 * includes both start and end.
 * For each given interval, it is assumed that its start is less or equal its end.
 * Your task is to determine whether the length of intersection of these two
 * intervals is a prime number.
 * Example, the intersection of the intervals (1, 3), (2, 4) is (2, 3)
 * which its length is 1, which not a prime number.
 * If the length of the intersection is a prime number, return "YES",
 * otherwise, return "NO".
 * If the two intervals don't intersect, return "NO".
 * [input/output] samples:
 * >>> intersection (1, 2) (2, 3)
 * "NO"
 * >>> intersection ((~1), 1) (0, 4)
 * "NO"
 * >>> intersection ((~3), (~1)) ((~5), 5)
 * "YES"
*)
let intersection (interval1 :  int * int) (interval2 :  int * int) : string =


Prompt:
(**You are given a list arr of integers and you need to return
 * sum of magnitudes of integers multiplied by product of all signs
 * of each number in the list, represented by 1, -1 or 0.
 * Note: return None for empty arr.
 * Example:
 * >>> prod_signs [1; 2; 2; (~4)]
 * Some(9)
 * >>> prod_signs [0; 1]
 * Some(0)
 * >>> prod_signs []
 * Some(None)
*)
let prod_signs (arr : int list) : int option =


Prompt:
(**Given a grid with N rows and N columns (N >= 2) and a positive integer k,
 * each cell of the grid contains a value. Every integer in the range [1, N * N]
 * inclusive appears exactly once on the cells of the grid.
 * You have to find the minimum path of length k in the grid. You can start
 * from any cell, and in each step you can move to any of the neighbor cells,
 * in other words, you can go to cells which share an edge with you current
 * cell.
 * Please note that a path of length k means visiting exactly k cells (not
 * necessarily distinct).
 * You CANNOT go off the grid.
 * A path A (of length k) is considered less than a path B (of length k) if
 * after making the ordered lists of the values on the cells that A and B go
 * through (let's call them lst_A and lst_B), lst_A is lexicographically less
 * than lst_B, in other words, there exist an integer index i (1 <= i <= k)
 * such that lst_A[i] < lst_B[i] and for any j (1 <= j < i) we have
 * lst_A[j] = lst_B[j].
 * It is guaranteed that the answer is unique.
 * Return an ordered list of the values on the cells that the minimum path go through.
 * Examples:
 * >>> minPath [[1; 2; 3]; [4; 5; 6]; [7; 8; 9]] 3
 * [1; 2; 1]
 * >>> minPath [[5; 9; 3]; [4; 1; 6]; [7; 8; 2]] 1
 * [1]
*)
let minPath (grid : int list list) (k : int) : int list =


Prompt:
(**Everyone knows Fibonacci sequence, it was studied deeply by mathematicians in
 * the last couple centuries. However, what people don't know is Tribonacci sequence.
 * Tribonacci sequence is defined by the recurrence:
 * tri(1) = 3
 * tri(n) = 1 + n / 2, if n is even.
 * tri(n) =  tri(n - 1) + tri(n - 2) + tri(n + 1), if n is odd.
 * For example:
 * tri(2) = 1 + (2 / 2) = 2
 * tri(4) = 3
 * tri(3) = tri(2) + tri(1) + tri(4)
 * = 2 + 3 + 3 = 8
 * You are given a non-negative integer number n, you have to a return a list of the
 * first n + 1 numbers of the Tribonacci sequence.
 * Examples:
 * >>> tri 3
 * [1; 3; 2; 8]
*)
let tri (n : int) : int list =


Prompt:
(**Given a positive integer n, return the product of the odd digits.
 * Return 0 if all digits are even.
 * For example:
 * >>> digits 1
 * 1
 * >>> digits 4
 * 0
 * >>> digits 235
 * 15
*)
let digits (n : int) : int =

let assertions =
 let candidate = digits in
  (assert ((candidate 5) = 5));
  (assert ((candidate 54) = 5));
  (assert ((candidate 120) = 1));
  (assert ((candidate 5014) = 5));
  (assert ((candidate 98765) = 315));
  (assert ((candidate 5576543) = 2625));
  (assert ((candidate 2468) = 0));
  ()


Prompt:
(**Create a function that takes a string as input which contains only square brackets.
 * The function should return true if and only if there is a valid subsequence of brackets
 * where at least one bracket in the subsequence is nested.
 * >>> is_nested "[[]]"
 * true
 * >>> is_nested "[]]]]]]][[[[[]"
 * false
 * >>> is_nested "[][]"
 * false
 * >>> is_nested "[]"
 * false
 * >>> is_nested "[[][]]"
 * true
 * >>> is_nested "[[]][["
 * true
*)
let is_nested (string : string) : bool =

let assertions =
 let candidate = is_nested in
  (assert ((candidate "[[]]") = true));
  (assert ((candidate "[]]]]]]][[[[[]") = false));
  (assert ((candidate "[][]") = false));
  (assert ((candidate "[]") = false));
  (assert ((candidate "[[[[]]]]") = true));
  (assert ((candidate "[]]]]]]]]]]") = false));
  (assert ((candidate "[][][[]]") = true));
  (assert ((candidate "[[]") = false));
  (assert ((candidate "[]]") = false));
  (assert ((candidate "[[]][[") = true));
  (assert ((candidate "[[][]]") = true));
  (assert ((candidate "") = false));
  (assert ((candidate "[[[[[[[[") = false));
  (assert ((candidate "]]]]]]]]") = false));
  ()


Prompt:
(**You are given a list of numbers.
 * You need to return the sum of squared numbers in the given list,
 * round each element in the list to the upper int(Ceiling) first.
 * Examples:
 * >>> lst [1.0; 2.0; 3.0]
 * 14
 * >>> lst [1.0; 4.0; 9.0]
 * 98
 * >>> lst [1.0; 3.0; 5.0; 7.0]
 * 84
 * >>> lst [1.4; 4.2; 0.0]
 * 29
 * >>> lst [-2.4; 1.0; 1.0]
 * 6
*)
let sum_squares (lst : float list) : int =


Prompt:
(**Create a function that returns true if the last character
 * of a given string is an alphabetical character and is not
 * a part of a word, and false otherwise.
 * Note: "word" is a group of characters separated by space.
 * Examples:
 * >>> check_if_last_char_is_a_letter "apple pie"
 * false
 * >>> check_if_last_char_is_a_letter "apple pi e"
 * true
 * >>> check_if_last_char_is_a_letter "apple pi e "
 * false
 * >>> check_if_last_char_is_a_letter ""
 * false
*)
let check_if_last_char_is_a_letter (txt : string) : bool =

let assertions =
 let candidate = check_if_last_char_is_a_letter in
  (assert ((candidate "apple") = false));
  (assert ((candidate "apple pi e") = true));
  (assert ((candidate "eeeee") = false));
  (assert ((candidate "A") = true));
  (assert ((candidate "Pumpkin pie ") = false));
  (assert ((candidate "Pumpkin pie 1") = false));
  (assert ((candidate "") = false));
  (assert ((candidate "eeeee e ") = false));
  (assert ((candidate "apple pie") = false));
  (assert ((candidate "apple pi e ") = false));
  ()


Prompt:
(**Create a function which returns the largest index of an element which
 * is not greater than or equal to the element immediately preceding it. If
 * no such element exists then return -1. The given list will not contain
 * duplicate values.
 * Examples:
 * >>> can_arrange [1; 2; 4; 3; 5]
 * 3
 * >>> can_arrange [1; 2; 3]
 * (~1)
*)
let can_arrange (arr : int list) : int =

let assertions =
 let candidate = can_arrange in
  (assert ((candidate [1; 2; 4; 3; 5]) = 3));
  (assert ((candidate [1; 2; 4; 5]) = (~1)));
  (assert ((candidate [1; 4; 2; 5; 6; 7; 8; 9; 10]) = 2));
  (assert ((candidate [4; 8; 5; 7; 3]) = 4));
  (assert ((candidate []) = (~1)));
  ()


Prompt:
(**Evaluate whether the given number n can be written as the sum of exactly 4 positive even numbers
 * Example
 * >>> is_equal_to_sum_even 4
 * false
 * >>> is_equal_to_sum_even 6
 * false
 * >>> is_equal_to_sum_even 8
 * true
*)
let is_equal_to_sum_even (n : int) : bool =

let assertions =
 let candidate = is_equal_to_sum_even in
  (assert ((candidate 4) = false));
  (assert ((candidate 6) = false));
  (assert ((candidate 8) = true));
  (assert ((candidate 10) = true));
  (assert ((candidate 11) = false));
  (assert ((candidate 12) = true));
  (assert ((candidate 13) = false));
  (assert ((candidate 16) = true));
  ()


Prompt:
(**The Brazilian factorial is defined as:
 * brazilian_factorial(n) = n! * (n-1)! * (n-2)! * ... * 1!
 * where n > 0
 * For example:
 * >>> special_factorial 4
 * 288
 * The function will receive an integer as input and should return the special
 * factorial of this integer.
*)
let special_factorial (n : int) : int =

let assertions =
 let candidate = special_factorial in
  (assert ((candidate 4) = 288));
  (assert ((candidate 5) = 34560));
  (assert ((candidate 7) = 125411328000));
  (assert ((candidate 1) = 1));
  ()


Prompt:
(**Given a string text, replace all spaces in it with underscores,
 * and if a string has more than 2 consecutive spaces,
 * then replace all consecutive spaces with -
 * >>> fix_spaces " Example"
 * "Example"
 * >>> fix_spaces " Example 1"
 * "Example_1"
 * >>> fix_spaces " Example 2"
 * "_Example_2"
 * >>> fix_spaces " Example 3"
 * "_Example-3"
*)
let fix_spaces (text : string) : string =

let assertions =
 let candidate = fix_spaces in
  (assert ((candidate "Example") = "Example"));
  (assert ((candidate "Mudasir Hanif ") = "Mudasir_Hanif_"));
  (assert ((candidate "Yellow Yellow  Dirty  Fellow") = "Yellow_Yellow__Dirty__Fellow"));
  (assert ((candidate "Exa   mple") = "Exa-mple"));
  (assert ((candidate "   Exa 1 2 2 mple") = "-Exa_1_2_2_mple"));
  ()


Prompt:
(**Create a function which takes a string representing a file's name, and returns
 * 'Yes' if the the file's name is valid, and returns 'No' otherwise.
 * A file's name is considered to be valid if and only if all the following conditions
 * are met:
 * - There should not be more than three digits ('0'-'9') in the file's name.
 * - The file's name contains exactly one dot '.'
 * - The substring before the dot should not be empty, and it starts with a letter from
 * the latin alphapet ('a'-'z' and 'A'-'Z').
 * - The substring after the dot should be one of these: ['txt', 'exe', 'dll']
 * Examples:
 * >>> file_name_check "example.txt"
 * "Yes"
 * >>> file_name_check "1example.dll"
 * "No"
*)
let file_name_check (file_name : string) : string =

let assertions =
 let candidate = file_name_check in
  (assert ((candidate "example.txt") = "Yes"));
  (assert ((candidate "1example.dll") = "No"));
  (assert ((candidate "s1sdf3.asd") = "No"));
  (assert ((candidate "K.dll") = "Yes"));
  (assert ((candidate "MY16FILE3.exe") = "Yes"));
  (assert ((candidate "His12FILE94.exe") = "No"));
  (assert ((candidate "_Y.txt") = "No"));
  (assert ((candidate "?aREYA.exe") = "No"));
  (assert ((candidate "/this_is_valid.dll") = "No"));
  (assert ((candidate "this_is_valid.wow") = "No"));
  (assert ((candidate "this_is_valid.txt") = "Yes"));
  (assert ((candidate "this_is_valid.txtexe") = "No"));
  (assert ((candidate "#this2_i4s_5valid.ten") = "No"));
  (assert ((candidate "@this1_is6_valid.exe") = "No"));
  (assert ((candidate "this_is_12valid.6exe4.txt") = "No"));
  (assert ((candidate "all.exe.txt") = "No"));
  (assert ((candidate "I563_No.exe") = "Yes"));
  (assert ((candidate "Is3youfault.txt") = "Yes"));
  (assert ((candidate "no_one#knows.dll") = "Yes"));
  (assert ((candidate "1I563_Yes3.exe") = "No"));
  (assert ((candidate "I563_Yes3.txtt") = "No"));
  (assert ((candidate "final..txt") = "No"));
  (assert ((candidate "final132") = "No"));
  (assert ((candidate "_f4indsartal132.") = "No"));
  (assert ((candidate ".txt") = "No"));
  (assert ((candidate "s.") = "No"));
  ()


Prompt:
(**"
 * This function will take a list of integers. For all entries in the list, the function shall square the integer entry if its index is a
 * multiple of 3 and will cube the integer entry if its index is a multiple of 4 and not a multiple of 3. The function will not
 * change the entries in the list whose indexes are not a multiple of 3 or 4. The function shall then return the sum of all entries.
 * Examples:
 * >>> lst
 * [1; 2; 3]
 * >>> lst
 * []
 * >>> lst
 * [(~1); (~5); 2; (~1); (~5)]
*)
let sum_squares (lst : int list) : int =


Prompt:
(**You are given a string representing a sentence,
 * the sentence contains some words separated by a space,
 * and you have to return a string that contains the words from the original sentence,
 * whose lengths are prime numbers,
 * the order of the words in the new string should be the same as the original one.
 * Example 1:
 * >>> words_in_sentence "This is a test"
 * "is"
 * Example 2:
 * >>> words_in_sentence "lets go for swimming"
 * "go for"
 * Constraints:
 * * 1 <= len(sentence) <= 100
 * * sentence contains only letters
*)
let words_in_sentence (sentence : string) : string =

let assertions =
 let candidate = words_in_sentence in
  (assert ((candidate "This is a test") = "is"));
  (assert ((candidate "lets go for swimming") = "go for"));
  (assert ((candidate "there is no place available here") = "there is no place"));
  (assert ((candidate "Hi I am Hussein") = "Hi am Hussein"));
  (assert ((candidate "go for it") = "go for it"));
  (assert ((candidate "here") = ""));
  (assert ((candidate "here is") = "is"));
  ()


Prompt:
(**Your task is to implement a function that will simplify the expression
 * x * n. The function returns true if x * n evaluates to a whole number and false
 * otherwise. Both x and n, are string representation of a fraction, and have the following format,
 * <numerator>/<denominator> where both numerator and denominator are positive whole numbers.
 * You can assume that x, and n are valid fractions, and do not have zero as denominator.
 * >>> simplify "1/5" "5/1"
 * true
 * >>> simplify "1/6" "2/1"
 * false
 * >>> simplify "7/10" "10/2"
 * false
*)
let simplify (x : string) (n : string) : bool =

let assertions =
 let candidate = simplify in
  (assert ((candidate "1/5" "5/1") = true));
  (assert ((candidate "1/6" "2/1") = false));
  (assert ((candidate "5/1" "3/1") = true));
  (assert ((candidate "7/10" "10/2") = false));
  (assert ((candidate "2/10" "50/10") = true));
  (assert ((candidate "7/2" "4/2") = true));
  (assert ((candidate "11/6" "6/1") = true));
  (assert ((candidate "2/3" "5/2") = false));
  (assert ((candidate "5/2" "3/5") = false));
  (assert ((candidate "2/4" "8/4") = true));
  (assert ((candidate "2/4" "4/2") = true));
  (assert ((candidate "1/5" "5/1") = true));
  (assert ((candidate "1/5" "1/5") = false));
  ()


Prompt:
(**Write a function which sorts the given list of integers
 * in ascending order according to the sum of their digits.
 * Note: if there are several items with similar sum of their digits,
 * order them based on their index in original list.
 * For example:
 * >>> order_by_points [1; 11; (~1); (~11); (~12)]
 * [(~1); (~11); 1; (~12); 11]
 * >>> order_by_points []
 * []
*)
let order_by_points (nums : int list) : int list =


Prompt:
(**Write a function that takes a list of numbers as input and returns
 * the number of elements in the list that are greater than 10 and both
 * first and last digits of a number are odd (1, 3, 5, 7, 9).
 * For example:
 * >>> specialFilter [15; (~73); 14; (~15)]
 * 1
 * >>> specialFilter [33; (~2); (~3); 45; 21; 109]
 * 2
*)
let specialFilter (nums : int list) : int =


Prompt:
(**You are given a positive integer n. You have to create an integer list a of length n.
 * For each i (1 ≤ i ≤ n), the value of a[i] = i * i - i + 1.
 * Return the number of triples (a[i], a[j], a[k]) of a where i < j < k,
 * and a[i] + a[j] + a[k] is a multiple of 3.
 * Example :
 * >>> get_max_triples 5
 * 1
 * Explanation:
 * a = [1, 3, 7, 13, 21]
 * The only valid triple is (1, 7, 13).
*)
let get_max_triples (n : int) : int =

let assertions =
 let candidate = get_max_triples in
  (assert ((candidate 5) = 1));
  (assert ((candidate 6) = 4));
  (assert ((candidate 10) = 36));
  (assert ((candidate 100) = 53361));
  ()


Prompt:
(**Write a function that accepts a list of strings as a parameter,
 * deletes the strings that have odd lengths from it,
 * and returns the resulted list with a sorted order,
 * The list is always a list of strings and never a list of numbers,
 * and it may contain duplicates.
 * The order of the list should be ascending by length of each word, and you
 * should return the list sorted by that rule.
 * If two words have the same length, sort the list alphabetically.
 * The function should return a list of strings in sorted order.
 * You may assume that all words will have the same length.
 * For example:
 * >>> list_sort ["aa"; "a"; "aaa"]
 * ["aa"]
 * >>> list_sort ["ab"; "a"; "aaa"; "cd"]
 * ["ab"; "cd"]
*)
let sorted_list_sum (lst : string list) : string list =

let assertions =
 let candidate = sorted_list_sum in
  (assert ((candidate ["aa"; "a"; "aaa"]) = ["aa"]));
  (assert ((candidate ["school"; "AI"; "asdf"; "b"]) = ["AI"; "asdf"; "school"]));
  (assert ((candidate ["d"; "b"; "c"; "a"]) = []));
  (assert ((candidate ["d"; "dcba"; "abcd"; "a"]) = ["abcd"; "dcba"]));
  (assert ((candidate ["AI"; "ai"; "au"]) = ["AI"; "ai"; "au"]));
  (assert ((candidate ["a"; "b"; "b"; "c"; "c"; "a"]) = []));
  (assert ((candidate ["aaaa"; "bbbb"; "dd"; "cc"]) = ["cc"; "dd"; "aaaa"; "bbbb"]));
  ()


Prompt:
(**A simple program which should return the value of x if n is
 * a prime number and should return the value of y otherwise.
 * Examples:
 * >>> x_or_y 7 34 12
 * 34
 * >>> x_or_y 15 8 5
 * 5
*)
let x_or_y (n : int) (x : int) (y : int) : int =

let assertions =
 let candidate = x_or_y in
  (assert ((candidate 7 34 12) = 34));
  (assert ((candidate 15 8 5) = 5));
  (assert ((candidate 3 33 5212) = 33));
  (assert ((candidate 1259 3 52) = 3));
  (assert ((candidate 7919 (~1) 12) = (~1)));
  (assert ((candidate 3609 1245 583) = 583));
  (assert ((candidate 91 56 129) = 129));
  (assert ((candidate 6 34 1234) = 1234));
  (assert ((candidate 1 2 0) = 0));
  (assert ((candidate 2 2 0) = 2));
  ()


Prompt:
(**Given a list of numbers, return the sum of squares of the numbers
 * in the list that are odd. Ignore numbers that are negative or not integers.
 * >>> double_the_difference [1; 3; 2; 0]
 * 10
 * >>> double_the_difference [(~1); (~2); 0]
 * 0
 * >>> double_the_difference [9; (~2)]
 * 81
 * >>> double_the_difference [0]
 * 0
 * If the input list is empty, return 0.
*)
let double_the_difference (lst : float list) : int =


Prompt:
(**I think we all remember that feeling when the result of some long-awaited
 * event is finally known. The feelings and thoughts you have at that moment are
 * definitely worth noting down and comparing.
 * Your task is to determine if a person correctly guessed the results of a number of matches.
 * You are given two lists of scores and guesses of equal length, where each index shows a match.
 * Return a list of the same length denoting how far off each guess was. If they have guessed correctly,
 * the value is 0, and if not, the value is the absolute difference between the guess and the score.
 * example:
 * >>> compare [1; 2; 3; 4; 5; 1] [1; 2; 3; 4; 2; (~2)]
 * [0; 0; 0; 0; 3; 3]
 * >>> compare [0; 5; 0; 0; 0; 4] [4; 1; 1; 0; 0; (~2)]
 * [4; 4; 1; 0; 0; 6]
*)
let compare (game : int list) (guess : int list) : int list =