OCaml Madlib
open Printf;; open Random;; (* Add the contents of the line as a new set of substitutions to the wordlist, and return the new list. *) let update_wordlist line wordlist = wordlist @ [ List.filter (fun s -> not (s = "")) (String.split_on_char ' ' line) ];; (* Return the next position in the string which is not a digit, if any, or the length, if none. *) let rec next_non_digit str pos = if (String.length str) <= pos || str.[pos] < '0' || str.[pos] > '9' then pos else next_non_digit str (pos + 1);; (* Take the word list and the index, and choose a random string. If the index is out of range, return "[error]". Also, paranoia check for the the chosen list to be empty, in which case the empty string is returned. *) let find_sub wordlist index = if (List.length wordlist) <= index then "[error]" else let chosen_list = List.nth wordlist index in if (List.length chosen_list) <= 0 then "" else List.nth chosen_list (Random.int (List.length chosen_list)) (* Copy the string with substitutions. *) let rec process_text_line wordlist line = (* Find the first hash mark denoting the substitution. *) let numpos = try String.index line '#' with _ -> -1 in (* If there's no hash mark, just return the string. *) if numpos = -1 then line else (* Isolate the part of the string before the #, the part after the hash, and the digits making up the list number. *) let prepart = String.sub line 0 numpos in let firstkeep = next_non_digit line (numpos + 1) in let indexpart = String.sub line (numpos + 1) (firstkeep - numpos - 1) in let postpart = String.sub line firstkeep ((String.length line) - firstkeep) in (* The result is the part before the #, the substitution provided by find_sub, then the part after the #NNN, after passing back through process_text_line to handle any additional substitutions. If the index string is empty, use empty string for the substitution. *) prepart ^ (if indexpart = "" then "" else (find_sub wordlist (int_of_string indexpart))) ^ (process_text_line wordlist postpart);; (* Read the wordlist section and update and return the wordlist. *) let rec read_wordlist stream wordlist = let line = input_line stream in if line = "-" then wordlist else read_wordlist stream (update_wordlist line wordlist);; (* Take a line and a stream, read the stream and process the instruction against the line, and return the new line. *) let rec copy_with_sub stream wordlist = try printf "%s\n" (process_text_line wordlist (input_line stream)); copy_with_sub stream wordlist with _ -> ();; (* Process the input. *) let process_input stream = copy_with_sub stream (read_wordlist stream [ ] );; (* Start it up. *) Random.self_init (); process_input stdin;;