Skip to content

Instantly share code, notes, and snippets.

@anton0xf
Created August 18, 2024 17:07
Show Gist options
  • Save anton0xf/78fda50c8c1fb306d6bf37ee9573d8f3 to your computer and use it in GitHub Desktop.
Save anton0xf/78fda50c8c1fb306d6bf37ee9573d8f3 to your computer and use it in GitHub Desktop.
module NextBiggerSpec (spec) where
import Test.Hspec
import Test.QuickCheck
import NextBigger (nextBigger)
import Data.List (sort,unfoldr)
import Data.Tuple (swap)
import Data.Maybe (isJust,fromJust)
spec :: Spec
spec = do
it "example tests" $ do
nextBigger 12 `shouldBe` 21
nextBigger 513 `shouldBe` 531
nextBigger 2017 `shouldBe` 2071
nextBigger 414 `shouldBe` 441
nextBigger 144 `shouldBe` 414
it "fixed tests" $ do
nextBigger 123456789 `shouldBe` 123456798
nextBigger 1234567890 `shouldBe` 1234567908
nextBigger 9876543210 `shouldBe` -1
nextBigger 9999999999 `shouldBe` -1
nextBigger 59884848459853 `shouldBe` 59884848483559
it "random tests" $ do
property $ withMaxSuccess 140 $ forAll (oneof [genArg,sortDesc <$> genArg]) $ \ n -> do
-- print (n,refNextBigger n)
nextBigger n `shouldBe` refNextBigger n
genArg :: Gen Int
genArg = do e <- choose (1,14 :: Int) ; choose (1,10^e-1)
sortDesc :: Int -> Int
sortDesc n = foldr ( \ v z -> 10 * z + v ) 0 $ sort $ unfoldr mod10 n where
mod10 0 = Nothing
mod10 n = Just $ swap $ n `divMod` 10
refNextBigger :: Int -> Int
refNextBigger n = maybe (-1) ( const $ read $ hd ++ mv : replace mv pvt (reverse tl) ) i where
s = show n
i = foldr ( \ (i,c,d) z -> if isJust z then z else if c < d then Just i else Nothing ) Nothing $ zip3 [0..] s (tail s)
(hd,pvt:tl) = splitAt (fromJust i) s
mv = minimum $ filter (> pvt) tl
replace _ _ [] = error "replace: needle not found in haystack"
replace needle replacement (hay:stack) | hay == needle = replacement : stack
| otherwise = hay : replace needle replacement stack
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment