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…
	
	Add table
		Add a link
		
	
		Reference in a new issue