Skip to content

Instantly share code, notes, and snippets.

@blakemerryman
Created December 22, 2014 19:40
Show Gist options
  • Save blakemerryman/a45416b6d751fa5b9f68 to your computer and use it in GitHub Desktop.
Save blakemerryman/a45416b6d751fa5b9f68 to your computer and use it in GitHub Desktop.
DailyProgrammer-Challenge193_ContainerDimensions
#!/usr/bin/env xcrun swift
/*
/r/DailyProgrammer Challenge # 193
Reddit - http://www.reddit.com/r/dailyprogrammer/
Blake Merryman
Github - https://github.com/blakemerryman
Challenge Description:
An international shipping company is trying to figure out how to manufacture various types of containers. Given a volume they want to figure out the dimensions of various shapes that would all hold the same volume.
Input:
* A volume in cubic meters.
Output:
* Dimensions of containers of various types that would hold the volume.
* The following containers are possible.
* Cube
* Ball (Sphere)
* Cylinder
* Cone
Ex:
Input:
> 27.0
Output:
> Cube: 3.00m width, 3.00m high, 3.00m tall
Cylinder: 3.00m tall, Diameter of 3.38m
Sphere: 1.86m Radius
Cone: 9.00m tall, 1.69m Radius
Notes:
* Input can be an integer or double value
* To run,
1. Make executable (chmod +x filename.swift)
2. Run by entering the following into the console:
> ./filename.swift ###
or
> ./filename.swift ###.##
*/
import Cocoa
// MARK: - Handle User Input
var volume = 0.0
// Grab input from console
for argument in Process.arguments {
let argumentAsDouble = (argument as NSString).doubleValue
if argumentAsDouble > 0.0 {
volume = argumentAsDouble
}
}
// MARK: - Important Constants & Enums
let kDimensionUnits = "m"
let kDimensionHeight = "height"
let kDimensionWidth = "width"
let kDimensionDepth = "depth"
let kDimensionRadius = "radius"
enum ContainerShape: String {
case Cube = "Cube"
case Sphere = "Sphere"
case Cylinder = "Cylinder"
case Cone = "Cone"
}
// MARK: - NumberFormatter
var numberFormatter = NSNumberFormatter()
numberFormatter.maximumSignificantDigits = {
var numberOfSigDigs = 0
for character in volume.description {
if character != "." {
numberOfSigDigs++
}
}
return numberOfSigDigs
}()
// MARK: - Utility Functions
/// Computes the height, width, & depth of a cube for a given volume.
func computeDimensionsForCubeWithVolume(volume: Double) -> [String:Double] {
let aSide = cbrt(volume)
return [kDimensionHeight:aSide, kDimensionWidth: aSide, kDimensionDepth: aSide]
}
/// Computes the radius of a sphere for a given volume.
func computeDimensionsForSphereWithVolume(volume: Double) -> [String:Double] {
let radius = cbrt( ( 3.0 * volume ) / ( 4.0 * M_PI ) )
return [kDimensionRadius:radius]
}
/// Computes the height & radius of a cylinder with minimum surface area for given volume.
func computeDimensionsForCylinderWithVolume(volume: Double) -> [String:Double] {
/*
Note on calculations:
We know the desired volume of the cylinder but not the desired dimensions.
This is an equation with two unknowns and in the Real numbers could have many
possible solutions. To narrow it down to one, we are going to use a little
calculus to minimize the surface area and thus give us the appropriate
radius & height for the given volume.
User copper.hat gives a great explanation behind getting the correct formulae
for the radius and height ( http://math.stackexchange.com/a/584770 ).
*/
let radius = cbrt(volume / (2 * M_PI))
let height = cbrt((4 * volume) / M_PI)
return [kDimensionRadius:radius,kDimensionHeight:height]
}
/// Computes the height & radius of a cone with a slant angle of 45º for given volume.
func computeDimensionsForConeWithVolume(volume: Double) -> [String:Double] {
/*
Note on calculations:
We know the desired volume of the cone but not the desired dimensions.
This is an equation with two unknowns and in the Real numbers could have many
possible solutions. To narrow it down to one, we are going to assume that
height and radius are equal, giving us a slant angle of 45º.
We could make any number of assumptions (desired slant angle, maximum height,
maximum radius, etc) but this one was chosen for simplicity.
V = ( h * pi * r^2 ) / 3 ... but h = r so
= ( pi * r^3 ) / 3 ... and solving for r gives us...
*/
let radius = cbrt((3 * volume) / M_PI)
return [kDimensionRadius:radius,kDimensionHeight:radius]
}
// Given a set of dimensions & shape, properly formats the string for output.
func formatDimensions(dimensions: [String:Double], forShape shape: ContainerShape) -> String {
switch shape {
case .Cube:
let height = numberFormatter.stringFromNumber(dimensions[kDimensionHeight]!)!
let width = numberFormatter.stringFromNumber(dimensions[kDimensionWidth]!)!
let depth = numberFormatter.stringFromNumber(dimensions[kDimensionDepth]!)!
return "\(shape.rawValue): \(height) \(kDimensionUnits) \(kDimensionHeight), \(width) \(kDimensionUnits) \(kDimensionWidth), \(depth) \(kDimensionUnits) \(kDimensionDepth)"
case .Cone, .Cylinder:
let radius = numberFormatter.stringFromNumber(dimensions[kDimensionRadius]!)!
let height = numberFormatter.stringFromNumber(dimensions[kDimensionHeight]!)!
return "\(shape.rawValue): \(radius) \(kDimensionUnits) \(kDimensionRadius),\(height) \(kDimensionUnits) \(kDimensionHeight)"
case .Sphere:
let radius = numberFormatter.stringFromNumber(dimensions[kDimensionRadius]!)!
return "\(shape.rawValue): \(radius) \(kDimensionUnits) \(kDimensionRadius)"
}
}
// MARK: - Primary Function
/// Function computes possible dimensions for the passed in shape & volume. Computed values are returned in a dictionary.
func computeDimensions(forShape shape: ContainerShape, withVolume volume: Double) -> String {
switch shape {
case .Cube:
return formatDimensions(computeDimensionsForCubeWithVolume(volume), forShape: .Cube)
case .Cone:
return formatDimensions(computeDimensionsForConeWithVolume(volume), forShape: .Cone)
case .Cylinder:
return formatDimensions(computeDimensionsForCylinderWithVolume(volume), forShape: .Cylinder)
case .Sphere:
return formatDimensions(computeDimensionsForSphereWithVolume(volume), forShape: .Sphere)
}
}
// --------------------------------------------------
// MARK: - Comput & Output to User
println("\n\nContainer Dimensions for a given volume of \(volume) \(kDimensionUnits)^3")
println("----------------------------------------------------------")
println("\(computeDimensions(forShape: .Cube, withVolume: volume))")
println("\(computeDimensions(forShape: .Cone, withVolume: volume))")
println("\(computeDimensions(forShape: .Cylinder, withVolume: volume))")
println("\(computeDimensions(forShape: .Sphere, withVolume: volume))")
println("----------------------------------------------------------\n\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment