Skip to content

Commit 0883b2e

Browse files
committed
Optimization: split LMove-and-Wait into two SMoves (#6)
1 parent 631ad0f commit 0883b2e

6 files changed

Lines changed: 78 additions & 7 deletions

File tree

package.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ executables:
4545

4646
tests:
4747
icfpc2018-test:
48-
main: Spec.hs
48+
main: Test.hs
4949
source-dirs: test
5050
ghc-options:
5151
- -threaded

src/Optimizations.hs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-- | Optimizations for sequences of commands.
2+
--
3+
-- Each optimizations replaces first occurrence of a pattern with an optimized
4+
-- version. It's up to you to figure out if the result is better than the
5+
-- input, and if you should re-run optimizations to find new occurrences of
6+
-- patterns.
7+
module Optimizations where
8+
9+
import Trace
10+
11+
-- | Turns [LMove a b, Wait] into [SMove a, SMove b]
12+
--
13+
-- The latter consumes 4 less energy points than the former.
14+
--
15+
-- Note: it doesn't make sense to split [LMove a b] into two SMoves because the
16+
-- extra step will consume 3 R³ energy points, which is detrimental for any
17+
-- R greater than one.
18+
splitLMove :: [Command] -> [Command]
19+
splitLMove [] = []
20+
splitLMove ((LMove a b):Wait:cmds) =
21+
(SMove (fromShortLinDiff a)) : (SMove (fromShortLinDiff b)) : cmds
22+
splitLMove (cmd:cmds) = cmd : (splitLMove cmds)

src/Trace.hs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ instance Coded Command where
167167

168168
| otherwise = error "Command.decode: invalid input"
169169

170+
-- | Converts short linear difference into a long linear difference.
171+
--
172+
-- This conversion is valid since any short linear difference satisfies
173+
-- mlen(ld) ≤ 5, which also satisfies LongLinDiff's predicate of mlen(ld) ≤ 15.
174+
fromShortLinDiff :: ShortLinDiff -> LongLinDiff
175+
fromShortLinDiff (ShortLinDiff axis diff) = LongLinDiff axis diff
170176

171177
encodeL :: Coded a => a -> L.ByteString
172178
encodeL x = runPutL . runEncode $ encode x >> flush

test/Test.hs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Test.Tasty
2+
3+
import TestSpec
4+
import TestOptimizations
5+
6+
main :: IO ()
7+
main = defaultMain tests
8+
9+
tests :: TestTree
10+
tests = testGroup "Tests" [specExamples, codec, optimizations]

test/TestOptimizations.hs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module TestOptimizations where
2+
3+
import Test.Tasty
4+
import Test.Tasty.HUnit
5+
6+
import Optimizations
7+
import Trace
8+
9+
optimizations :: TestTree
10+
optimizations = testGroup "Optimizations" [testSplitLMove]
11+
12+
testSplitLMove :: TestTree
13+
testSplitLMove = testGroup "splitLMove"
14+
[
15+
testCase "Empty input" $ splitLMove [] @?= []
16+
17+
, testCase "Unoptimal input" $
18+
let
19+
a = ShortLinDiff X 3
20+
a' = fromShortLinDiff a
21+
b = ShortLinDiff Z (-1)
22+
b' = fromShortLinDiff b
23+
in splitLMove [LMove a b, Wait] @?= [SMove a', SMove b']
24+
25+
, testCase "Only first occurrence is optimized" $
26+
let
27+
a = ShortLinDiff X 3
28+
a' = fromShortLinDiff a
29+
b = ShortLinDiff Z (-1)
30+
b' = fromShortLinDiff b
31+
in
32+
splitLMove [LMove a b, Wait, LMove a b, Wait]
33+
@?= [SMove a', SMove b', LMove a b, Wait]
34+
]

test/Spec.hs renamed to test/TestSpec.hs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
{-# LANGUAGE BinaryLiterals #-}
22

3+
module TestSpec (
4+
specExamples,
5+
codec
6+
) where
7+
38
import Test.Tasty
49
import Test.Tasty.HUnit
510

@@ -15,12 +20,6 @@ assert :: String -> Bool -> IO ()
1520
assert _ True = return ()
1621
assert message False = fail message
1722

18-
main :: IO ()
19-
main = defaultMain tests
20-
21-
tests :: TestTree
22-
tests = testGroup "Tests" [specExamples, codec]
23-
2423
specExamples :: TestTree
2524
specExamples = testGroup "Specification examples"
2625
[

0 commit comments

Comments
 (0)