[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