From bba3f16c43d9cad6ec92cbdfbfe69703701319bc Mon Sep 17 00:00:00 2001 From: William Carroll Date: Wed, 12 Aug 2020 12:03:35 +0100 Subject: [PATCH] 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 --- scratch/brilliant/App.hs | 23 +++++++++++++++--- scratch/brilliant/README.md | 18 +++++++------- scratch/brilliant/Spec.hs | 45 ++++++++++++++++++----------------- scratch/brilliant/default.nix | 7 +++--- scratch/brilliant/shell.nix | 1 + 5 files changed, 57 insertions(+), 37 deletions(-) diff --git a/scratch/brilliant/App.hs b/scratch/brilliant/App.hs index bf39de499..0272988f3 100644 --- a/scratch/brilliant/App.hs +++ b/scratch/brilliant/App.hs @@ -7,14 +7,31 @@ import Utils ((|>)) import qualified Data.Char as Char import qualified Utils +import qualified Data.List.Split as Split import qualified Keyboard import qualified Data.HashMap.Strict as HM -------------------------------------------------------------------------------- transform :: Keyboard -> Transform -> Keyboard -transform (Keyboard xs) HorizontalFlip = xs |> fmap reverse |> Keyboard -transform (Keyboard xs) VerticalFlip = xs |> reverse |> Keyboard -transform (Keyboard xs) (Shift n) = xs |> fmap (Utils.rotate n) |> Keyboard + +transform (Keyboard xs) xform = + 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 passage newKeyboard = diff --git a/scratch/brilliant/README.md b/scratch/brilliant/README.md index a9019a0f4..60d7de4e2 100644 --- a/scratch/brilliant/README.md +++ b/scratch/brilliant/README.md @@ -57,11 +57,11 @@ Now a working example: $ ./result/transform-keyboard --transforms=HHVS12VHVHS3 --passage='Hello,Brilliant.' Typing: "Hello,Brilliant." On this keyboard: -[N][M][,][.][/][Z][X][C][V][B] -[H][J][K][L][;][A][S][D][F][G] -[Y][U][I][O][P][Q][W][E][R][T] -[6][7][8][9][0][1][2][3][4][5] -Result: QKRRF30LDRRDY1;4 +[H][J][K][L][;][Q][W][E][R][T] +[Y][U][I][O][P][1][2][3][4][5] +[6][7][8][9][0][Z][X][C][V][B] +[N][M][,][.][/][A][S][D][F][G] +Result: ZIVV4D/O3VV36APF ``` ...and an example with an erroneous input (i.e. `!`): @@ -70,10 +70,10 @@ Result: QKRRF30LDRRDY1;4 $ ./result/transform-keyboard --transforms=HHVS12VHVHS3 --passage='Hello,Brilliant!' Typing: "Hello,Brilliant!" On this keyboard: -[N][M][,][.][/][Z][X][C][V][B] -[H][J][K][L][;][A][S][D][F][G] -[Y][U][I][O][P][Q][W][E][R][T] -[6][7][8][9][0][1][2][3][4][5] +[H][J][K][L][;][Q][W][E][R][T] +[Y][U][I][O][P][1][2][3][4][5] +[6][7][8][9][0][Z][X][C][V][B] +[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: [1][2][3][4][5][6][7][8][9][0] [Q][W][E][R][T][Y][U][I][O][P] diff --git a/scratch/brilliant/Spec.hs b/scratch/brilliant/Spec.hs index 78ae8cb50..e99e02564 100644 --- a/scratch/brilliant/Spec.hs +++ b/scratch/brilliant/Spec.hs @@ -5,11 +5,12 @@ import Test.Hspec import Test.QuickCheck import Keyboard (Keyboard(..)) import Transforms (Transform(..)) +import Data.Coerce +import Utils import qualified App import qualified Keyboard import qualified Transforms -import qualified Utils -------------------------------------------------------------------------------- main :: IO () @@ -55,12 +56,12 @@ main = hspec $ do it "shifts any keyboard" $ do property $ \first second third fourth n -> - App.transform (Keyboard [first, second, third, fourth]) (Shift n) == do - Keyboard $ [ Utils.rotate n first - , Utils.rotate n second - , Utils.rotate n third - , Utils.rotate n fourth - ] + App.transform (Keyboard [first, second, third, fourth]) (Shift n) + |> (coerce :: Keyboard -> [[Char]]) + |> concat == + [first, second, third, fourth] + |> concat + |> Utils.rotate n it "flips a QWERTY keyboard horizontally" $ do App.transform Keyboard.qwerty HorizontalFlip == do @@ -72,27 +73,27 @@ main = hspec $ do it "flips a keyboard vertically" $ do App.transform Keyboard.qwerty VerticalFlip == do - Keyboard $ [ ['Z','X','C','V','B','N','M',',','.','/'] - , ['A','S','D','F','G','H','J','K','L',';'] - , ['Q','W','E','R','T','Y','U','I','O','P'] - , ['1','2','3','4','5','6','7','8','9','0'] - ] + Keyboard [ ['Z','X','C','V','B','N','M',',','.','/'] + , ['A','S','D','F','G','H','J','K','L',';'] + , ['Q','W','E','R','T','Y','U','I','O','P'] + , ['1','2','3','4','5','6','7','8','9','0'] + ] it "shifts a keyboard left N times" $ do App.transform Keyboard.qwerty (Shift 2) == do - Keyboard $ [ ['3','4','5','6','7','8','9','0','1','2'] - , ['E','R','T','Y','U','I','O','P','Q','W'] - , ['D','F','G','H','J','K','L',';','A','S'] - , ['C','V','B','N','M',',','.','/','Z','X'] - ] + Keyboard [ ['3','4','5','6','7','8','9','0','Q','W'] + , ['E','R','T','Y','U','I','O','P','A','S'] + , ['D','F','G','H','J','K','L',';','Z','X'] + , ['C','V','B','N','M',',','.','/','1','2'] + ] it "shifts right negative amounts" $ do App.transform Keyboard.qwerty (Shift (-3)) == do - Keyboard $ [ ['8','9','0','1','2','3','4','5','6','7'] - , ['I','O','P','Q','W','E','R','T','Y','U'] - , ['K','L',';','A','S','D','F','G','H','J'] - , [',','.','/','Z','X','C','V','B','N','M'] - ] + Keyboard [ [',','.','/','1','2','3','4','5','6','7'] + , ['8','9','0','Q','W','E','R','T','Y','U'] + , ['I','O','P','A','S','D','F','G','H','J'] + , ['K','L',';','Z','X','C','V','B','N','M'] + ] describe "Transforms.optimize" $ do it "removes superfluous horizontal transformations" $ do diff --git a/scratch/brilliant/default.nix b/scratch/brilliant/default.nix index 83c62a3d2..5a0ece741 100644 --- a/scratch/brilliant/default.nix +++ b/scratch/brilliant/default.nix @@ -5,9 +5,10 @@ let rev = "afa9ca61924f05aacfe495a7ad0fd84709d236cc"; }) {}; - ghc = pkgs.haskellPackages.ghcWithPackages (hpkgs: [ - hpkgs.optparse-applicative - hpkgs.unordered-containers + ghc = pkgs.haskellPackages.ghcWithPackages (hpkgs: with hpkgs; [ + optparse-applicative + unordered-containers + split ]); in pkgs.stdenv.mkDerivation { name = "transform-keyboard"; diff --git a/scratch/brilliant/shell.nix b/scratch/brilliant/shell.nix index 02d69d3be..d0a6c7e5e 100644 --- a/scratch/brilliant/shell.nix +++ b/scratch/brilliant/shell.nix @@ -10,6 +10,7 @@ in pkgs.mkShell { hspec optparse-applicative unordered-containers + split ])) ]; }