How to resolve the algorithm 99 bottles of beer step by step in the OCaml programming language

Published on 12 May 2024 09:40 PM

How to resolve the algorithm 99 bottles of beer step by step in the OCaml programming language

Table of Contents

Problem Statement

Display the complete lyrics for the song:     99 Bottles of Beer on the Wall.

The lyrics follow this form: ... and so on, until reaching   0     (zero). Grammatical support for   1 bottle of beer   is optional. As with any puzzle, try to do it in as creative/concise/comical a way as possible (simple, obvious solutions allowed, too).

Let's start with the solution:

Step by Step solution about How to resolve the algorithm 99 bottles of beer step by step in the OCaml programming language

Source code in the ocaml programming language

for n = 99 downto 1 do
  Printf.printf "%d bottles of beer on the wall\n" n;
  Printf.printf "%d bottles of beer\n" n;
  Printf.printf "Take one down, pass it around\n";
  Printf.printf "%d bottles of beer on the wall\n\n" (pred n);
done

let verse n = 
    let 
        line2 = function
            | 0 -> "No more bottles of beer"
            | 1 -> "1 bottle of beer"
            | n -> string_of_int n ^ " bottles of beer" 
    in
        let 
            line1or4 y = line2 y ^ " on the wall" 
        in
            let 
                line3 = function
                | 1 -> "Take it down, pass it around"
                | _ -> "Take one down, pass it around" 
            in
                line1or4 n ^ "\n" ^ 
                line2 n ^ "\n" ^
                line3 n ^ "\n" ^
                line1or4 (n-1) ^ "\n";;

let rec beer n =
    print_endline (verse n);
    if n > 1 then beer (n-1);;

beer 99;;

(* A basic "Writer" monoid with emit *)
module Writer = struct
  type 'a t = 'a * string
  let ( >>= ) (x,s) f = let (y,s') = f x in (y, s ^ s')
  let return x = (x,"")
  let emit (x,s) = print_string s; x
end

(* Utility functions for handling strings and grammar *)
let line s    = (String.capitalize s) ^ ".\n"
let count     = function 0 -> "no more" | n -> string_of_int n
let plural    = function 1 -> "" | _ -> "s"
let specify   = function 1 -> "it" | _ -> "one"
let bottles n = count n ^ " bottle" ^ plural n ^ " of beer"

(* Actions, expressed as an int * string, for Writer *)
let report n  = (n, line (bottles n ^ " on the wall, " ^ bottles n))
let take n    = (n-1, "Take " ^ specify n ^ " down and pass it around")
let summary n = (n, ", " ^ bottles n ^ " on the wall.\n\n")
let shop      = (99, "Go to the store and buy some more")

let rec verse state =
  Writer.(state >>= report >>= function 0 -> shop >>= summary (* ends here *)
                                      | n -> take n >>= summary |> verse)
let sing start =
  Writer.(emit (verse (return start)))

# sing 2;;
2 bottles of beer on the wall, 2 bottles of beer.
Take one down and pass it around, 1 bottle of beer on the wall.

1 bottle of beer on the wall, 1 bottle of beer.
Take it down and pass it around, no more bottles of beer on the wall.

No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.

- : int = 99

  

You may also check:How to resolve the algorithm Matrix-exponentiation operator step by step in the J programming language
You may also check:How to resolve the algorithm Literals/String step by step in the Rust programming language
You may also check:How to resolve the algorithm Last Friday of each month step by step in the Fōrmulæ programming language
You may also check:How to resolve the algorithm Time a function step by step in the BASIC256 programming language
You may also check:How to resolve the algorithm Forward difference step by step in the Swift programming language