const US_LIQUID_GALLONS_TO_CUBIC_INCHES = 231 const CUBIC_INCHES_TO_US_LIQUID_GALLONS = 1 / US_LIQUID_GALLONS_TO_CUBIC_INCHES const toLiquid = cubicInches => cubicInches * CUBIC_INCHES_TO_US_LIQUID_GALLONS const fromLiquid = gallons => gallons * US_LIQUID_GALLONS_TO_CUBIC_INCHES class Container { constructor({ l, w, h }, level = 0) { this.l = l this.w = w this.h = h this.level = level } get liquidVolumeCapacity() { return toLiquid(this.l * this.w * this.h) } get liquidVolumeFilled() { return toLiquid(this.l * this.w * this.level) } get liquidVolumeRemaining() { return this.liquidVolumeCapacity - this.liquidVolumeFilled } } /** Functional Core */ const _changeLevel = (amount, container) => { const alteredLevel = fromLiquid(container.liquidVolumeFilled + amount) / container.l / container.w return createContainer(container, alteredLevel) } const createContainer = ({ l, w, h }, level) => { if (Math.sign(l) + Math.sign(w) + Math.sign(h) !== 3) return console.error( `[Error] All dimensions must be positive and greater than zero!` ) return new Container({ l, w, h }, level) } const fill = ({ container, amount }) => _changeLevel(amount, container) const drain = ({ container, amount }) => _changeLevel(-1 * amount, container) myTank = createContainer({ l: 12, w: 12, h: 12 }) console.log('capacity:', myTank.liquidVolumeCapacity) console.log('filled:', myTank.liquidVolumeFilled) myTank = fill({ amount: myTank.liquidVolumeCapacity, container: myTank }) console.log('\nremaining liquid volume:', myTank.liquidVolumeRemaining) console.log('remain h:', myTank.h - myTank.level) myTank = drain({ amount: 4, container: myTank }) console.log('\nremaining liquid volume:', myTank.liquidVolumeRemaining) console.log('remain h:', myTank.h - myTank.level) console.log('filled:', myTank.liquidVolumeFilled) myTank = fill({ amount: 3, container: myTank }) console.log('\nremaining liquid volume:', myTank.liquidVolumeRemaining) console.log('remain h:', myTank.h - myTank.level) console.log('filled:', myTank.liquidVolumeFilled)