Prefer snake-shift instead of a row-by-row shift
Per the assignment's instructions, the `Shift n` operation should treat the *entire keyboard* like a cycle and shift that. I was erroneously treating *each row* like a cycle and shifting those one-by-one. This change fixes that. In addition, it also: - Updates README.md with expected inputs and outputs - Updates test suite - Adds `split` dependency to {default,shell}.nix
This commit is contained in:
parent
f11b91c985
commit
bba3f16c43
5 changed files with 57 additions and 37 deletions
|
@ -7,14 +7,31 @@ import Utils ((|>))
|
||||||
|
|
||||||
import qualified Data.Char as Char
|
import qualified Data.Char as Char
|
||||||
import qualified Utils
|
import qualified Utils
|
||||||
|
import qualified Data.List.Split as Split
|
||||||
import qualified Keyboard
|
import qualified Keyboard
|
||||||
import qualified Data.HashMap.Strict as HM
|
import qualified Data.HashMap.Strict as HM
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
transform :: Keyboard -> Transform -> Keyboard
|
transform :: Keyboard -> Transform -> Keyboard
|
||||||
transform (Keyboard xs) HorizontalFlip = xs |> fmap reverse |> Keyboard
|
|
||||||
transform (Keyboard xs) VerticalFlip = xs |> reverse |> Keyboard
|
transform (Keyboard xs) xform =
|
||||||
transform (Keyboard xs) (Shift n) = xs |> fmap (Utils.rotate n) |> Keyboard
|
case xform of
|
||||||
|
HorizontalFlip ->
|
||||||
|
xs
|
||||||
|
|> fmap reverse
|
||||||
|
|> Keyboard
|
||||||
|
|
||||||
|
VerticalFlip ->
|
||||||
|
xs
|
||||||
|
|> reverse
|
||||||
|
|> Keyboard
|
||||||
|
|
||||||
|
Shift n ->
|
||||||
|
xs
|
||||||
|
|> concat
|
||||||
|
|> Utils.rotate n
|
||||||
|
|> Split.chunksOf 10
|
||||||
|
|> Keyboard
|
||||||
|
|
||||||
retypePassage :: String -> Keyboard -> Maybe String
|
retypePassage :: String -> Keyboard -> Maybe String
|
||||||
retypePassage passage newKeyboard =
|
retypePassage passage newKeyboard =
|
||||||
|
|
|
@ -57,11 +57,11 @@ Now a working example:
|
||||||
$ ./result/transform-keyboard --transforms=HHVS12VHVHS3 --passage='Hello,Brilliant.'
|
$ ./result/transform-keyboard --transforms=HHVS12VHVHS3 --passage='Hello,Brilliant.'
|
||||||
Typing: "Hello,Brilliant."
|
Typing: "Hello,Brilliant."
|
||||||
On this keyboard:
|
On this keyboard:
|
||||||
[N][M][,][.][/][Z][X][C][V][B]
|
[H][J][K][L][;][Q][W][E][R][T]
|
||||||
[H][J][K][L][;][A][S][D][F][G]
|
[Y][U][I][O][P][1][2][3][4][5]
|
||||||
[Y][U][I][O][P][Q][W][E][R][T]
|
[6][7][8][9][0][Z][X][C][V][B]
|
||||||
[6][7][8][9][0][1][2][3][4][5]
|
[N][M][,][.][/][A][S][D][F][G]
|
||||||
Result: QKRRF30LDRRDY1;4
|
Result: ZIVV4D/O3VV36APF
|
||||||
```
|
```
|
||||||
|
|
||||||
...and an example with an erroneous input (i.e. `!`):
|
...and an example with an erroneous input (i.e. `!`):
|
||||||
|
@ -70,10 +70,10 @@ Result: QKRRF30LDRRDY1;4
|
||||||
$ ./result/transform-keyboard --transforms=HHVS12VHVHS3 --passage='Hello,Brilliant!'
|
$ ./result/transform-keyboard --transforms=HHVS12VHVHS3 --passage='Hello,Brilliant!'
|
||||||
Typing: "Hello,Brilliant!"
|
Typing: "Hello,Brilliant!"
|
||||||
On this keyboard:
|
On this keyboard:
|
||||||
[N][M][,][.][/][Z][X][C][V][B]
|
[H][J][K][L][;][Q][W][E][R][T]
|
||||||
[H][J][K][L][;][A][S][D][F][G]
|
[Y][U][I][O][P][1][2][3][4][5]
|
||||||
[Y][U][I][O][P][Q][W][E][R][T]
|
[6][7][8][9][0][Z][X][C][V][B]
|
||||||
[6][7][8][9][0][1][2][3][4][5]
|
[N][M][,][.][/][A][S][D][F][G]
|
||||||
Looks like at least one of the characters in your input passage doesn't fit on our QWERTY keyboard:
|
Looks like at least one of the characters in your input passage doesn't fit on our QWERTY keyboard:
|
||||||
[1][2][3][4][5][6][7][8][9][0]
|
[1][2][3][4][5][6][7][8][9][0]
|
||||||
[Q][W][E][R][T][Y][U][I][O][P]
|
[Q][W][E][R][T][Y][U][I][O][P]
|
||||||
|
|
|
@ -5,11 +5,12 @@ import Test.Hspec
|
||||||
import Test.QuickCheck
|
import Test.QuickCheck
|
||||||
import Keyboard (Keyboard(..))
|
import Keyboard (Keyboard(..))
|
||||||
import Transforms (Transform(..))
|
import Transforms (Transform(..))
|
||||||
|
import Data.Coerce
|
||||||
|
import Utils
|
||||||
|
|
||||||
import qualified App
|
import qualified App
|
||||||
import qualified Keyboard
|
import qualified Keyboard
|
||||||
import qualified Transforms
|
import qualified Transforms
|
||||||
import qualified Utils
|
|
||||||
--------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------
|
||||||
|
|
||||||
main :: IO ()
|
main :: IO ()
|
||||||
|
@ -55,12 +56,12 @@ main = hspec $ do
|
||||||
|
|
||||||
it "shifts any keyboard" $ do
|
it "shifts any keyboard" $ do
|
||||||
property $ \first second third fourth n ->
|
property $ \first second third fourth n ->
|
||||||
App.transform (Keyboard [first, second, third, fourth]) (Shift n) == do
|
App.transform (Keyboard [first, second, third, fourth]) (Shift n)
|
||||||
Keyboard $ [ Utils.rotate n first
|
|> (coerce :: Keyboard -> [[Char]])
|
||||||
, Utils.rotate n second
|
|> concat ==
|
||||||
, Utils.rotate n third
|
[first, second, third, fourth]
|
||||||
, Utils.rotate n fourth
|
|> concat
|
||||||
]
|
|> Utils.rotate n
|
||||||
|
|
||||||
it "flips a QWERTY keyboard horizontally" $ do
|
it "flips a QWERTY keyboard horizontally" $ do
|
||||||
App.transform Keyboard.qwerty HorizontalFlip == do
|
App.transform Keyboard.qwerty HorizontalFlip == do
|
||||||
|
@ -72,27 +73,27 @@ main = hspec $ do
|
||||||
|
|
||||||
it "flips a keyboard vertically" $ do
|
it "flips a keyboard vertically" $ do
|
||||||
App.transform Keyboard.qwerty VerticalFlip == do
|
App.transform Keyboard.qwerty VerticalFlip == do
|
||||||
Keyboard $ [ ['Z','X','C','V','B','N','M',',','.','/']
|
Keyboard [ ['Z','X','C','V','B','N','M',',','.','/']
|
||||||
, ['A','S','D','F','G','H','J','K','L',';']
|
, ['A','S','D','F','G','H','J','K','L',';']
|
||||||
, ['Q','W','E','R','T','Y','U','I','O','P']
|
, ['Q','W','E','R','T','Y','U','I','O','P']
|
||||||
, ['1','2','3','4','5','6','7','8','9','0']
|
, ['1','2','3','4','5','6','7','8','9','0']
|
||||||
]
|
]
|
||||||
|
|
||||||
it "shifts a keyboard left N times" $ do
|
it "shifts a keyboard left N times" $ do
|
||||||
App.transform Keyboard.qwerty (Shift 2) == do
|
App.transform Keyboard.qwerty (Shift 2) == do
|
||||||
Keyboard $ [ ['3','4','5','6','7','8','9','0','1','2']
|
Keyboard [ ['3','4','5','6','7','8','9','0','Q','W']
|
||||||
, ['E','R','T','Y','U','I','O','P','Q','W']
|
, ['E','R','T','Y','U','I','O','P','A','S']
|
||||||
, ['D','F','G','H','J','K','L',';','A','S']
|
, ['D','F','G','H','J','K','L',';','Z','X']
|
||||||
, ['C','V','B','N','M',',','.','/','Z','X']
|
, ['C','V','B','N','M',',','.','/','1','2']
|
||||||
]
|
]
|
||||||
|
|
||||||
it "shifts right negative amounts" $ do
|
it "shifts right negative amounts" $ do
|
||||||
App.transform Keyboard.qwerty (Shift (-3)) == do
|
App.transform Keyboard.qwerty (Shift (-3)) == do
|
||||||
Keyboard $ [ ['8','9','0','1','2','3','4','5','6','7']
|
Keyboard [ [',','.','/','1','2','3','4','5','6','7']
|
||||||
, ['I','O','P','Q','W','E','R','T','Y','U']
|
, ['8','9','0','Q','W','E','R','T','Y','U']
|
||||||
, ['K','L',';','A','S','D','F','G','H','J']
|
, ['I','O','P','A','S','D','F','G','H','J']
|
||||||
, [',','.','/','Z','X','C','V','B','N','M']
|
, ['K','L',';','Z','X','C','V','B','N','M']
|
||||||
]
|
]
|
||||||
|
|
||||||
describe "Transforms.optimize" $ do
|
describe "Transforms.optimize" $ do
|
||||||
it "removes superfluous horizontal transformations" $ do
|
it "removes superfluous horizontal transformations" $ do
|
||||||
|
|
|
@ -5,9 +5,10 @@ let
|
||||||
rev = "afa9ca61924f05aacfe495a7ad0fd84709d236cc";
|
rev = "afa9ca61924f05aacfe495a7ad0fd84709d236cc";
|
||||||
}) {};
|
}) {};
|
||||||
|
|
||||||
ghc = pkgs.haskellPackages.ghcWithPackages (hpkgs: [
|
ghc = pkgs.haskellPackages.ghcWithPackages (hpkgs: with hpkgs; [
|
||||||
hpkgs.optparse-applicative
|
optparse-applicative
|
||||||
hpkgs.unordered-containers
|
unordered-containers
|
||||||
|
split
|
||||||
]);
|
]);
|
||||||
in pkgs.stdenv.mkDerivation {
|
in pkgs.stdenv.mkDerivation {
|
||||||
name = "transform-keyboard";
|
name = "transform-keyboard";
|
||||||
|
|
|
@ -10,6 +10,7 @@ in pkgs.mkShell {
|
||||||
hspec
|
hspec
|
||||||
optparse-applicative
|
optparse-applicative
|
||||||
unordered-containers
|
unordered-containers
|
||||||
|
split
|
||||||
]))
|
]))
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue