Skip to content

Instantly share code, notes, and snippets.

@shapr
Created July 10, 2019 06:07
Show Gist options
  • Save shapr/1e128e681ef7e554538ef94b98cb7a2d to your computer and use it in GitHub Desktop.
Save shapr/1e128e681ef7e554538ef94b98cb7a2d to your computer and use it in GitHub Desktop.
{-# LANGUAGE TypeApplications #-}
module Main where
import Data.SBV
main = do
res <- optimize Lexicographic configure
print res
configure :: Goal
configure = do
engineNames <- sIntegers $ getName <$> engines
let engineCost = costAmount engineNames
thrust = thrustAmount' engineNames -- round down floats
turn = turnAmount' engineNames -- round down floats
constrain $ engineCost .<= 210 -- Kestrel + Weapons
constrain $ engineCost .>= 0 -- can't be negative!
mapM_ (\x -> constrain $ x .>= 0) engineNames -- zero or more of each component
mapM_ (\x -> constrain $ x .<= 10) engineNames -- I can't imagine more than ten of any component?
maximize "sum thrust and steering/26" ((thrust * 26) + turn :: SInteger)
-- maximize "thrust" thrust
-- maximize "turn" turn
costAmount :: [SInteger] -> SInteger
costAmount es = sum $ zipWith (*) (getSize <$> engines) es
turnAmount :: [SInteger] -> SFloat
turnAmount es = sum $ zipWith (*) (getTurn <$> engines) (toSFloat sRTP <$> es) -- sbv won't multiply SInteger times SFloat, so convert SInteger to SFloat?
turnAmount' :: [SInteger] -> SInteger
turnAmount' es = sum $ zipWith (*) ((fromSFloat sRTZ) . getTurn <$> engines) es -- sbv won't multiply SInteger times SFloat, so convert SFloat to SInteger?
thrustAmount :: [SInteger] -> SFloat
thrustAmount es = sum $ zipWith (*) (getThrust <$> engines) (toSFloat sRTP <$> es) -- sbv won't multiply SInteger times SFloat, so convert SInteger to SFloat?
thrustAmount' :: [SInteger] -> SInteger
thrustAmount' es = sum $ zipWith (*) ((fromSFloat sRTZ) . getThrust <$> engines) es -- sbv won't multiply SInteger times SFloat, so convert SFloat to SInteger?
getName (n,_,_,_) = n
getSize (_,s,_,_) = s
getThrust (_,_,th,_) = th
getTurn (_,_,_,tu) = tu
{- many engines, with different amounts of thrust and turning
a ship has limited space
What combination of engines fits into the ship, and gives the most thrust? -}
-- values from https://github.com/endless-sky/endless-sky/blob/master/data/engines.txt
-- name, size, thrust, turning
engines :: [(String, SInteger, SFloat, SFloat)]
engines = [ ("X1050", 20, 4.0, 110) -- has both thrust and turning!
, ("X1200", 12, 0, 160)
, ("X1700", 16, 6.0, 0)
, ("X2200", 20, 0, 307)
, ("X2700", 27, 11.5, 0)
, ("X3200", 35, 0, 590)
, ("X3700", 46, 22.1, 0)
, ("X4200", 59, 0, 1132)
, ("X4700", 79, 42.5, 0)
, ("X5200", 100, 0, 2174)
, ("X5700", 134, 81.5, 0)
, ("Chipmunk Thruster", 20, 9.6, 0)
, ("Chipmunk Steering", 15, 0, 256)
, ("Greyhound Steering", 26, 0, 492)
, ("Greyhound Thruster", 34, 18.4, 0)
, ("Impala Steering", 43, 0, 944)
, ("Impala Thruster", 58, 35.4, 0)
, ("Orca Steering", 74, 0, 1812)
, ("Orca Thruster", 98, 67.9, 0)
, ("Tyrant Steering", 125, 0, 3479)
, ("Tyrant Thruster", 167, 130.5, 0)
, ("A120 Thruster", 22, 15.4, 0)
, ("A125 Steering", 16, 0, 392)
, ("A250 Thruster", 34, 27.3, 0)
, ("A255 Steering", 25, 0, 687)
, ("A370 Thruster", 53, 47.6, 0)
, ("A375 Steering", 38, 0, 1192)
, ("A520 Thruster", 82, 81.9, 0)
, ("A525 Steering", 60, 0, 2050)
, ("A860 Thruster", 127, 139.7, 0)
, ("A865 Steering", 92, 0, 3509)
, ("Baellie", 24, 10.1, 250) -- hai
, ("Basrem Thruster", 18, 13.2, 0)
, ("Benga Thruster", 28, 23.6, 0)
, ("Biroo Thruster", 44, 41.5, 0)
, ("Bondir Thruster", 63, 66.1, 0)
, ("Bufaer Thruster", 104, 120.1, 0)
, ("Basrem Steering", 12, 0, 309)
, ("Benga Steering", 20, 0, 577)
, ("Biroo Steering", 32, 0, 1054)
, ("Bondir Steering", 49, 0, 1758)
, ("Bufaer Steering", 76, 0, 3043)
, ("Coalition Large Steering", 25, 0, 711.9) -- coalition
, ("Coalition Large Thruster", 32, 26.2, 0)
, ("Coalition Small Steering", 7, 0, 178.8)
, ("Coalition Small Thruster", 9, 6.6, 0)
, ("Korath Asteroid Steering", 10, 0, 280) -- Korath
, ("Korath Asteroid Thruster", 14, 11.2, 0)
, ("Korath Comet Steering", 18, 0, 568.8)
, ("Korath Comet Thruster", 24, 21.8, 0)
, ("Korath Lunar Steering", 30, 0, 1056)
, ("Korath Lunar Thruster", 40, 41.2, 0)
, ("Korath Planetary Steering", 52, 0, 2069.6)
, ("Korath Planetary Thruster", 69, 80.0, 0)
, ("Korath Stellar Steering", 89, 0, 4005)
, ("Korath Stellar Thruster", 118, 153.4, 0)
, ("Pug Akfar Thruster", 43, 28, 0) -- pug
, ("Pug Akfar Steering", 33, 0, 750)
, ("Pug Cormet Thruster", 60, 44, 0)
, ("Pug Comet Steering", 46, 0, 1130)
, ("Pug Lohmar Thruster", 84, 66, 0)
, ("Pug Lohmar Steering", 64, 0, 1700)
, ("Quarg Medium Thruster", 70, 80, 0) -- quarg
, ("Quarg Medium Steering", 50, 0, 1600)
, ("Crucible Thruster", 20, 18, 0) -- remnant
, ("Crucible Steering", 14, 0, 448)
, ("Forge Thruster", 39, 37, 0)
, ("Forge Steering", 28, 0, 952)
, ("Smelter Thruster", 76, 76.8, 0)
, ("Smelter Steering", 55, 0, 1980)
, ("Type 1 Radiant Thruster", 12, 6.6, 0) -- wanderer
, ("Type 1 Radiant Steering", 9, 0, 172.8)
, ("Type 2 Radiant Thruster", 27, 17.6, 0)
, ("Type 2 Radiant Steering", 20, 0, 454)
, ("Type 3 Radiant Thruster", 42, 31.5, 0)
, ("Type 3 Radiant Steering", 30, 0, 786)
, ("Type 4 Radiant Thruster", 64, 55.2, 0)
, ("Type 4 Radiant Steering", 47, 0, 1395.9)
]
-- {- start with "combination of engines that gives the most thrust" -}
-- name, engine space, weapon space
ships :: [(String, SInteger, SInteger)]
ships = [ ("Dreadnought", 190, 360)
, ("Bactrian", 180, 300)
, ("Albatross", 142, 236)
, ("Weapons Kestrel", 210, 390)
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment