[Shootout-list] Working Ocaml dispatch
Brian Hurt
bhurt at spnz.org
Tue Aug 23 01:39:41 UTC 2005
Found my bug. Rather surprisingly, the last five pressurized bottles have
their checksums subtracted and not added. Which, I comment, makes it
impossible to use folds.
I assume that you need to keep open the option of doing something
interesting when filling, sealing, pressurizing, or emptying bottles.
Instead of using objects and virtual functions to do this, I took the more
interesting route of using modules and functors. I'm not sure if this is
an advantage or not.
I comment that this version is not optimized for much of anything.
Brian
-------------- next part --------------
module type IBottle = sig
type bottleState
val init : int -> bottleState
val check : int -> bottleState -> int
val next : bottleState -> bottleState
val cycle : bottleState -> bottleState
end;;
module type PressurizedActions = sig
type t
val init : int -> t
val fill : t -> t
val pressurize : t -> t
val seal : t -> t
val empty : t -> t
val check : t -> int
end;;
module PressurizedBottle(PA: PressurizedActions) = struct
type bottleState =
| UnpressurizedEmpty of PA.t
| UnpressurizedFull of PA.t
| PressurizedUnsealed of PA.t
| PressurizedSealed of PA.t
let init i = UnpressurizedEmpty (PA.init i)
let check c = function
| UnpressurizedEmpty(x) -> c + 4 + (PA.check x)
| UnpressurizedFull(x) -> c + 5 + (PA.check x)
| PressurizedUnsealed(x) -> c + 6 + (PA.check x)
| PressurizedSealed(x) -> c + 7 + (PA.check x)
let next = function
| UnpressurizedEmpty(x) -> UnpressurizedFull(PA.fill x)
| UnpressurizedFull(x) -> PressurizedUnsealed(PA.pressurize x)
| PressurizedUnsealed(x) -> PressurizedSealed(PA.seal x)
| PressurizedSealed(x) -> UnpressurizedEmpty(PA.empty x)
let cycle state =
let state = next state in
let state = next state in
let state = next state in
next state
end;;
module type BottleActions = sig
type t
val init : int -> t
val fill : t -> t
val seal : t -> t
val empty : t -> t
val check : t -> int
end;;
module Bottle(BA: BottleActions) = struct
type bottleState =
| Empty of BA.t
| Full of BA.t
| Sealed of BA.t
let init i = Empty (BA.init i)
let check c = function
| Empty(x) -> c + 1 + (BA.check x)
| Full(x) -> c + 2 + (BA.check x)
| Sealed(x) -> c + 3 + (BA.check x)
let next = function
| Empty(x) -> Full(BA.fill x)
| Full(x) -> Sealed(BA.seal x)
| Sealed(x) -> Empty(BA.empty x)
let cycle state =
let state = next state in
let state = next state in
next state
end;;
module DefaultActions = struct
type t = int
let init i = (i + 1)
let fill x = x
let pressurize x = x
let seal x = x
let empty x = x
let check x = x
end;;
module DefaultPressurizedBottle = PressurizedBottle(DefaultActions);;
module DefaultBottle = Bottle(DefaultActions);;
let _ =
let n =
if (Array.length Sys.argv) > 1 then
int_of_string Sys.argv.(1)
else
1
in
let ba = Array.init 10 DefaultBottle.init
and pa = Array.init 10 DefaultPressurizedBottle.init
in
let rec loop i sum =
if i == 0 then
sum
else
begin
for j = 0 to 9 do
ba.(j) <- DefaultBottle.cycle ba.(j)
done;
for j = 0 to 9 do
pa.(j) <- DefaultPressurizedBottle.cycle pa.(j)
done;
let c = i mod 2 in
let check f b1 b2 b3 b4 b5 c =
(f c b1) + (f c b2) + (f c b3) + (f c b4) + (f c b5) in
let sum = sum +
(check DefaultBottle.check
ba.(0) ba.(1) ba.(2) ba.(3) ba.(4) c) +
(check DefaultBottle.check
ba.(5) ba.(6) ba.(7) ba.(8) ba.(9) c) +
(check DefaultPressurizedBottle.check
pa.(0) pa.(1) pa.(2) pa.(3) pa.(4) c) -
(check DefaultPressurizedBottle.check
pa.(5) pa.(6) pa.(7) pa.(8) pa.(9) c)
in
loop (i-1) sum
end
in
Printf.printf "%d\n" (loop n 0)
;;
More information about the Shootout-list
mailing list