TF6PK6JDRLBRDRJVI7M4RWSJG5NK6SAMSYINXD6ZGSE7DL4ILTMAC MCBWM3FBZPTBMBJM4QISAX45C2D75QGHWXPLAYMN3EXJJ2CV4ASAC XL3UEJW5ODILLWT37VFOTWJG5J4YV4MTODD5BTREEC7ZFSYXQHZQC TEWWDULPAUYV2VFT3LGUTXGVVDPFFTBRHXQVJAZT63D5Q2NLPS6QC 5CXVNGYMMIBKPFJFJK7T5HLMUAP2IE7UCFZBFZTY5DBJFRQHPP5QC VRPOSMITS7VRSIJU6YNEBELCUBTHPMPJD6F6F5PE35R2KECS42KAC ASGE7I4JJ3HTHHSQKVNL74ZVZQ6WTYX6M54FYKOUE4PCPRPUNSUQC PMF36FUOINXVVNP5XW6ZOFPPWFBRK62O4VCX45NE4Y4GDPL2Z3BQC WFOLCYCZVNRVCEWSDJR36BGSN6IKJ4CMISYCOWBLENMOP2JUTRIQC L6TQHWB6JUMHD6KZR3RMO23UHQ2E37P2BAFZGDXBL5KWK2WWAIJQC 2Q7SZHYMAFCYLG5MROYQ4BJ7HDIASPLIZJP7SM7BNX4GESUCZXJQC O6UAIBEXBNE2XMWQWU6YKGGRLDQFI364JMV6HCYCCI3LBQRD6RPQC G25ET6HXYNPM2HJ2L76TGOLVV2LBDA3CIWCAN6SL2WKNTUG56RDQC twoPowers :: (Num a, Bits a, Integral b) => a -> [b]twoPowers 0 = []twoPowers m =(if m `testBit` 0 then (0 :) else id) . fmap (+ 1) $ twoPowers (m `shiftR` 1)
-- | Index of highest-order set bit, or -1 if there are none.
mult' :: Int -> Nimber -> Nimber -> Nimbermult' _ 0 _ = 0mult' _ _ 0 = 0mult' _ 1 b = bmult' _ a 1 = amult' m a b =let semiD = bit (bit m - 1) -- semimultiple of Ds1 = a `shiftR` bit m -- a = a1D+a2s2 = a .^. (s1 `shiftL` bit m)t1 = b `shiftR` bit m -- b = b1D+b2t2 = b .^. (t1 `shiftL` bit m)c = mult' (m - 1) s2 t2in ((mult' (m - 1) (s1 + s2) (t1 + t2) - c) `shiftL` bit m) + mult' (m - 1) (mult' (m - 1) s1 t1) semiD + c
mult' _ 0 _ = 0mult' _ _ 0 = 0mult' _ 1 t = tmult' _ s 1 = smult' k s t =let semiD = bit (bit k - 1) -- semimultiple of Ds1 = s `shiftR` bit k -- a = a1D+a2s2 = s .^. (s1 `shiftL` bit k)t1 = t `shiftR` bit k -- b = b1D+b2t2 = t .^. (t1 `shiftL` bit k)c = mult' (k-1) s2 t2in ((mult' (k-1) (s1 + s2) (t1 + t2) - c) `shiftL` bit k) + mult' (k-1) (mult' (k-1) s1 t1) semiD + c
sqr' :: Int -> Nimber -> Nimbersqr' _ 0 = 0sqr' _ 1 = 1sqr' m n =let a = n `shiftR` bit m -- n = aD+baD = a `shiftL` bit mb = n .^. aDsemiD = bit (bit m - 1) -- semimultiple of Dsqra = sqr' (m - 1) ain sqra `shiftL` bit m + mult' (m - 1) sqra semiD + sqr' (m - 1) b
| otherwise = product . fmap snd . filter (testBit n . fst) . zip [0 ..] . take (1 + floorLog (n + 1)) $ iterate sqr x
| otherwise =let m = floorLog @Int $ floorLog xin product . fmap snd . filter (testBit n . fst) . zip [0 ..] . take (1 + floorLog (n + 1)) $ iterate (sqr' m) x