integer-roots-1.0.2.0/0000755000000000000000000000000007346545000012642 5ustar0000000000000000integer-roots-1.0.2.0/LICENSE0000644000000000000000000000210707346545000013647 0ustar0000000000000000Copyright (c) 2011 Daniel Fischer, 2016-2020 Andrew Lelechenko. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. integer-roots-1.0.2.0/Math/NumberTheory/Primes/0000755000000000000000000000000007346545000017415 5ustar0000000000000000integer-roots-1.0.2.0/Math/NumberTheory/Primes/Small.hs0000644000000000000000000022333007346545000021024 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Primes.Small -- Copyright: (c) 2019 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- This is an internal module, -- defining an array of precalculated primes < 2^16. -- {-# LANGUAGE MagicHash #-} module Math.NumberTheory.Primes.Small ( smallPrimesPtr , smallPrimesLength ) where import GHC.Exts (Ptr(..)) import Data.Word (Word16) -- length smallPrimes smallPrimesLength :: Int smallPrimesLength = 6542 -- concatMap (\x -> map Data.Char.chr [x `mod` 256, x `quot` 256]) smallPrimes smallPrimesPtr :: Ptr Word16 smallPrimesPtr = Ptr "\STX\NUL\ETX\NUL\ENQ\NUL\a\NUL\v\NUL\r\NUL\DC1\NUL\DC3\NUL\ETB\NUL\GS\NUL\US\NUL%\NUL)\NUL+\NUL/\NUL5\NUL;\NUL=\NULC\NULG\NULI\NULO\NULS\NULY\NULa\NULe\NULg\NULk\NULm\NULq\NUL\DEL\NUL\131\NUL\137\NUL\139\NUL\149\NUL\151\NUL\157\NUL\163\NUL\167\NUL\173\NUL\179\NUL\181\NUL\191\NUL\193\NUL\197\NUL\199\NUL\211\NUL\223\NUL\227\NUL\229\NUL\233\NUL\239\NUL\241\NUL\251\NUL\SOH\SOH\a\SOH\r\SOH\SI\SOH\NAK\SOH\EM\SOH\ESC\SOH%\SOH3\SOH7\SOH9\SOH=\SOHK\SOHQ\SOH[\SOH]\SOHa\SOHg\SOHo\SOHu\SOH{\SOH\DEL\SOH\133\SOH\141\SOH\145\SOH\153\SOH\163\SOH\165\SOH\175\SOH\177\SOH\183\SOH\187\SOH\193\SOH\201\SOH\205\SOH\207\SOH\211\SOH\223\SOH\231\SOH\235\SOH\243\SOH\247\SOH\253\SOH\t\STX\v\STX\GS\STX#\STX-\STX3\STX9\STX;\STXA\STXK\STXQ\STXW\STXY\STX_\STXe\STXi\STXk\STXw\STX\129\STX\131\STX\135\STX\141\STX\147\STX\149\STX\161\STX\165\STX\171\STX\179\STX\189\STX\197\STX\207\STX\215\STX\221\STX\227\STX\231\STX\239\STX\245\STX\249\STX\SOH\ETX\ENQ\ETX\DC3\ETX\GS\ETX)\ETX+\ETX5\ETX7\ETX;\ETX=\ETXG\ETXU\ETXY\ETX[\ETX_\ETXm\ETXq\ETXs\ETXw\ETX\139\ETX\143\ETX\151\ETX\161\ETX\169\ETX\173\ETX\179\ETX\185\ETX\199\ETX\203\ETX\209\ETX\215\ETX\223\ETX\229\ETX\241\ETX\245\ETX\251\ETX\253\ETX\a\EOT\t\EOT\SI\EOT\EM\EOT\ESC\EOT%\EOT'\EOT-\EOT?\EOTC\EOTE\EOTI\EOTO\EOTU\EOT]\EOTc\EOTi\EOT\DEL\EOT\129\EOT\139\EOT\147\EOT\157\EOT\163\EOT\169\EOT\177\EOT\189\EOT\193\EOT\199\EOT\205\EOT\207\EOT\213\EOT\225\EOT\235\EOT\253\EOT\255\EOT\ETX\ENQ\t\ENQ\v\ENQ\DC1\ENQ\NAK\ENQ\ETB\ENQ\ESC\ENQ'\ENQ)\ENQ/\ENQQ\ENQW\ENQ]\ENQe\ENQw\ENQ\129\ENQ\143\ENQ\147\ENQ\149\ENQ\153\ENQ\159\ENQ\167\ENQ\171\ENQ\173\ENQ\179\ENQ\191\ENQ\201\ENQ\203\ENQ\207\ENQ\209\ENQ\213\ENQ\219\ENQ\231\ENQ\243\ENQ\251\ENQ\a\ACK\r\ACK\DC1\ACK\ETB\ACK\US\ACK#\ACK+\ACK/\ACK=\ACKA\ACKG\ACKI\ACKM\ACKS\ACKU\ACK[\ACKe\ACKy\ACK\DEL\ACK\131\ACK\133\ACK\157\ACK\161\ACK\163\ACK\173\ACK\185\ACK\187\ACK\197\ACK\205\ACK\211\ACK\217\ACK\223\ACK\241\ACK\247\ACK\251\ACK\253\ACK\t\a\DC3\a\US\a'\a7\aE\aK\aO\aQ\aU\aW\aa\am\as\ay\a\139\a\141\a\157\a\159\a\181\a\187\a\195\a\201\a\205\a\207\a\211\a\219\a\225\a\235\a\237\a\247\a\ENQ\b\SI\b\NAK\b!\b#\b'\b)\b3\b?\bA\bQ\bS\bY\b]\b_\bi\bq\b\131\b\155\b\159\b\165\b\173\b\189\b\191\b\195\b\203\b\219\b\221\b\225\b\233\b\239\b\245\b\249\b\ENQ\t\a\t\GS\t#\t%\t+\t/\t5\tC\tI\tM\tO\tU\tY\t_\tk\tq\tw\t\133\t\137\t\143\t\155\t\163\t\169\t\173\t\199\t\217\t\227\t\235\t\239\t\245\t\247\t\253\t\DC3\n\US\n!\n1\n9\n=\nI\nW\na\nc\ng\no\nu\n{\n\DEL\n\129\n\133\n\139\n\147\n\151\n\153\n\159\n\169\n\171\n\181\n\189\n\193\n\207\n\217\n\229\n\231\n\237\n\241\n\243\n\ETX\v\DC1\v\NAK\v\ESC\v#\v)\v-\v?\vG\vQ\vW\v]\ve\vo\v{\v\137\v\141\v\147\v\153\v\155\v\183\v\185\v\195\v\203\v\207\v\221\v\225\v\233\v\245\v\251\v\a\f\v\f\DC1\f%\f/\f1\fA\f[\f_\fa\fm\fs\fw\f\131\f\137\f\145\f\149\f\157\f\179\f\181\f\185\f\187\f\199\f\227\f\229\f\235\f\241\f\247\f\251\f\SOH\r\ETX\r\SI\r\DC3\r\US\r!\r+\r-\r=\r?\rO\rU\ri\ry\r\129\r\133\r\135\r\139\r\141\r\163\r\171\r\183\r\189\r\199\r\201\r\205\r\211\r\213\r\219\r\229\r\231\r\243\r\253\r\255\r\t\SO\ETB\SO\GS\SO!\SO'\SO/\SO5\SO;\SOK\SOW\SOY\SO]\SOk\SOq\SOu\SO}\SO\135\SO\143\SO\149\SO\155\SO\177\SO\183\SO\185\SO\195\SO\209\SO\213\SO\219\SO\237\SO\239\SO\249\SO\a\SI\v\SI\r\SI\ETB\SI%\SI)\SI1\SIC\SIG\SIM\SIO\SIS\SIY\SI[\SIg\SIk\SI\DEL\SI\149\SI\161\SI\163\SI\167\SI\173\SI\179\SI\181\SI\187\SI\209\SI\211\SI\217\SI\233\SI\239\SI\251\SI\253\SI\ETX\DLE\SI\DLE\US\DLE!\DLE%\DLE+\DLE9\DLE=\DLE?\DLEQ\DLEi\DLEs\DLEy\DLE{\DLE\133\DLE\135\DLE\145\DLE\147\DLE\157\DLE\163\DLE\165\DLE\175\DLE\177\DLE\187\DLE\193\DLE\201\DLE\231\DLE\241\DLE\243\DLE\253\DLE\ENQ\DC1\v\DC1\NAK\DC1'\DC1-\DC19\DC1E\DC1G\DC1Y\DC1_\DC1c\DC1i\DC1o\DC1\129\DC1\131\DC1\141\DC1\155\DC1\161\DC1\165\DC1\167\DC1\171\DC1\195\DC1\197\DC1\209\DC1\215\DC1\231\DC1\239\DC1\245\DC1\251\DC1\r\DC2\GS\DC2\US\DC2#\DC2)\DC2+\DC21\DC27\DC2A\DC2G\DC2S\DC2_\DC2q\DC2s\DC2y\DC2}\DC2\143\DC2\151\DC2\175\DC2\179\DC2\181\DC2\185\DC2\191\DC2\193\DC2\205\DC2\209\DC2\223\DC2\253\DC2\a\DC3\r\DC3\EM\DC3'\DC3-\DC37\DC3C\DC3E\DC3I\DC3O\DC3W\DC3]\DC3g\DC3i\DC3m\DC3{\DC3\129\DC3\135\DC3\139\DC3\145\DC3\147\DC3\157\DC3\159\DC3\175\DC3\187\DC3\195\DC3\213\DC3\217\DC3\223\DC3\235\DC3\237\DC3\243\DC3\249\DC3\255\DC3\ESC\DC4!\DC4/\DC43\DC4;\DC4E\DC4M\DC4Y\DC4k\DC4o\DC4q\DC4u\DC4\141\DC4\153\DC4\159\DC4\161\DC4\177\DC4\183\DC4\189\DC4\203\DC4\213\DC4\227\DC4\231\DC4\ENQ\NAK\v\NAK\DC1\NAK\ETB\NAK\US\NAK%\NAK)\NAK+\NAK7\NAK=\NAKA\NAKC\NAKI\NAK_\NAKe\NAKg\NAKk\NAK}\NAK\DEL\NAK\131\NAK\143\NAK\145\NAK\151\NAK\155\NAK\181\NAK\187\NAK\193\NAK\197\NAK\205\NAK\215\NAK\247\NAK\a\SYN\t\SYN\SI\SYN\DC3\SYN\NAK\SYN\EM\SYN\ESC\SYN%\SYN3\SYN9\SYN=\SYNE\SYNO\SYNU\SYNi\SYNm\SYNo\SYNu\SYN\147\SYN\151\SYN\159\SYN\169\SYN\175\SYN\181\SYN\189\SYN\195\SYN\207\SYN\211\SYN\217\SYN\219\SYN\225\SYN\229\SYN\235\SYN\237\SYN\247\SYN\249\SYN\t\ETB\SI\ETB#\ETB'\ETB3\ETBA\ETB]\ETBc\ETBw\ETB{\ETB\141\ETB\149\ETB\155\ETB\159\ETB\165\ETB\179\ETB\185\ETB\191\ETB\201\ETB\203\ETB\213\ETB\225\ETB\233\ETB\243\ETB\245\ETB\255\ETB\a\CAN\DC3\CAN\GS\CAN5\CAN7\CAN;\CANC\CANI\CANM\CANU\CANg\CANq\CANw\CAN}\CAN\DEL\CAN\133\CAN\143\CAN\155\CAN\157\CAN\167\CAN\173\CAN\179\CAN\185\CAN\193\CAN\199\CAN\209\CAN\215\CAN\217\CAN\223\CAN\229\CAN\235\CAN\245\CAN\253\CAN\NAK\EM\ESC\EM1\EM3\EME\EMI\EMQ\EM[\EMy\EM\129\EM\147\EM\151\EM\153\EM\163\EM\169\EM\171\EM\177\EM\181\EM\199\EM\207\EM\219\EM\237\EM\253\EM\ETX\SUB\ENQ\SUB\DC1\SUB\ETB\SUB!\SUB#\SUB-\SUB/\SUB5\SUB?\SUBM\SUBQ\SUBi\SUBk\SUB{\SUB}\SUB\135\SUB\137\SUB\147\SUB\167\SUB\171\SUB\173\SUB\177\SUB\185\SUB\201\SUB\207\SUB\213\SUB\215\SUB\227\SUB\243\SUB\251\SUB\255\SUB\ENQ\ESC#\ESC%\ESC/\ESC1\ESC7\ESC;\ESCA\ESCG\ESCO\ESCU\ESCY\ESCe\ESCk\ESCs\ESC\DEL\ESC\131\ESC\145\ESC\157\ESC\167\ESC\191\ESC\197\ESC\209\ESC\215\ESC\217\ESC\239\ESC\247\ESC\t\FS\DC3\FS\EM\FS'\FS+\FS-\FS3\FS=\FSE\FSK\FSO\FSU\FSs\FS\129\FS\139\FS\141\FS\153\FS\163\FS\165\FS\181\FS\183\FS\201\FS\225\FS\243\FS\249\FS\t\GS\ESC\GS!\GS#\GS5\GS9\GS?\GSA\GSK\GSS\GS]\GSc\GSi\GSq\GSu\GS{\GS}\GS\135\GS\137\GS\149\GS\153\GS\159\GS\165\GS\167\GS\179\GS\183\GS\197\GS\215\GS\219\GS\225\GS\245\GS\249\GS\SOH\RS\a\RS\v\RS\DC3\RS\ETB\RS%\RS+\RS/\RS=\RSI\RSM\RSO\RSm\RSq\RS\137\RS\143\RS\149\RS\161\RS\173\RS\187\RS\193\RS\197\RS\199\RS\203\RS\221\RS\227\RS\239\RS\247\RS\253\RS\SOH\US\r\US\SI\US\ESC\US9\USI\USK\USQ\USg\USu\US{\US\133\US\145\US\151\US\153\US\157\US\165\US\175\US\181\US\187\US\211\US\225\US\231\US\235\US\243\US\255\US\DC1 \ESC \GS ' ) - 3 G M Q _ c e i w } \137 \161 \171 \177 \185 \195 \197 \227 \231 \237 \239 \251 \255 \r!\DC3!5!A!I!O!Y![!_!s!}!\133!\149!\151!\161!\175!\179!\181!\193!\199!\215!\221!\229!\233!\241!\245!\251!\ETX\"\t\"\SI\"\ESC\"!\"%\"+\"1\"9\"K\"O\"c\"g\"s\"u\"\DEL\"\133\"\135\"\145\"\157\"\159\"\163\"\183\"\189\"\219\"\225\"\229\"\237\"\247\"\ETX#\t#\v#'#)#/#3#5#E#Q#S#Y#c#k#\131#\143#\149#\167#\173#\177#\191#\197#\201#\213#\221#\227#\239#\243#\249#\ENQ$\v$\ETB$\EM$)$=$A$C$M$_$g$k$y$}$\DEL$\133$\155$\161$\175$\181$\187$\197$\203$\205$\215$\217$\221$\223$\245$\247$\251$\SOH%\a%\DC3%\EM%'%1%=%C%K%O%s%\129%\141%\147%\151%\157%\159%\171%\177%\189%\205%\207%\217%\225%\247%\249%\ENQ&\v&\SI&\NAK&'&)&5&;&?&K&S&Y&e&i&o&{&\129&\131&\143&\155&\159&\173&\179&\195&\201&\203&\213&\221&\239&\245&\ETB'\EM'5'7'M'S'U'_'k'm's'w'\DEL'\149'\155'\157'\167'\175'\179'\185'\193'\197'\209'\227'\239'\ETX(\a(\r(\DC3(\ESC(\US(!(1(=(?(I(Q([(](a(g(u(\129(\151(\159(\187(\189(\193(\213(\217(\219(\223(\237(\247(\ETX)\ENQ)\DC1)!)#)?)G)])e)i)o)u)\131)\135)\143)\155)\161)\167)\171)\191)\195)\213)\215)\227)\233)\237)\243)\SOH*\DC3*\GS*%*/*O*U*_*e*k*m*s*\131*\137*\139*\151*\157*\185*\187*\197*\205*\221*\227*\235*\241*\251*\DC3+'+1+3+=+?+K+O+U+i+m+o+{+\141+\151+\153+\163+\165+\169+\189+\205+\231+\235+\243+\249+\253+\t,\SI,\ETB,#,/,5,9,A,W,Y,i,w,\129,\135,\147,\159,\173,\179,\183,\203,\207,\219,\225,\227,\233,\239,\255,\a-\GS-\US-;-C-I-M-a-e-q-\137-\157-\161-\169-\179-\181-\197-\199-\211-\223-\SOH.\ETX.\a.\r.\EM.\US.%.-.3.7.9.?.W.[.o.y.\DEL.\133.\147.\151.\157.\163.\165.\177.\183.\193.\195.\205.\211.\231.\235.\ENQ/\t/\v/\DC1/'/)/A/E/K/M/Q/W/o/u/}/\129/\131/\165/\171/\179/\195/\207/\209/\219/\221/\231/\237/\245/\249/\SOH0\r0#0)070;0U0Y0[0g0q0y0}0\133\&0\145\&0\149\&0\163\&0\169\&0\185\&0\191\&0\199\&0\203\&0\209\&0\215\&0\223\&0\229\&0\239\&0\251\&0\253\&0\ETX1\t1\EM1!1'1-191C1E1K1]1a1g1m1s1\DEL1\145\&1\153\&1\159\&1\169\&1\177\&1\195\&1\199\&1\213\&1\219\&1\237\&1\247\&1\255\&1\t2\NAK2\ETB2\GS2)252Y2]2c2k2o2u2w2{2\141\&2\153\&2\159\&2\167\&2\173\&2\179\&2\183\&2\201\&2\203\&2\207\&2\209\&2\233\&2\237\&2\243\&2\249\&2\a3%3+3/353A3G3[3_3g3k3s3y3\DEL3\131\&3\161\&3\163\&3\173\&3\185\&3\193\&3\203\&3\211\&3\235\&3\241\&3\253\&3\SOH4\SI4\DC34\EM4\ESC474E4U4W4c4i4m4\129\&4\139\&4\145\&4\151\&4\157\&4\165\&4\175\&4\187\&4\201\&4\211\&4\225\&4\241\&4\255\&4\t5\ETB5\GS5-535;5A5Q5e5o5q5w5{5}5\129\&5\141\&5\143\&5\153\&5\155\&5\161\&5\183\&5\189\&5\191\&5\195\&5\213\&5\221\&5\231\&5\239\&5\ENQ6\a6\DC16#6165676;6M6O6S6Y6a6k6m6\139\&6\143\&6\173\&6\175\&6\185\&6\187\&6\205\&6\209\&6\227\&6\233\&6\247\&6\SOH7\ETX7\a7\ESC7?7E7I7O7]7a7u7\DEL7\141\&7\163\&7\169\&7\171\&7\201\&7\213\&7\223\&7\241\&7\243\&7\247\&7\ENQ8\v8!83858A8G8K8S8W8_8e8o8q8}8\143\&8\153\&8\167\&8\183\&8\197\&8\201\&8\207\&8\213\&8\215\&8\221\&8\225\&8\227\&8\255\&8\SOH9\GS9#9%9)9/9=9A9M9[9k9y9}9\131\&9\139\&9\145\&9\149\&9\155\&9\161\&9\167\&9\175\&9\179\&9\187\&9\191\&9\205\&9\221\&9\229\&9\235\&9\239\&9\251\&9\ETX:\DC3:\NAK:\US:':+:1:K:Q:[:c:g:m:y:\135:\165:\169:\183:\205:\213:\225:\229:\235:\243:\253:\ETX;\DC1;\ESC;!;#;-;9;E;S;Y;_;q;{;\129;\137;\155;\159;\165;\167;\173;\183;\185;\195;\203;\209;\215;\225;\227;\245;\255;\SOH<\r<\DC1<\ETB<\US<)<5\t>\SI>\DC1>\GS>#>)>/>3>A>W>c>e>w>\129>\135>\161>\185>\189>\191>\195>\197>\201>\215>\219>\225>\231>\239>\255>\v?\r?7?;?=?A?Y?_?e?g?y?}?\139?\145?\173?\191?\205?\211?\221?\233?\235?\241?\253?\ESC@!@%@+@1@?@C@E@]@a@g@m@\135@\145@\163@\169@\177@\183@\189@\219@\223@\235@\247@\249@\tA\vA\DC1A\NAKA!A3A5A;A?AYAeAkAwA{A\147A\171A\183A\189A\191A\203A\231A\239A\243A\249A\ENQB\aB\EMB\USB#B)B/BCBSBUB[BaBsB}B\131B\133B\137B\145B\151B\157B\181B\197B\203B\211B\221B\227B\241B\aC\SIC\USC%C'C3C7C9COCWCiC\139C\141C\147C\165C\169C\175C\181C\189C\199C\207C\225C\231C\235C\237C\241C\249C\tD\vD\ETBD#D)D;D?DEDKDQDSDYDeDoD\131D\143D\161D\165D\171D\173D\189D\191D\201D\215D\219D\249D\251D\ENQE\DC1E\DC3E+E1EAEIESEUEaEwE}E\DELE\143E\163E\173E\175E\187E\199E\217E\227E\239E\245E\247E\SOHF\ETXF\tF\DC3F%F'F3F9F=FCFEF]FyF{F\DELF\129F\139F\141F\157F\169F\177F\199F\201F\207F\211F\213F\223F\229F\249F\ENQG\SIG\ETBG#G)G/G5G9GKGMGQG]GoGqG}G\131G\135G\137G\153G\165G\177G\191G\195G\203G\221G\225G\237G\251G\SOHH\aH\vH\DC3H\EMH\GSH1H=HGHUHYH[HkHmHyH\151H\155H\161H\185H\205H\229H\239H\247H\ETXI\rI\EMI\USI+I7I=IEIUIcIiImIsI\151I\171I\181I\211I\223I\225I\229I\231I\ETXJ\SIJ\GSJ#J9JAJEJWJ]JkJ}J\129J\135J\137J\143J\177J\195J\197J\213J\219J\237J\239J\aK\vK\rK\DC3K\USK%K1K;KCKIKYKeKmKwK\133K\173K\179K\181K\187K\191K\203K\217K\221K\223K\227K\229K\233K\241K\247K\SOHL\aL\rL\SIL\NAKL\ESCL!L-L3LKLULWLaLgLsLyL\DELL\141L\147L\153L\205L\225L\231L\241L\243L\253L\ENQM\SIM\ESCM'M)M/M3MAMQMYMeMkM\129M\131M\141M\149M\155M\177M\179M\201M\207M\215M\225M\237M\249M\251M\ENQN\vN\ETBN\EMN\GSN+N5N7N=NONSN_NgNyN\133N\139N\145N\149N\155N\161N\175N\179N\181N\193N\205N\209N\215N\233N\251N\aO\tO\EMO%O-O?OIOcOgOmOuO{O\129O\133O\135O\145O\165O\169O\175O\183O\187O\207O\217O\219O\253O\255O\ETXP\ESCP\GSP)P5P?PEPGPSPqPwP\131P\147P\159P\161P\183P\201P\213P\227P\237P\239P\251P\aQ\vQ\rQ\DC1Q\ETBQ#Q%Q5QGQIQqQyQ\137Q\143Q\151Q\161Q\163Q\167Q\185Q\193Q\203Q\211Q\223Q\227Q\245Q\247Q\tR\DC3R\NAKR\EMR\ESCR\USR'RCRERKRaRmRsR\129R\147R\151R\157R\165R\171R\177R\187R\195R\199R\201R\219R\229R\235R\255R\NAKS\GSS#SASESGSKS]ScS\129S\131S\135S\143S\149S\153S\159S\171S\185S\219S\233S\239S\243S\245S\251S\255S\rT\DC1T\DC3T\EMT5T7T;TATITSTUT_TaTkTmTqT\143T\145T\157T\169T\179T\197T\209T\223T\233T\235T\247T\253T\aU\rU\ESCU'U+U9U=UOUQU[UcUgUoUyU\133U\151U\169U\177U\183U\201U\217U\231U\237U\243U\253U\vV\SIV\NAKV\ETBV#V/V3V9V?VKVMV]V_VkVqVuV\131V\137V\141V\143V\155V\173V\177V\213V\231V\243V\255V\SOHW\ENQW\aW\vW\DC3W\USW#WGWMW_WaWmWwW}W\137W\161W\169W\175W\181W\197W\209W\211W\229W\239W\ETXX\rX\SIX\NAKX'X+X-XUX[X]XmXoXsX{X\141X\151X\163X\169X\171X\181X\189X\193X\199X\211X\213X\223X\241X\249X\255X\ETXY\ETBY\ESCY!YEYKYMYWY]YuY{Y\137Y\153Y\159Y\177Y\179Y\189Y\209Y\219Y\227Y\233Y\237Y\243Y\245Y\255Y\SOHZ\rZ\DC1Z\DC3Z\ETBZ\USZ)Z/Z;ZMZ[ZgZwZ\DELZ\133Z\149Z\157Z\161Z\163Z\169Z\187Z\211Z\229Z\239Z\251Z\253Z\SOH[\SI[\EM[\US[%[+[=[I[K[g[y[\135[\151[\163[\177[\201[\213[\235[\241[\243[\253[\ENQ\\\t\\\v\\\SI\\\GS\\)\\/\\3\\9\\G\\K\\M\\Q\\o\\u\\w\\}\\\135\\\137\\\167\\\189\\\191\\\195\\\201\\\209\\\215\\\221\\\237\\\249\\\ENQ]\v]\DC3]\ETB]\EM]1]=]A]G]O]U][]e]g]m]y]\149]\163]\169]\173]\185]\193]\199]\211]\215]\221]\235]\241]\253]\a^\r^\DC3^\ESC^!^'^+^-^1^9^E^I^W^i^s^u^\133^\139^\159^\165^\175^\183^\187^\217^\253^\t_\DC1_'_3_5_;_G_W_]_c_e_w_{_\149_\153_\161_\179_\189_\197_\207_\213_\227_\231_\251_\DC1`#`/`7`S`_`e`k`s`y`\133`\157`\173`\187`\191`\205`\217`\223`\233`\245`\ta\SIa\DC3a\ESCa-a9aKaUaWa[aoaya\135a\139a\145a\147a\157a\181a\199a\201a\205a\225a\241a\255a\tb\ETBb\GSb!b'b;bAbKbQbSb_beb\131b\141b\149b\155b\159b\165b\173b\213b\215b\219b\221b\233b\251b\255b\ENQc\rc\ETBc\GSc/cAcCcOc_cgcmcqcwc}c\DELc\179c\193c\197c\217c\233c\235c\239c\245c\SOHd\ETXd\td\NAKd!d'd+d9dCdIdOd]dgdud\133d\141d\147d\159d\163d\171d\193d\199d\201d\219d\241d\247d\249d\ve\DC1e!e/e9e?eKeMeSeWe_eqe}e\141e\143e\147e\161e\165e\173e\185e\197e\227e\243e\251e\255e\SOHf\af\GSf)f1f;fAfGfMf[fafsf}f\137f\139f\149f\151f\155f\181f\185f\197f\205f\209f\227f\235f\245f\ETXg\DC3g\EMg\USg'g1g7g?gEgQg[gogyg\129g\133g\145g\171g\189g\193g\205g\223g\229g\ETXh\th\DC1h\ETBh-h9h;h?hEhKhMhWhYh]hchihkhqh\135h\153h\159h\177h\189h\197h\209h\215h\225h\237h\239h\255h\SOHi\vi\ri\ETBi)i/iCiGiIiOieikiqi\131i\137i\151i\163i\179i\181i\187i\193i\197i\211i\223i\227i\229i\247i\aj+j7j=jKjgjijuj{j\135j\141j\145j\147j\163j\193j\201j\225j\231j\ENQk\SIk\DC1k#k'k-k9kAkWkYk_kuk\135k\137k\147k\149k\159k\189k\191k\219k\225k\239k\255k\ENQl\EMl)l+l1l5lUlYl[l_lelglslwl}l\131l\143l\145l\151l\155l\161l\169l\175l\179l\199l\203l\235l\245l\253l\rm\SIm%m'm+m1m9m?mOm]mamsm{m\DELm\147m\153m\165m\177m\183m\193m\195m\205m\207m\219m\247m\ETXn\NAKn\ETBn)n3n;nEnunwn{n\129n\137n\147n\149n\159n\189n\191n\227n\233n\243n\249n\251n\ro\DC1o\ETBo\USo/o=oMoSoaoeoyo}o\131o\133o\143o\155o\157o\163o\175o\181o\187o\191o\203o\205o\211o\215o\227o\233o\241o\245o\247o\253o\SIp\EMp\USp'p3p9pOpQpWpcpupyp\135p\141p\145p\165p\171p\187p\195p\199p\207p\229p\237p\249p\255p\ENQq\NAKq!q3qQqYq]q_qcqiq\131q\135q\149q\173q\195q\201q\203q\209q\219q\225q\239q\245q\251q\ar\DC1r\ETBr\EMr%r/r;rCrUrgrqrwr\DELr\143r\149r\155r\163r\179r\199r\203r\205r\215r\217r\227r\239r\245r\253r\ETXs\rs!s+s=sWs[sas\DELs\129s\133s\141s\147s\159s\171s\189s\193s\201s\223s\229s\231s\243s\NAKt\ESCt-t9t?tAt]tkt{t\137t\141t\155t\167t\171t\177t\183t\185t\221t\225t\231t\251t\au\USu%u;u=uMu_ukuwu\137u\139u\145u\151u\157u\161u\167u\181u\185u\187u\209u\217u\229u\235u\245u\251u\ETXv\SIv!v-v3v=v?vUvcvivovsv\133v\139v\159v\181v\183v\195v\219v\223v\241v\ETXw\ENQw\ESCw\GSw!w-w5wAwKwYw]w_wqw\129w\167w\173w\179w\185w\197w\207w\213w\225w\233w\239w\243w\249w\ax%x+x5x=xSxYxaxmxwxyx\131x\133x\139x\149x\151x\161x\173x\191x\211x\217x\221x\229x\251x\SOHy\ay%y+y9y?yKyWy]ygyiysy\145y\147y\163y\171y\175y\177y\183y\201y\205y\207y\213y\217y\243y\247y\255y\ENQz\SIz\DC1z\NAKz\ESCz#z'z-zKzWzYz_zeziz}z\147z\155z\159z\161z\165z\237z\245z\249z\SOH{\ETB{\EM{\GS{+{5{7{;{O{U{_{q{w{\139{\155{\161{\169{\175{\179{\199{\211{\233{\235{\239{\241{\253{\a|\EM|\ESC|1|7|I|g|i|s|\129|\139|\147|\163|\213|\219|\229|\237|\247|\ETX}\t}\ESC}\GS}3}9};}?}E}M}S}Y}c}u}w}\141}\143}\159}\173}\183}\189}\191}\203}\213}\233}\237}\251}\SOH~\ENQ~)~+~/~5~A~C~G~U~a~g~k~q~s~y~}~\145~\155~\157~\167~\173~\185~\187~\211~\223~\235~\241~\247~\251~\DC3\DEL\NAK\DEL\EM\DEL1\DEL3\DEL9\DEL=\DELC\DELK\DEL[\DELa\DELc\DELm\DELy\DEL\135\DEL\141\DEL\175\DEL\181\DEL\195\DEL\201\DEL\205\DEL\207\DEL\237\DEL\ETX\128\v\128\SI\128\NAK\128\GS\128!\128#\128?\128A\128G\128K\128e\128w\128\141\128\143\128\149\128\165\128\171\128\173\128\189\128\201\128\203\128\215\128\219\128\225\128\231\128\245\128\255\128\ENQ\129\r\129\EM\129\GS\129/\129\&1\129;\129C\129S\129Y\129_\129}\129\DEL\129\137\129\155\129\157\129\167\129\175\129\179\129\187\129\199\129\223\129\a\130\t\130\NAK\130\US\130%\130\&1\130\&3\130?\130C\130E\130I\130O\130a\130o\130{\130\129\130\133\130\147\130\177\130\181\130\189\130\199\130\207\130\213\130\223\130\241\130\249\130\253\130\v\131\ESC\131!\131)\131-\131\&3\131\&5\131?\131A\131M\131Q\131S\131W\131]\131e\131i\131o\131\143\131\167\131\177\131\185\131\203\131\213\131\215\131\221\131\231\131\233\131\237\131\255\131\ENQ\132\DC1\132\DC3\132#\132%\132;\132A\132G\132O\132a\132e\132w\132\131\132\139\132\145\132\149\132\169\132\175\132\205\132\227\132\239\132\241\132\247\132\t\133\r\133K\133O\133Q\133]\133c\133m\133o\133{\133\135\133\163\133\165\133\169\133\183\133\205\133\211\133\213\133\219\133\225\133\235\133\249\133\253\133\255\133\t\134\SI\134\ETB\134!\134/\134\&9\134?\134A\134M\134c\134u\134}\134\135\134\153\134\165\134\167\134\179\134\183\134\195\134\197\134\207\134\209\134\215\134\233\134\239\134\245\134\ETB\135\GS\135\US\135+\135/\135\&5\135G\135Y\135[\135k\135q\135w\135\DEL\135\133\135\143\135\161\135\169\135\179\135\187\135\197\135\199\135\203\135\221\135\247\135\ETX\136\EM\136\ESC\136\US\136!\136\&7\136=\136C\136Q\136a\136g\136{\136\133\136\145\136\147\136\165\136\207\136\211\136\235\136\237\136\243\136\253\136\t\137\v\137\DC1\137\ESC\137#\137'\137-\137\&9\137E\137M\137Q\137W\137c\137\129\137\149\137\155\137\179\137\185\137\195\137\207\137\209\137\219\137\239\137\245\137\251\137\255\137\v\138\EM\138#\138\&5\138A\138I\138O\138[\138_\138m\138w\138y\138\133\138\163\138\179\138\181\138\193\138\199\138\203\138\205\138\209\138\215\138\241\138\245\138\a\139\t\139\r\139\DC3\139!\139W\139]\139\145\139\147\139\163\139\169\139\175\139\187\139\213\139\217\139\219\139\225\139\247\139\253\139\255\139\v\140\ETB\140\GS\140'\140\&9\140;\140G\140S\140]\140o\140{\140\129\140\137\140\143\140\153\140\159\140\167\140\171\140\173\140\177\140\197\140\221\140\227\140\233\140\243\140\SOH\141\v\141\r\141#\141)\141\&7\141A\141[\141_\141q\141y\141\133\141\145\141\155\141\167\141\173\141\181\141\197\141\203\141\211\141\217\141\223\141\245\141\247\141\SOH\142\NAK\142\US\142%\142Q\142c\142i\142s\142u\142y\142\DEL\142\141\142\145\142\171\142\175\142\177\142\189\142\199\142\207\142\211\142\219\142\231\142\235\142\247\142\255\142\NAK\143\GS\143#\143-\143?\143E\143K\143S\143Y\143e\143i\143q\143\131\143\141\143\153\143\159\143\171\143\173\143\179\143\183\143\185\143\201\143\213\143\225\143\239\143\249\143\a\144\r\144\ETB\144#\144%\144\&1\144\&7\144;\144A\144C\144O\144S\144m\144s\144\133\144\139\144\149\144\155\144\157\144\175\144\185\144\193\144\197\144\223\144\233\144\253\144\ETX\145\DC3\145'\145\&3\145=\145E\145O\145Q\145a\145g\145{\145\133\145\153\145\157\145\187\145\189\145\193\145\201\145\217\145\219\145\237\145\241\145\243\145\249\145\ETX\146\NAK\146!\146/\146A\146G\146W\146k\146q\146u\146}\146\131\146\135\146\141\146\153\146\161\146\171\146\173\146\185\146\191\146\195\146\197\146\203\146\213\146\215\146\231\146\243\146\SOH\147\v\147\DC1\147\EM\147\US\147;\147=\147C\147U\147s\147\149\147\151\147\167\147\179\147\181\147\199\147\215\147\221\147\229\147\239\147\247\147\SOH\148\t\148\DC3\148?\148E\148K\148O\148c\148g\148i\148m\148{\148\151\148\159\148\165\148\181\148\195\148\225\148\231\148\ENQ\149\t\149\ETB\149!\149'\149-\149\&5\149\&9\149K\149W\149]\149_\149u\149\129\149\137\149\143\149\155\149\159\149\173\149\177\149\183\149\185\149\189\149\207\149\227\149\233\149\249\149\US\150/\150\&1\150\&5\150;\150=\150e\150\143\150\157\150\161\150\167\150\169\150\193\150\203\150\209\150\211\150\229\150\239\150\251\150\253\150\r\151\SI\151\NAK\151%\151+\151\&3\151\&7\151\&9\151C\151I\151Q\151[\151]\151o\151\DEL\151\135\151\147\151\165\151\177\151\183\151\195\151\205\151\211\151\217\151\235\151\247\151\ENQ\152\t\152\v\152\NAK\152)\152/\152;\152A\152Q\152k\152o\152\129\152\131\152\135\152\167\152\177\152\185\152\191\152\195\152\201\152\207\152\221\152\227\152\245\152\249\152\251\152\r\153\ETB\153\US\153)\153\&1\153;\153=\153A\153G\153I\153S\153}\153\133\153\145\153\149\153\155\153\173\153\175\153\191\153\199\153\203\153\205\153\215\153\229\153\241\153\251\153\SI\154\DC3\154\ESC\154%\154K\154O\154U\154W\154a\154u\154\DEL\154\139\154\145\154\157\154\183\154\195\154\199\154\207\154\235\154\243\154\247\154\255\154\ETB\155\GS\155'\155/\155\&5\155E\155Q\155Y\155c\155o\155w\155\141\155\147\155\149\155\159\155\161\155\167\155\177\155\183\155\189\155\197\155\203\155\207\155\221\155\249\155\SOH\156\DC1\156#\156+\156/\156\&5\156I\156M\156_\156e\156g\156\DEL\156\151\156\157\156\163\156\175\156\187\156\191\156\193\156\215\156\217\156\227\156\233\156\241\156\253\156\SOH\157\NAK\157'\157-\157\&1\157=\157U\157[\157a\157\151\157\159\157\165\157\169\157\195\157\231\157\235\157\237\157\241\157\v\158\ETB\158#\158'\158-\158\&3\158;\158G\158Q\158S\158_\158o\158\129\158\135\158\143\158\149\158\161\158\179\158\189\158\191\158\245\158\249\158\251\158\ENQ\159#\159/\159\&7\159;\159C\159S\159a\159m\159s\159w\159}\159\137\159\143\159\145\159\149\159\163\159\175\159\179\159\193\159\199\159\223\159\229\159\235\159\245\159\SOH\160\r\160!\160\&3\160\&9\160?\160O\160W\160[\160a\160u\160y\160\153\160\157\160\171\160\181\160\183\160\189\160\201\160\217\160\219\160\223\160\229\160\241\160\243\160\253\160\ENQ\161\v\161\SI\161\DC1\161\ESC\161)\161/\161\&5\161A\161S\161u\161}\161\135\161\141\161\165\161\171\161\173\161\183\161\195\161\197\161\227\161\237\161\251\161\a\162\DC3\162#\162)\162/\162\&1\162C\162G\162M\162k\162y\162}\162\131\162\137\162\139\162\145\162\149\162\155\162\169\162\175\162\179\162\187\162\197\162\209\162\215\162\247\162\SOH\163\t\163\US\163!\163+\163\&1\163I\163Q\163U\163s\163y\163{\163\135\163\151\163\159\163\165\163\169\163\175\163\183\163\199\163\213\163\219\163\225\163\229\163\231\163\241\163\253\163\255\163\SI\164\GS\164!\164#\164'\164;\164M\164W\164Y\164c\164i\164u\164\147\164\155\164\173\164\185\164\195\164\197\164\203\164\209\164\213\164\225\164\237\164\239\164\243\164\255\164\DC1\165)\165+\165\&5\165;\165C\165S\165[\165a\165m\165w\165\133\165\139\165\151\165\157\165\163\165\167\165\169\165\193\165\197\165\203\165\211\165\217\165\221\165\223\165\227\165\233\165\247\165\251\165\ETX\166\r\166%\166=\166I\166K\166Q\166]\166s\166\145\166\147\166\153\166\171\166\181\166\187\166\193\166\201\166\205\166\207\166\213\166\223\166\231\166\241\166\247\166\255\166\SI\167\NAK\167#\167)\167-\167E\167M\167W\167Y\167e\167k\167o\167\147\167\149\167\171\167\177\167\185\167\191\167\201\167\209\167\215\167\227\167\237\167\251\167\ENQ\168\v\168\GS\168)\168+\168\&7\168;\168U\168_\168m\168}\168\143\168\151\168\169\168\181\168\193\168\199\168\215\168\229\168\253\168\a\169\DC3\169\ESC\169\&1\169\&7\169\&9\169C\169\DEL\169\133\169\135\169\139\169\147\169\163\169\177\169\187\169\193\169\217\169\223\169\235\169\253\169\NAK\170\ETB\170\&5\170\&9\170;\170G\170M\170W\170Y\170]\170k\170q\170\129\170\131\170\141\170\149\170\171\170\191\170\197\170\201\170\233\170\239\170\SOH\171\ENQ\171\a\171\v\171\r\171\DC1\171\EM\171M\171[\171q\171s\171\137\171\157\171\167\171\175\171\185\171\187\171\193\171\197\171\211\171\215\171\221\171\241\171\245\171\251\171\253\171\t\172\NAK\172\ESC\172'\172\&7\172\&9\172E\172O\172W\172[\172a\172c\172\DEL\172\139\172\147\172\157\172\169\172\171\172\175\172\189\172\217\172\225\172\231\172\235\172\237\172\241\172\247\172\249\172\ENQ\173?\173E\173S\173]\173_\173e\173\129\173\161\173\165\173\195\173\203\173\209\173\213\173\219\173\231\173\243\173\245\173\249\173\255\173\ENQ\174\DC3\174#\174+\174I\174M\174O\174Y\174a\174g\174k\174q\174\139\174\143\174\155\174\157\174\167\174\185\174\197\174\209\174\227\174\229\174\233\174\245\174\253\174\t\175\DC3\175'\175+\175\&3\175C\175O\175W\175]\175m\175u\175\DEL\175\139\175\153\175\159\175\163\175\171\175\183\175\187\175\207\175\213\175\253\175\ENQ\176\NAK\176\ESC\176?\176A\176G\176K\176Q\176S\176i\176{\176}\176\135\176\141\176\177\176\191\176\203\176\207\176\225\176\233\176\237\176\251\176\ENQ\177\a\177\DC1\177\EM\177\GS\177\US\177\&1\177A\177M\177[\177e\177s\177y\177\DEL\177\169\177\179\177\185\177\191\177\211\177\221\177\229\177\241\177\245\177\SOH\178\DC3\178\NAK\178\US\178-\178?\178I\178[\178c\178i\178m\178{\178\129\178\139\178\169\178\183\178\189\178\195\178\199\178\211\178\249\178\253\178\255\178\ETX\179\t\179\DC1\179\GS\179'\179-\179?\179E\179w\179}\179\129\179\135\179\147\179\155\179\165\179\197\179\203\179\225\179\227\179\237\179\249\179\v\180\r\180\DC3\180\ETB\180\&5\180=\180C\180I\180[\180e\180g\180k\180w\180\139\180\149\180\157\180\181\180\191\180\193\180\199\180\221\180\227\180\229\180\247\180\SOH\181\r\181\SI\181-\181?\181K\181g\181i\181o\181s\181y\181\135\181\141\181\153\181\163\181\171\181\175\181\187\181\213\181\223\181\231\181\237\181\253\181\255\181\t\182\ESC\182)\182/\182\&3\182\&9\182G\182W\182Y\182_\182c\182o\182\131\182\135\182\155\182\159\182\165\182\177\182\179\182\215\182\219\182\225\182\227\182\237\182\239\182\ENQ\183\r\183\DC3\183\GS\183)\183\&5\183G\183U\183m\183\145\183\149\183\169\183\193\183\203\183\209\183\211\183\239\183\245\183\a\184\SI\184\DC3\184\EM\184!\184'\184+\184-\184\&9\184U\184g\184u\184\133\184\147\184\165\184\175\184\183\184\189\184\193\184\199\184\205\184\213\184\235\184\247\184\249\184\ETX\185\NAK\185\ESC\185\GS\185/\185\&9\185;\185G\185Q\185c\185\131\185\137\185\141\185\147\185\153\185\161\185\167\185\173\185\183\185\203\185\209\185\221\185\231\185\239\185\249\185\a\186\r\186\ETB\186%\186)\186+\186A\186S\186U\186_\186a\186e\186y\186}\186\DEL\186\161\186\163\186\175\186\181\186\191\186\193\186\203\186\221\186\227\186\241\186\253\186\t\187\US\187'\187-\187=\187C\187K\187O\187[\187a\187i\187m\187\145\187\151\187\157\187\177\187\201\187\207\187\219\187\237\187\247\187\249\187\ETX\188\GS\188#\188\&3\188;\188A\188E\188]\188o\188w\188\131\188\143\188\153\188\171\188\183\188\185\188\209\188\213\188\225\188\243\188\255\188\r\189\ETB\189\EM\189\GS\189\&5\189A\189O\189Y\189_\189a\189g\189k\189q\189\139\189\143\189\149\189\155\189\157\189\179\189\187\189\205\189\209\189\227\189\235\189\239\189\a\190\t\190\NAK\190!\190%\190'\190[\190]\190o\190u\190y\190\DEL\190\139\190\141\190\147\190\159\190\169\190\177\190\181\190\183\190\207\190\217\190\219\190\229\190\231\190\243\190\249\190\v\191\&3\191\&9\191M\191]\191_\191k\191q\191{\191\135\191\137\191\141\191\147\191\161\191\173\191\185\191\207\191\213\191\221\191\225\191\227\191\243\191\ENQ\192\DC1\192\DC3\192\EM\192)\192/\192\&1\192\&7\192;\192G\192e\192m\192}\192\DEL\192\145\192\155\192\179\192\181\192\187\192\211\192\215\192\217\192\239\192\241\192\SOH\193\ETX\193\t\193\NAK\193\EM\193+\193\&3\193\&7\193E\193I\193[\193s\193y\193{\193\129\193\139\193\141\193\151\193\189\193\195\193\205\193\219\193\225\193\231\193\255\193\ETX\194\ENQ\194\DC1\194!\194/\194?\194K\194M\194S\194]\194w\194{\194}\194\137\194\143\194\147\194\159\194\167\194\179\194\189\194\207\194\213\194\227\194\255\194\SOH\195\a\195\DC1\195\DC3\195\ETB\195%\195G\195I\195O\195e\195g\195q\195\DEL\195\131\195\133\195\149\195\157\195\167\195\173\195\181\195\191\195\199\195\203\195\209\195\211\195\227\195\233\195\239\195\SOH\196\US\196-\196\&3\196\&7\196U\196W\196a\196o\196s\196\135\196\145\196\153\196\157\196\165\196\183\196\187\196\201\196\207\196\211\196\235\196\241\196\247\196\t\197\ESC\197\GS\197A\197G\197Q\197_\197k\197o\197u\197w\197\149\197\155\197\159\197\161\197\167\197\195\197\215\197\219\197\239\197\251\197\DC3\198#\198\&5\198A\198O\198U\198Y\198e\198\133\198\145\198\151\198\161\198\169\198\179\198\185\198\203\198\205\198\221\198\235\198\241\198\a\199\r\199\EM\199\ESC\199-\199\&1\199\&9\199W\199c\199g\199s\199u\199\DEL\199\165\199\187\199\189\199\193\199\207\199\213\199\225\199\249\199\253\199\255\199\ETX\200\DC1\200\GS\200'\200)\200\&9\200?\200S\200W\200k\200\129\200\141\200\143\200\147\200\149\200\161\200\183\200\207\200\213\200\219\200\221\200\227\200\231\200\237\200\239\200\249\200\ENQ\201\DC1\201\ETB\201\EM\201\US\201/\201\&7\201=\201A\201S\201_\201k\201y\201}\201\137\201\143\201\151\201\157\201\175\201\181\201\191\201\203\201\217\201\223\201\227\201\235\201\SOH\202\a\202\t\202%\202\&7\202\&9\202K\202U\202[\202i\202s\202u\202\DEL\202\141\202\147\202\157\202\159\202\181\202\187\202\195\202\201\202\217\202\229\202\237\202\ETX\203\ENQ\203\t\203\ETB\203)\203\&5\203;\203S\203Y\203c\203e\203q\203\135\203\153\203\159\203\179\203\185\203\195\203\209\203\213\203\215\203\221\203\233\203\255\203\r\204\EM\204\GS\204#\204+\204A\204C\204M\204Y\204a\204\137\204\139\204\145\204\155\204\163\204\167\204\209\204\229\204\233\204\t\205\NAK\205\US\205%\205\&1\205=\205?\205I\205Q\205W\205[\205c\205g\205\129\205\147\205\151\205\159\205\187\205\193\205\211\205\217\205\229\205\231\205\241\205\247\205\253\205\v\206\NAK\206!\206/\206G\206M\206Q\206e\206{\206}\206\143\206\147\206\153\206\165\206\167\206\183\206\201\206\215\206\221\206\227\206\231\206\237\206\245\206\a\207\v\207\EM\207\&7\207;\207M\207U\207_\207a\207e\207m\207y\207}\207\137\207\155\207\157\207\169\207\179\207\181\207\197\207\205\207\209\207\239\207\241\207\247\207\DC3\208\NAK\208\US\208!\208\&3\208=\208K\208O\208i\208o\208\129\208\133\208\153\208\159\208\163\208\171\208\189\208\193\208\205\208\231\208\255\208\ETX\209\ETB\209-\209/\209A\209W\209Y\209]\209i\209k\209q\209w\209}\209\129\209\135\209\149\209\153\209\177\209\189\209\195\209\213\209\215\209\227\209\255\209\r\210\DC1\210\ETB\210\US\210\&5\210;\210G\210Y\210a\210e\210y\210\DEL\210\131\210\137\210\139\210\157\210\163\210\167\210\179\210\191\210\199\210\227\210\233\210\241\210\251\210\253\210\NAK\211!\211+\211C\211K\211U\211i\211u\211{\211\135\211\147\211\151\211\165\211\177\211\201\211\235\211\253\211\ENQ\212\SI\212\NAK\212'\212/\212\&3\212;\212K\212Y\212_\212c\212i\212\129\212\131\212\137\212\141\212\147\212\149\212\165\212\171\212\177\212\197\212\221\212\225\212\227\212\231\212\245\212\249\212\v\213\r\213\DC3\213\US\213#\213\&1\213\&5\213\&7\213I\213Y\213_\213e\213g\213w\213\139\213\145\213\151\213\181\213\185\213\193\213\199\213\223\213\239\213\245\213\251\213\ETX\214\SI\214-\214\&1\214C\214U\214]\214a\214{\214\133\214\135\214\157\214\165\214\175\214\189\214\195\214\199\214\217\214\225\214\237\214\t\215\v\215\DC1\215\NAK\215!\215'\215?\215E\215M\215W\215k\215{\215\131\215\161\215\167\215\173\215\177\215\179\215\189\215\203\215\209\215\219\215\251\215\DC1\216#\216%\216)\216+\216/\216\&7\216M\216U\216g\216s\216\143\216\145\216\161\216\173\216\191\216\205\216\215\216\233\216\245\216\251\216\ESC\217%\217\&3\217\&9\217C\217E\217O\217Q\217W\217m\217o\217s\217y\217\129\217\139\217\145\217\159\217\165\217\169\217\181\217\211\217\235\217\241\217\247\217\255\217\ENQ\218\t\218\v\218\SI\218\NAK\218\GS\218#\218)\218?\218Q\218Y\218]\218_\218q\218w\218{\218}\218\141\218\159\218\179\218\189\218\195\218\201\218\231\218\233\218\245\218\DC1\219\ETB\219\GS\219#\219%\219\&1\219;\219C\219U\219g\219k\219s\219\133\219\143\219\145\219\173\219\175\219\185\219\199\219\203\219\205\219\235\219\247\219\r\220'\220\&1\220\&9\220?\220I\220Q\220a\220o\220u\220{\220\133\220\147\220\153\220\157\220\159\220\169\220\181\220\183\220\189\220\199\220\207\220\211\220\213\220\223\220\249\220\SI\221\NAK\221\ETB\221#\221\&5\221\&9\221S\221W\221_\221i\221o\221}\221\135\221\137\221\155\221\161\221\171\221\191\221\197\221\203\221\207\221\231\221\233\221\237\221\245\221\251\221\v\222\EM\222)\222;\222=\222A\222M\222O\222Y\222[\222a\222m\222w\222}\222\131\222\151\222\157\222\161\222\167\222\205\222\209\222\215\222\227\222\241\222\245\222\SOH\223\t\223\DC3\223\US\223+\223\&3\223\&7\223=\223K\223U\223[\223g\223i\223s\223\133\223\135\223\153\223\163\223\171\223\181\223\183\223\195\223\199\223\213\223\241\223\243\223\ETX\224\ENQ\224\ETB\224\GS\224'\224-\224\&5\224E\224S\224q\224{\224\143\224\149\224\159\224\183\224\185\224\213\224\215\224\227\224\243\224\249\224\SOH\225%\225)\225\&1\225\&5\225C\225O\225Y\225a\225m\225q\225w\225\DEL\225\131\225\137\225\151\225\173\225\181\225\187\225\191\225\193\225\203\225\209\225\229\225\239\225\247\225\253\225\ETX\226\EM\226+\226-\226=\226C\226W\226[\226u\226y\226\135\226\157\226\171\226\175\226\187\226\193\226\201\226\205\226\211\226\217\226\243\226\253\226\255\226\DC1\227#\227'\227)\227\&9\227;\227M\227Q\227W\227_\227c\227i\227u\227w\227}\227\131\227\159\227\197\227\201\227\209\227\225\227\251\227\255\227\SOH\228\v\228\ETB\228\EM\228#\228+\228\&1\228;\228G\228I\228S\228U\228m\228q\228\143\228\169\228\175\228\181\228\199\228\205\228\211\228\233\228\235\228\245\228\a\229!\229%\229\&7\229?\229E\229K\229W\229g\229m\229u\229\133\229\139\229\147\229\163\229\165\229\207\229\t\230\DC1\230\NAK\230\ESC\230\GS\230!\230)\230\&9\230?\230S\230W\230c\230o\230u\230\129\230\131\230\141\230\143\230\149\230\171\230\173\230\183\230\189\230\197\230\203\230\213\230\227\230\233\230\239\230\243\230\ENQ\231\r\231\ETB\231\US\231/\231=\231G\231I\231S\231U\231a\231g\231k\231\DEL\231\137\231\145\231\197\231\205\231\215\231\221\231\223\231\233\231\241\231\251\231\SOH\232\a\232\SI\232\EM\232\ESC\232\&1\232\&3\232\&7\232=\232K\232O\232Q\232i\232u\232y\232\147\232\165\232\169\232\175\232\189\232\219\232\225\232\229\232\235\232\237\232\ETX\233\v\233\SI\233\NAK\233\ETB\233-\233\&3\233;\233K\233Q\233_\233c\233i\233{\233\131\233\143\233\149\233\161\233\185\233\215\233\231\233\239\233\DC1\234\EM\234/\234\&5\234C\234M\234_\234m\234q\234}\234\133\234\137\234\173\234\179\234\185\234\187\234\197\234\199\234\203\234\223\234\229\234\235\234\245\234\SOH\235\a\235\t\235\&1\235\&9\235?\235[\235a\235c\235o\235\129\235\133\235\157\235\171\235\177\235\183\235\193\235\213\235\223\235\237\235\253\235\v\236\ESC\236!\236)\236M\236Q\236]\236i\236o\236{\236\173\236\185\236\191\236\195\236\201\236\207\236\215\236\221\236\231\236\233\236\243\236\245\236\a\237\DC1\237\US\237/\237\&7\237=\237A\237U\237Y\237[\237e\237k\237y\237\139\237\149\237\187\237\197\237\215\237\217\237\227\237\229\237\241\237\245\237\247\237\251\237\t\238\SI\238\EM\238!\238I\238O\238c\238g\238s\238{\238\129\238\163\238\171\238\193\238\201\238\213\238\223\238\225\238\241\238\ESC\239'\239/\239E\239M\239c\239k\239q\239\147\239\149\239\155\239\159\239\173\239\179\239\195\239\197\239\219\239\225\239\233\239\SOH\240\ETB\240\GS\240\US\240+\240/\240\&5\240C\240G\240O\240g\240k\240q\240w\240y\240\143\240\163\240\169\240\173\240\187\240\191\240\197\240\203\240\211\240\217\240\227\240\233\240\241\240\247\240\a\241\NAK\241\ESC\241!\241\&7\241=\241U\241u\241{\241\141\241\147\241\165\241\175\241\183\241\213\241\231\241\237\241\253\241\t\242\SI\242\ESC\242\GS\242#\242'\242\&3\242;\242A\242W\242_\242e\242i\242w\242\129\242\147\242\167\242\177\242\179\242\185\242\189\242\191\242\219\242\237\242\239\242\249\242\255\242\ENQ\243\v\243\EM\243A\243Y\243[\243_\243g\243s\243w\243\139\243\143\243\175\243\193\243\209\243\215\243\251\243\ETX\244\t\244\r\244\DC3\244!\244%\244+\244E\244K\244U\244c\244u\244\DEL\244\133\244\139\244\153\244\163\244\169\244\175\244\189\244\195\244\219\244\223\244\237\244\ETX\245\v\245\ETB\245!\245)\245\&5\245G\245Q\245c\245k\245\131\245\141\245\149\245\153\245\177\245\183\245\201\245\207\245\209\245\219\245\249\245\251\245\ENQ\246\a\246\v\246\r\246\&5\246\&7\246S\246[\246a\246g\246y\246\DEL\246\137\246\151\246\155\246\173\246\203\246\221\246\223\246\235\246\t\247\SI\247-\247\&1\247C\247O\247Q\247U\247c\247i\247s\247y\247\129\247\135\247\145\247\157\247\159\247\165\247\177\247\187\247\189\247\207\247\211\247\231\247\235\247\241\247\255\247\ENQ\248\v\248!\248'\248-\248\&5\248G\248Y\248c\248e\248o\248q\248w\248{\248\129\248\141\248\159\248\161\248\171\248\179\248\183\248\201\248\203\248\209\248\215\248\221\248\231\248\239\248\249\248\255\248\DC1\249\GS\249%\249\&1\249\&7\249;\249A\249O\249_\249a\249m\249q\249w\249\157\249\163\249\169\249\185\249\205\249\233\249\253\249\a\250\r\250\DC3\250!\250%\250?\250C\250Q\250[\250m\250{\250\151\250\153\250\157\250\171\250\187\250\189\250\217\250\223\250\231\250\237\250\SI\251\ETB\251\ESC\251-\251/\251?\251G\251M\251u\251}\251\143\251\147\251\177\251\183\251\195\251\197\251\227\251\233\251\243\251\SOH\252)\252\&7\252A\252C\252O\252Y\252a\252e\252m\252s\252y\252\149\252\151\252\155\252\167\252\181\252\197\252\205\252\235\252\251\252\r\253\SI\253\EM\253+\253\&1\253Q\253U\253g\253m\253o\253{\253\133\253\151\253\153\253\159\253\169\253\183\253\201\253\229\253\235\253\243\253\ETX\254\ENQ\254\t\254\GS\254'\254/\254A\254K\254M\254W\254_\254c\254i\254u\254{\254\143\254\147\254\149\254\155\254\159\254\179\254\189\254\215\254\233\254\243\254\245\254\a\255\r\255\GS\255+\255/\255I\255M\255[\255e\255q\255\DEL\255\133\255\139\255\143\255\157\255\167\255\169\255\199\255\217\255\239\255\241\255"# -- smallPrimes :: [Word16] -- smallPrimes = -- [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997,1009,1013,1019,1021,1031,1033,1039,1049,1051,1061,1063,1069,1087,1091,1093,1097,1103,1109,1117,1123,1129,1151,1153,1163,1171,1181,1187,1193,1201,1213,1217,1223,1229,1231,1237,1249,1259,1277,1279,1283,1289,1291,1297,1301,1303,1307,1319,1321,1327,1361,1367,1373,1381,1399,1409,1423,1427,1429,1433,1439,1447,1451,1453,1459,1471,1481,1483,1487,1489,1493,1499,1511,1523,1531,1543,1549,1553,1559,1567,1571,1579,1583,1597,1601,1607,1609,1613,1619,1621,1627,1637,1657,1663,1667,1669,1693,1697,1699,1709,1721,1723,1733,1741,1747,1753,1759,1777,1783,1787,1789,1801,1811,1823,1831,1847,1861,1867,1871,1873,1877,1879,1889,1901,1907,1913,1931,1933,1949,1951,1973,1979,1987,1993,1997,1999,2003,2011,2017,2027,2029,2039,2053,2063,2069,2081,2083,2087,2089,2099,2111,2113,2129,2131,2137,2141,2143,2153,2161,2179,2203,2207,2213,2221,2237,2239,2243,2251,2267,2269,2273,2281,2287,2293,2297,2309,2311,2333,2339,2341,2347,2351,2357,2371,2377,2381,2383,2389,2393,2399,2411,2417,2423,2437,2441,2447,2459,2467,2473,2477,2503,2521,2531,2539,2543,2549,2551,2557,2579,2591,2593,2609,2617,2621,2633,2647,2657,2659,2663,2671,2677,2683,2687,2689,2693,2699,2707,2711,2713,2719,2729,2731,2741,2749,2753,2767,2777,2789,2791,2797,2801,2803,2819,2833,2837,2843,2851,2857,2861,2879,2887,2897,2903,2909,2917,2927,2939,2953,2957,2963,2969,2971,2999,3001,3011,3019,3023,3037,3041,3049,3061,3067,3079,3083,3089,3109,3119,3121,3137,3163,3167,3169,3181,3187,3191,3203,3209,3217,3221,3229,3251,3253,3257,3259,3271,3299,3301,3307,3313,3319,3323,3329,3331,3343,3347,3359,3361,3371,3373,3389,3391,3407,3413,3433,3449,3457,3461,3463,3467,3469,3491,3499,3511,3517,3527,3529,3533,3539,3541,3547,3557,3559,3571,3581,3583,3593,3607,3613,3617,3623,3631,3637,3643,3659,3671,3673,3677,3691,3697,3701,3709,3719,3727,3733,3739,3761,3767,3769,3779,3793,3797,3803,3821,3823,3833,3847,3851,3853,3863,3877,3881,3889,3907,3911,3917,3919,3923,3929,3931,3943,3947,3967,3989,4001,4003,4007,4013,4019,4021,4027,4049,4051,4057,4073,4079,4091,4093,4099,4111,4127,4129,4133,4139,4153,4157,4159,4177,4201,4211,4217,4219,4229,4231,4241,4243,4253,4259,4261,4271,4273,4283,4289,4297,4327,4337,4339,4349,4357,4363,4373,4391,4397,4409,4421,4423,4441,4447,4451,4457,4463,4481,4483,4493,4507,4513,4517,4519,4523,4547,4549,4561,4567,4583,4591,4597,4603,4621,4637,4639,4643,4649,4651,4657,4663,4673,4679,4691,4703,4721,4723,4729,4733,4751,4759,4783,4787,4789,4793,4799,4801,4813,4817,4831,4861,4871,4877,4889,4903,4909,4919,4931,4933,4937,4943,4951,4957,4967,4969,4973,4987,4993,4999,5003,5009,5011,5021,5023,5039,5051,5059,5077,5081,5087,5099,5101,5107,5113,5119,5147,5153,5167,5171,5179,5189,5197,5209,5227,5231,5233,5237,5261,5273,5279,5281,5297,5303,5309,5323,5333,5347,5351,5381,5387,5393,5399,5407,5413,5417,5419,5431,5437,5441,5443,5449,5471,5477,5479,5483,5501,5503,5507,5519,5521,5527,5531,5557,5563,5569,5573,5581,5591,5623,5639,5641,5647,5651,5653,5657,5659,5669,5683,5689,5693,5701,5711,5717,5737,5741,5743,5749,5779,5783,5791,5801,5807,5813,5821,5827,5839,5843,5849,5851,5857,5861,5867,5869,5879,5881,5897,5903,5923,5927,5939,5953,5981,5987,6007,6011,6029,6037,6043,6047,6053,6067,6073,6079,6089,6091,6101,6113,6121,6131,6133,6143,6151,6163,6173,6197,6199,6203,6211,6217,6221,6229,6247,6257,6263,6269,6271,6277,6287,6299,6301,6311,6317,6323,6329,6337,6343,6353,6359,6361,6367,6373,6379,6389,6397,6421,6427,6449,6451,6469,6473,6481,6491,6521,6529,6547,6551,6553,6563,6569,6571,6577,6581,6599,6607,6619,6637,6653,6659,6661,6673,6679,6689,6691,6701,6703,6709,6719,6733,6737,6761,6763,6779,6781,6791,6793,6803,6823,6827,6829,6833,6841,6857,6863,6869,6871,6883,6899,6907,6911,6917,6947,6949,6959,6961,6967,6971,6977,6983,6991,6997,7001,7013,7019,7027,7039,7043,7057,7069,7079,7103,7109,7121,7127,7129,7151,7159,7177,7187,7193,7207,7211,7213,7219,7229,7237,7243,7247,7253,7283,7297,7307,7309,7321,7331,7333,7349,7351,7369,7393,7411,7417,7433,7451,7457,7459,7477,7481,7487,7489,7499,7507,7517,7523,7529,7537,7541,7547,7549,7559,7561,7573,7577,7583,7589,7591,7603,7607,7621,7639,7643,7649,7669,7673,7681,7687,7691,7699,7703,7717,7723,7727,7741,7753,7757,7759,7789,7793,7817,7823,7829,7841,7853,7867,7873,7877,7879,7883,7901,7907,7919,7927,7933,7937,7949,7951,7963,7993,8009,8011,8017,8039,8053,8059,8069,8081,8087,8089,8093,8101,8111,8117,8123,8147,8161,8167,8171,8179,8191,8209,8219,8221,8231,8233,8237,8243,8263,8269,8273,8287,8291,8293,8297,8311,8317,8329,8353,8363,8369,8377,8387,8389,8419,8423,8429,8431,8443,8447,8461,8467,8501,8513,8521,8527,8537,8539,8543,8563,8573,8581,8597,8599,8609,8623,8627,8629,8641,8647,8663,8669,8677,8681,8689,8693,8699,8707,8713,8719,8731,8737,8741,8747,8753,8761,8779,8783,8803,8807,8819,8821,8831,8837,8839,8849,8861,8863,8867,8887,8893,8923,8929,8933,8941,8951,8963,8969,8971,8999,9001,9007,9011,9013,9029,9041,9043,9049,9059,9067,9091,9103,9109,9127,9133,9137,9151,9157,9161,9173,9181,9187,9199,9203,9209,9221,9227,9239,9241,9257,9277,9281,9283,9293,9311,9319,9323,9337,9341,9343,9349,9371,9377,9391,9397,9403,9413,9419,9421,9431,9433,9437,9439,9461,9463,9467,9473,9479,9491,9497,9511,9521,9533,9539,9547,9551,9587,9601,9613,9619,9623,9629,9631,9643,9649,9661,9677,9679,9689,9697,9719,9721,9733,9739,9743,9749,9767,9769,9781,9787,9791,9803,9811,9817,9829,9833,9839,9851,9857,9859,9871,9883,9887,9901,9907,9923,9929,9931,9941,9949,9967,9973,10007,10009,10037,10039,10061,10067,10069,10079,10091,10093,10099,10103,10111,10133,10139,10141,10151,10159,10163,10169,10177,10181,10193,10211,10223,10243,10247,10253,10259,10267,10271,10273,10289,10301,10303,10313,10321,10331,10333,10337,10343,10357,10369,10391,10399,10427,10429,10433,10453,10457,10459,10463,10477,10487,10499,10501,10513,10529,10531,10559,10567,10589,10597,10601,10607,10613,10627,10631,10639,10651,10657,10663,10667,10687,10691,10709,10711,10723,10729,10733,10739,10753,10771,10781,10789,10799,10831,10837,10847,10853,10859,10861,10867,10883,10889,10891,10903,10909,10937,10939,10949,10957,10973,10979,10987,10993,11003,11027,11047,11057,11059,11069,11071,11083,11087,11093,11113,11117,11119,11131,11149,11159,11161,11171,11173,11177,11197,11213,11239,11243,11251,11257,11261,11273,11279,11287,11299,11311,11317,11321,11329,11351,11353,11369,11383,11393,11399,11411,11423,11437,11443,11447,11467,11471,11483,11489,11491,11497,11503,11519,11527,11549,11551,11579,11587,11593,11597,11617,11621,11633,11657,11677,11681,11689,11699,11701,11717,11719,11731,11743,11777,11779,11783,11789,11801,11807,11813,11821,11827,11831,11833,11839,11863,11867,11887,11897,11903,11909,11923,11927,11933,11939,11941,11953,11959,11969,11971,11981,11987,12007,12011,12037,12041,12043,12049,12071,12073,12097,12101,12107,12109,12113,12119,12143,12149,12157,12161,12163,12197,12203,12211,12227,12239,12241,12251,12253,12263,12269,12277,12281,12289,12301,12323,12329,12343,12347,12373,12377,12379,12391,12401,12409,12413,12421,12433,12437,12451,12457,12473,12479,12487,12491,12497,12503,12511,12517,12527,12539,12541,12547,12553,12569,12577,12583,12589,12601,12611,12613,12619,12637,12641,12647,12653,12659,12671,12689,12697,12703,12713,12721,12739,12743,12757,12763,12781,12791,12799,12809,12821,12823,12829,12841,12853,12889,12893,12899,12907,12911,12917,12919,12923,12941,12953,12959,12967,12973,12979,12983,13001,13003,13007,13009,13033,13037,13043,13049,13063,13093,13099,13103,13109,13121,13127,13147,13151,13159,13163,13171,13177,13183,13187,13217,13219,13229,13241,13249,13259,13267,13291,13297,13309,13313,13327,13331,13337,13339,13367,13381,13397,13399,13411,13417,13421,13441,13451,13457,13463,13469,13477,13487,13499,13513,13523,13537,13553,13567,13577,13591,13597,13613,13619,13627,13633,13649,13669,13679,13681,13687,13691,13693,13697,13709,13711,13721,13723,13729,13751,13757,13759,13763,13781,13789,13799,13807,13829,13831,13841,13859,13873,13877,13879,13883,13901,13903,13907,13913,13921,13931,13933,13963,13967,13997,13999,14009,14011,14029,14033,14051,14057,14071,14081,14083,14087,14107,14143,14149,14153,14159,14173,14177,14197,14207,14221,14243,14249,14251,14281,14293,14303,14321,14323,14327,14341,14347,14369,14387,14389,14401,14407,14411,14419,14423,14431,14437,14447,14449,14461,14479,14489,14503,14519,14533,14537,14543,14549,14551,14557,14561,14563,14591,14593,14621,14627,14629,14633,14639,14653,14657,14669,14683,14699,14713,14717,14723,14731,14737,14741,14747,14753,14759,14767,14771,14779,14783,14797,14813,14821,14827,14831,14843,14851,14867,14869,14879,14887,14891,14897,14923,14929,14939,14947,14951,14957,14969,14983,15013,15017,15031,15053,15061,15073,15077,15083,15091,15101,15107,15121,15131,15137,15139,15149,15161,15173,15187,15193,15199,15217,15227,15233,15241,15259,15263,15269,15271,15277,15287,15289,15299,15307,15313,15319,15329,15331,15349,15359,15361,15373,15377,15383,15391,15401,15413,15427,15439,15443,15451,15461,15467,15473,15493,15497,15511,15527,15541,15551,15559,15569,15581,15583,15601,15607,15619,15629,15641,15643,15647,15649,15661,15667,15671,15679,15683,15727,15731,15733,15737,15739,15749,15761,15767,15773,15787,15791,15797,15803,15809,15817,15823,15859,15877,15881,15887,15889,15901,15907,15913,15919,15923,15937,15959,15971,15973,15991,16001,16007,16033,16057,16061,16063,16067,16069,16073,16087,16091,16097,16103,16111,16127,16139,16141,16183,16187,16189,16193,16217,16223,16229,16231,16249,16253,16267,16273,16301,16319,16333,16339,16349,16361,16363,16369,16381,16411,16417,16421,16427,16433,16447,16451,16453,16477,16481,16487,16493,16519,16529,16547,16553,16561,16567,16573,16603,16607,16619,16631,16633,16649,16651,16657,16661,16673,16691,16693,16699,16703,16729,16741,16747,16759,16763,16787,16811,16823,16829,16831,16843,16871,16879,16883,16889,16901,16903,16921,16927,16931,16937,16943,16963,16979,16981,16987,16993,17011,17021,17027,17029,17033,17041,17047,17053,17077,17093,17099,17107,17117,17123,17137,17159,17167,17183,17189,17191,17203,17207,17209,17231,17239,17257,17291,17293,17299,17317,17321,17327,17333,17341,17351,17359,17377,17383,17387,17389,17393,17401,17417,17419,17431,17443,17449,17467,17471,17477,17483,17489,17491,17497,17509,17519,17539,17551,17569,17573,17579,17581,17597,17599,17609,17623,17627,17657,17659,17669,17681,17683,17707,17713,17729,17737,17747,17749,17761,17783,17789,17791,17807,17827,17837,17839,17851,17863,17881,17891,17903,17909,17911,17921,17923,17929,17939,17957,17959,17971,17977,17981,17987,17989,18013,18041,18043,18047,18049,18059,18061,18077,18089,18097,18119,18121,18127,18131,18133,18143,18149,18169,18181,18191,18199,18211,18217,18223,18229,18233,18251,18253,18257,18269,18287,18289,18301,18307,18311,18313,18329,18341,18353,18367,18371,18379,18397,18401,18413,18427,18433,18439,18443,18451,18457,18461,18481,18493,18503,18517,18521,18523,18539,18541,18553,18583,18587,18593,18617,18637,18661,18671,18679,18691,18701,18713,18719,18731,18743,18749,18757,18773,18787,18793,18797,18803,18839,18859,18869,18899,18911,18913,18917,18919,18947,18959,18973,18979,19001,19009,19013,19031,19037,19051,19069,19073,19079,19081,19087,19121,19139,19141,19157,19163,19181,19183,19207,19211,19213,19219,19231,19237,19249,19259,19267,19273,19289,19301,19309,19319,19333,19373,19379,19381,19387,19391,19403,19417,19421,19423,19427,19429,19433,19441,19447,19457,19463,19469,19471,19477,19483,19489,19501,19507,19531,19541,19543,19553,19559,19571,19577,19583,19597,19603,19609,19661,19681,19687,19697,19699,19709,19717,19727,19739,19751,19753,19759,19763,19777,19793,19801,19813,19819,19841,19843,19853,19861,19867,19889,19891,19913,19919,19927,19937,19949,19961,19963,19973,19979,19991,19993,19997,20011,20021,20023,20029,20047,20051,20063,20071,20089,20101,20107,20113,20117,20123,20129,20143,20147,20149,20161,20173,20177,20183,20201,20219,20231,20233,20249,20261,20269,20287,20297,20323,20327,20333,20341,20347,20353,20357,20359,20369,20389,20393,20399,20407,20411,20431,20441,20443,20477,20479,20483,20507,20509,20521,20533,20543,20549,20551,20563,20593,20599,20611,20627,20639,20641,20663,20681,20693,20707,20717,20719,20731,20743,20747,20749,20753,20759,20771,20773,20789,20807,20809,20849,20857,20873,20879,20887,20897,20899,20903,20921,20929,20939,20947,20959,20963,20981,20983,21001,21011,21013,21017,21019,21023,21031,21059,21061,21067,21089,21101,21107,21121,21139,21143,21149,21157,21163,21169,21179,21187,21191,21193,21211,21221,21227,21247,21269,21277,21283,21313,21317,21319,21323,21341,21347,21377,21379,21383,21391,21397,21401,21407,21419,21433,21467,21481,21487,21491,21493,21499,21503,21517,21521,21523,21529,21557,21559,21563,21569,21577,21587,21589,21599,21601,21611,21613,21617,21647,21649,21661,21673,21683,21701,21713,21727,21737,21739,21751,21757,21767,21773,21787,21799,21803,21817,21821,21839,21841,21851,21859,21863,21871,21881,21893,21911,21929,21937,21943,21961,21977,21991,21997,22003,22013,22027,22031,22037,22039,22051,22063,22067,22073,22079,22091,22093,22109,22111,22123,22129,22133,22147,22153,22157,22159,22171,22189,22193,22229,22247,22259,22271,22273,22277,22279,22283,22291,22303,22307,22343,22349,22367,22369,22381,22391,22397,22409,22433,22441,22447,22453,22469,22481,22483,22501,22511,22531,22541,22543,22549,22567,22571,22573,22613,22619,22621,22637,22639,22643,22651,22669,22679,22691,22697,22699,22709,22717,22721,22727,22739,22741,22751,22769,22777,22783,22787,22807,22811,22817,22853,22859,22861,22871,22877,22901,22907,22921,22937,22943,22961,22963,22973,22993,23003,23011,23017,23021,23027,23029,23039,23041,23053,23057,23059,23063,23071,23081,23087,23099,23117,23131,23143,23159,23167,23173,23189,23197,23201,23203,23209,23227,23251,23269,23279,23291,23293,23297,23311,23321,23327,23333,23339,23357,23369,23371,23399,23417,23431,23447,23459,23473,23497,23509,23531,23537,23539,23549,23557,23561,23563,23567,23581,23593,23599,23603,23609,23623,23627,23629,23633,23663,23669,23671,23677,23687,23689,23719,23741,23743,23747,23753,23761,23767,23773,23789,23801,23813,23819,23827,23831,23833,23857,23869,23873,23879,23887,23893,23899,23909,23911,23917,23929,23957,23971,23977,23981,23993,24001,24007,24019,24023,24029,24043,24049,24061,24071,24077,24083,24091,24097,24103,24107,24109,24113,24121,24133,24137,24151,24169,24179,24181,24197,24203,24223,24229,24239,24247,24251,24281,24317,24329,24337,24359,24371,24373,24379,24391,24407,24413,24419,24421,24439,24443,24469,24473,24481,24499,24509,24517,24527,24533,24547,24551,24571,24593,24611,24623,24631,24659,24671,24677,24683,24691,24697,24709,24733,24749,24763,24767,24781,24793,24799,24809,24821,24841,24847,24851,24859,24877,24889,24907,24917,24919,24923,24943,24953,24967,24971,24977,24979,24989,25013,25031,25033,25037,25057,25073,25087,25097,25111,25117,25121,25127,25147,25153,25163,25169,25171,25183,25189,25219,25229,25237,25243,25247,25253,25261,25301,25303,25307,25309,25321,25339,25343,25349,25357,25367,25373,25391,25409,25411,25423,25439,25447,25453,25457,25463,25469,25471,25523,25537,25541,25561,25577,25579,25583,25589,25601,25603,25609,25621,25633,25639,25643,25657,25667,25673,25679,25693,25703,25717,25733,25741,25747,25759,25763,25771,25793,25799,25801,25819,25841,25847,25849,25867,25873,25889,25903,25913,25919,25931,25933,25939,25943,25951,25969,25981,25997,25999,26003,26017,26021,26029,26041,26053,26083,26099,26107,26111,26113,26119,26141,26153,26161,26171,26177,26183,26189,26203,26209,26227,26237,26249,26251,26261,26263,26267,26293,26297,26309,26317,26321,26339,26347,26357,26371,26387,26393,26399,26407,26417,26423,26431,26437,26449,26459,26479,26489,26497,26501,26513,26539,26557,26561,26573,26591,26597,26627,26633,26641,26647,26669,26681,26683,26687,26693,26699,26701,26711,26713,26717,26723,26729,26731,26737,26759,26777,26783,26801,26813,26821,26833,26839,26849,26861,26863,26879,26881,26891,26893,26903,26921,26927,26947,26951,26953,26959,26981,26987,26993,27011,27017,27031,27043,27059,27061,27067,27073,27077,27091,27103,27107,27109,27127,27143,27179,27191,27197,27211,27239,27241,27253,27259,27271,27277,27281,27283,27299,27329,27337,27361,27367,27397,27407,27409,27427,27431,27437,27449,27457,27479,27481,27487,27509,27527,27529,27539,27541,27551,27581,27583,27611,27617,27631,27647,27653,27673,27689,27691,27697,27701,27733,27737,27739,27743,27749,27751,27763,27767,27773,27779,27791,27793,27799,27803,27809,27817,27823,27827,27847,27851,27883,27893,27901,27917,27919,27941,27943,27947,27953,27961,27967,27983,27997,28001,28019,28027,28031,28051,28057,28069,28081,28087,28097,28099,28109,28111,28123,28151,28163,28181,28183,28201,28211,28219,28229,28277,28279,28283,28289,28297,28307,28309,28319,28349,28351,28387,28393,28403,28409,28411,28429,28433,28439,28447,28463,28477,28493,28499,28513,28517,28537,28541,28547,28549,28559,28571,28573,28579,28591,28597,28603,28607,28619,28621,28627,28631,28643,28649,28657,28661,28663,28669,28687,28697,28703,28711,28723,28729,28751,28753,28759,28771,28789,28793,28807,28813,28817,28837,28843,28859,28867,28871,28879,28901,28909,28921,28927,28933,28949,28961,28979,29009,29017,29021,29023,29027,29033,29059,29063,29077,29101,29123,29129,29131,29137,29147,29153,29167,29173,29179,29191,29201,29207,29209,29221,29231,29243,29251,29269,29287,29297,29303,29311,29327,29333,29339,29347,29363,29383,29387,29389,29399,29401,29411,29423,29429,29437,29443,29453,29473,29483,29501,29527,29531,29537,29567,29569,29573,29581,29587,29599,29611,29629,29633,29641,29663,29669,29671,29683,29717,29723,29741,29753,29759,29761,29789,29803,29819,29833,29837,29851,29863,29867,29873,29879,29881,29917,29921,29927,29947,29959,29983,29989,30011,30013,30029,30047,30059,30071,30089,30091,30097,30103,30109,30113,30119,30133,30137,30139,30161,30169,30181,30187,30197,30203,30211,30223,30241,30253,30259,30269,30271,30293,30307,30313,30319,30323,30341,30347,30367,30389,30391,30403,30427,30431,30449,30467,30469,30491,30493,30497,30509,30517,30529,30539,30553,30557,30559,30577,30593,30631,30637,30643,30649,30661,30671,30677,30689,30697,30703,30707,30713,30727,30757,30763,30773,30781,30803,30809,30817,30829,30839,30841,30851,30853,30859,30869,30871,30881,30893,30911,30931,30937,30941,30949,30971,30977,30983,31013,31019,31033,31039,31051,31063,31069,31079,31081,31091,31121,31123,31139,31147,31151,31153,31159,31177,31181,31183,31189,31193,31219,31223,31231,31237,31247,31249,31253,31259,31267,31271,31277,31307,31319,31321,31327,31333,31337,31357,31379,31387,31391,31393,31397,31469,31477,31481,31489,31511,31513,31517,31531,31541,31543,31547,31567,31573,31583,31601,31607,31627,31643,31649,31657,31663,31667,31687,31699,31721,31723,31727,31729,31741,31751,31769,31771,31793,31799,31817,31847,31849,31859,31873,31883,31891,31907,31957,31963,31973,31981,31991,32003,32009,32027,32029,32051,32057,32059,32063,32069,32077,32083,32089,32099,32117,32119,32141,32143,32159,32173,32183,32189,32191,32203,32213,32233,32237,32251,32257,32261,32297,32299,32303,32309,32321,32323,32327,32341,32353,32359,32363,32369,32371,32377,32381,32401,32411,32413,32423,32429,32441,32443,32467,32479,32491,32497,32503,32507,32531,32533,32537,32561,32563,32569,32573,32579,32587,32603,32609,32611,32621,32633,32647,32653,32687,32693,32707,32713,32717,32719,32749,32771,32779,32783,32789,32797,32801,32803,32831,32833,32839,32843,32869,32887,32909,32911,32917,32933,32939,32941,32957,32969,32971,32983,32987,32993,32999,33013,33023,33029,33037,33049,33053,33071,33073,33083,33091,33107,33113,33119,33149,33151,33161,33179,33181,33191,33199,33203,33211,33223,33247,33287,33289,33301,33311,33317,33329,33331,33343,33347,33349,33353,33359,33377,33391,33403,33409,33413,33427,33457,33461,33469,33479,33487,33493,33503,33521,33529,33533,33547,33563,33569,33577,33581,33587,33589,33599,33601,33613,33617,33619,33623,33629,33637,33641,33647,33679,33703,33713,33721,33739,33749,33751,33757,33767,33769,33773,33791,33797,33809,33811,33827,33829,33851,33857,33863,33871,33889,33893,33911,33923,33931,33937,33941,33961,33967,33997,34019,34031,34033,34039,34057,34061,34123,34127,34129,34141,34147,34157,34159,34171,34183,34211,34213,34217,34231,34253,34259,34261,34267,34273,34283,34297,34301,34303,34313,34319,34327,34337,34351,34361,34367,34369,34381,34403,34421,34429,34439,34457,34469,34471,34483,34487,34499,34501,34511,34513,34519,34537,34543,34549,34583,34589,34591,34603,34607,34613,34631,34649,34651,34667,34673,34679,34687,34693,34703,34721,34729,34739,34747,34757,34759,34763,34781,34807,34819,34841,34843,34847,34849,34871,34877,34883,34897,34913,34919,34939,34949,34961,34963,34981,35023,35027,35051,35053,35059,35069,35081,35083,35089,35099,35107,35111,35117,35129,35141,35149,35153,35159,35171,35201,35221,35227,35251,35257,35267,35279,35281,35291,35311,35317,35323,35327,35339,35353,35363,35381,35393,35401,35407,35419,35423,35437,35447,35449,35461,35491,35507,35509,35521,35527,35531,35533,35537,35543,35569,35573,35591,35593,35597,35603,35617,35671,35677,35729,35731,35747,35753,35759,35771,35797,35801,35803,35809,35831,35837,35839,35851,35863,35869,35879,35897,35899,35911,35923,35933,35951,35963,35969,35977,35983,35993,35999,36007,36011,36013,36017,36037,36061,36067,36073,36083,36097,36107,36109,36131,36137,36151,36161,36187,36191,36209,36217,36229,36241,36251,36263,36269,36277,36293,36299,36307,36313,36319,36341,36343,36353,36373,36383,36389,36433,36451,36457,36467,36469,36473,36479,36493,36497,36523,36527,36529,36541,36551,36559,36563,36571,36583,36587,36599,36607,36629,36637,36643,36653,36671,36677,36683,36691,36697,36709,36713,36721,36739,36749,36761,36767,36779,36781,36787,36791,36793,36809,36821,36833,36847,36857,36871,36877,36887,36899,36901,36913,36919,36923,36929,36931,36943,36947,36973,36979,36997,37003,37013,37019,37021,37039,37049,37057,37061,37087,37097,37117,37123,37139,37159,37171,37181,37189,37199,37201,37217,37223,37243,37253,37273,37277,37307,37309,37313,37321,37337,37339,37357,37361,37363,37369,37379,37397,37409,37423,37441,37447,37463,37483,37489,37493,37501,37507,37511,37517,37529,37537,37547,37549,37561,37567,37571,37573,37579,37589,37591,37607,37619,37633,37643,37649,37657,37663,37691,37693,37699,37717,37747,37781,37783,37799,37811,37813,37831,37847,37853,37861,37871,37879,37889,37897,37907,37951,37957,37963,37967,37987,37991,37993,37997,38011,38039,38047,38053,38069,38083,38113,38119,38149,38153,38167,38177,38183,38189,38197,38201,38219,38231,38237,38239,38261,38273,38281,38287,38299,38303,38317,38321,38327,38329,38333,38351,38371,38377,38393,38431,38447,38449,38453,38459,38461,38501,38543,38557,38561,38567,38569,38593,38603,38609,38611,38629,38639,38651,38653,38669,38671,38677,38693,38699,38707,38711,38713,38723,38729,38737,38747,38749,38767,38783,38791,38803,38821,38833,38839,38851,38861,38867,38873,38891,38903,38917,38921,38923,38933,38953,38959,38971,38977,38993,39019,39023,39041,39043,39047,39079,39089,39097,39103,39107,39113,39119,39133,39139,39157,39161,39163,39181,39191,39199,39209,39217,39227,39229,39233,39239,39241,39251,39293,39301,39313,39317,39323,39341,39343,39359,39367,39371,39373,39383,39397,39409,39419,39439,39443,39451,39461,39499,39503,39509,39511,39521,39541,39551,39563,39569,39581,39607,39619,39623,39631,39659,39667,39671,39679,39703,39709,39719,39727,39733,39749,39761,39769,39779,39791,39799,39821,39827,39829,39839,39841,39847,39857,39863,39869,39877,39883,39887,39901,39929,39937,39953,39971,39979,39983,39989,40009,40013,40031,40037,40039,40063,40087,40093,40099,40111,40123,40127,40129,40151,40153,40163,40169,40177,40189,40193,40213,40231,40237,40241,40253,40277,40283,40289,40343,40351,40357,40361,40387,40423,40427,40429,40433,40459,40471,40483,40487,40493,40499,40507,40519,40529,40531,40543,40559,40577,40583,40591,40597,40609,40627,40637,40639,40693,40697,40699,40709,40739,40751,40759,40763,40771,40787,40801,40813,40819,40823,40829,40841,40847,40849,40853,40867,40879,40883,40897,40903,40927,40933,40939,40949,40961,40973,40993,41011,41017,41023,41039,41047,41051,41057,41077,41081,41113,41117,41131,41141,41143,41149,41161,41177,41179,41183,41189,41201,41203,41213,41221,41227,41231,41233,41243,41257,41263,41269,41281,41299,41333,41341,41351,41357,41381,41387,41389,41399,41411,41413,41443,41453,41467,41479,41491,41507,41513,41519,41521,41539,41543,41549,41579,41593,41597,41603,41609,41611,41617,41621,41627,41641,41647,41651,41659,41669,41681,41687,41719,41729,41737,41759,41761,41771,41777,41801,41809,41813,41843,41849,41851,41863,41879,41887,41893,41897,41903,41911,41927,41941,41947,41953,41957,41959,41969,41981,41983,41999,42013,42017,42019,42023,42043,42061,42071,42073,42083,42089,42101,42131,42139,42157,42169,42179,42181,42187,42193,42197,42209,42221,42223,42227,42239,42257,42281,42283,42293,42299,42307,42323,42331,42337,42349,42359,42373,42379,42391,42397,42403,42407,42409,42433,42437,42443,42451,42457,42461,42463,42467,42473,42487,42491,42499,42509,42533,42557,42569,42571,42577,42589,42611,42641,42643,42649,42667,42677,42683,42689,42697,42701,42703,42709,42719,42727,42737,42743,42751,42767,42773,42787,42793,42797,42821,42829,42839,42841,42853,42859,42863,42899,42901,42923,42929,42937,42943,42953,42961,42967,42979,42989,43003,43013,43019,43037,43049,43051,43063,43067,43093,43103,43117,43133,43151,43159,43177,43189,43201,43207,43223,43237,43261,43271,43283,43291,43313,43319,43321,43331,43391,43397,43399,43403,43411,43427,43441,43451,43457,43481,43487,43499,43517,43541,43543,43573,43577,43579,43591,43597,43607,43609,43613,43627,43633,43649,43651,43661,43669,43691,43711,43717,43721,43753,43759,43777,43781,43783,43787,43789,43793,43801,43853,43867,43889,43891,43913,43933,43943,43951,43961,43963,43969,43973,43987,43991,43997,44017,44021,44027,44029,44041,44053,44059,44071,44087,44089,44101,44111,44119,44123,44129,44131,44159,44171,44179,44189,44201,44203,44207,44221,44249,44257,44263,44267,44269,44273,44279,44281,44293,44351,44357,44371,44381,44383,44389,44417,44449,44453,44483,44491,44497,44501,44507,44519,44531,44533,44537,44543,44549,44563,44579,44587,44617,44621,44623,44633,44641,44647,44651,44657,44683,44687,44699,44701,44711,44729,44741,44753,44771,44773,44777,44789,44797,44809,44819,44839,44843,44851,44867,44879,44887,44893,44909,44917,44927,44939,44953,44959,44963,44971,44983,44987,45007,45013,45053,45061,45077,45083,45119,45121,45127,45131,45137,45139,45161,45179,45181,45191,45197,45233,45247,45259,45263,45281,45289,45293,45307,45317,45319,45329,45337,45341,45343,45361,45377,45389,45403,45413,45427,45433,45439,45481,45491,45497,45503,45523,45533,45541,45553,45557,45569,45587,45589,45599,45613,45631,45641,45659,45667,45673,45677,45691,45697,45707,45737,45751,45757,45763,45767,45779,45817,45821,45823,45827,45833,45841,45853,45863,45869,45887,45893,45943,45949,45953,45959,45971,45979,45989,46021,46027,46049,46051,46061,46073,46091,46093,46099,46103,46133,46141,46147,46153,46171,46181,46183,46187,46199,46219,46229,46237,46261,46271,46273,46279,46301,46307,46309,46327,46337,46349,46351,46381,46399,46411,46439,46441,46447,46451,46457,46471,46477,46489,46499,46507,46511,46523,46549,46559,46567,46573,46589,46591,46601,46619,46633,46639,46643,46649,46663,46679,46681,46687,46691,46703,46723,46727,46747,46751,46757,46769,46771,46807,46811,46817,46819,46829,46831,46853,46861,46867,46877,46889,46901,46919,46933,46957,46993,46997,47017,47041,47051,47057,47059,47087,47093,47111,47119,47123,47129,47137,47143,47147,47149,47161,47189,47207,47221,47237,47251,47269,47279,47287,47293,47297,47303,47309,47317,47339,47351,47353,47363,47381,47387,47389,47407,47417,47419,47431,47441,47459,47491,47497,47501,47507,47513,47521,47527,47533,47543,47563,47569,47581,47591,47599,47609,47623,47629,47639,47653,47657,47659,47681,47699,47701,47711,47713,47717,47737,47741,47743,47777,47779,47791,47797,47807,47809,47819,47837,47843,47857,47869,47881,47903,47911,47917,47933,47939,47947,47951,47963,47969,47977,47981,48017,48023,48029,48049,48073,48079,48091,48109,48119,48121,48131,48157,48163,48179,48187,48193,48197,48221,48239,48247,48259,48271,48281,48299,48311,48313,48337,48341,48353,48371,48383,48397,48407,48409,48413,48437,48449,48463,48473,48479,48481,48487,48491,48497,48523,48527,48533,48539,48541,48563,48571,48589,48593,48611,48619,48623,48647,48649,48661,48673,48677,48679,48731,48733,48751,48757,48761,48767,48779,48781,48787,48799,48809,48817,48821,48823,48847,48857,48859,48869,48871,48883,48889,48907,48947,48953,48973,48989,48991,49003,49009,49019,49031,49033,49037,49043,49057,49069,49081,49103,49109,49117,49121,49123,49139,49157,49169,49171,49177,49193,49199,49201,49207,49211,49223,49253,49261,49277,49279,49297,49307,49331,49333,49339,49363,49367,49369,49391,49393,49409,49411,49417,49429,49433,49451,49459,49463,49477,49481,49499,49523,49529,49531,49537,49547,49549,49559,49597,49603,49613,49627,49633,49639,49663,49667,49669,49681,49697,49711,49727,49739,49741,49747,49757,49783,49787,49789,49801,49807,49811,49823,49831,49843,49853,49871,49877,49891,49919,49921,49927,49937,49939,49943,49957,49991,49993,49999,50021,50023,50033,50047,50051,50053,50069,50077,50087,50093,50101,50111,50119,50123,50129,50131,50147,50153,50159,50177,50207,50221,50227,50231,50261,50263,50273,50287,50291,50311,50321,50329,50333,50341,50359,50363,50377,50383,50387,50411,50417,50423,50441,50459,50461,50497,50503,50513,50527,50539,50543,50549,50551,50581,50587,50591,50593,50599,50627,50647,50651,50671,50683,50707,50723,50741,50753,50767,50773,50777,50789,50821,50833,50839,50849,50857,50867,50873,50891,50893,50909,50923,50929,50951,50957,50969,50971,50989,50993,51001,51031,51043,51047,51059,51061,51071,51109,51131,51133,51137,51151,51157,51169,51193,51197,51199,51203,51217,51229,51239,51241,51257,51263,51283,51287,51307,51329,51341,51343,51347,51349,51361,51383,51407,51413,51419,51421,51427,51431,51437,51439,51449,51461,51473,51479,51481,51487,51503,51511,51517,51521,51539,51551,51563,51577,51581,51593,51599,51607,51613,51631,51637,51647,51659,51673,51679,51683,51691,51713,51719,51721,51749,51767,51769,51787,51797,51803,51817,51827,51829,51839,51853,51859,51869,51871,51893,51899,51907,51913,51929,51941,51949,51971,51973,51977,51991,52009,52021,52027,52051,52057,52067,52069,52081,52103,52121,52127,52147,52153,52163,52177,52181,52183,52189,52201,52223,52237,52249,52253,52259,52267,52289,52291,52301,52313,52321,52361,52363,52369,52379,52387,52391,52433,52453,52457,52489,52501,52511,52517,52529,52541,52543,52553,52561,52567,52571,52579,52583,52609,52627,52631,52639,52667,52673,52691,52697,52709,52711,52721,52727,52733,52747,52757,52769,52783,52807,52813,52817,52837,52859,52861,52879,52883,52889,52901,52903,52919,52937,52951,52957,52963,52967,52973,52981,52999,53003,53017,53047,53051,53069,53077,53087,53089,53093,53101,53113,53117,53129,53147,53149,53161,53171,53173,53189,53197,53201,53231,53233,53239,53267,53269,53279,53281,53299,53309,53323,53327,53353,53359,53377,53381,53401,53407,53411,53419,53437,53441,53453,53479,53503,53507,53527,53549,53551,53569,53591,53593,53597,53609,53611,53617,53623,53629,53633,53639,53653,53657,53681,53693,53699,53717,53719,53731,53759,53773,53777,53783,53791,53813,53819,53831,53849,53857,53861,53881,53887,53891,53897,53899,53917,53923,53927,53939,53951,53959,53987,53993,54001,54011,54013,54037,54049,54059,54083,54091,54101,54121,54133,54139,54151,54163,54167,54181,54193,54217,54251,54269,54277,54287,54293,54311,54319,54323,54331,54347,54361,54367,54371,54377,54401,54403,54409,54413,54419,54421,54437,54443,54449,54469,54493,54497,54499,54503,54517,54521,54539,54541,54547,54559,54563,54577,54581,54583,54601,54617,54623,54629,54631,54647,54667,54673,54679,54709,54713,54721,54727,54751,54767,54773,54779,54787,54799,54829,54833,54851,54869,54877,54881,54907,54917,54919,54941,54949,54959,54973,54979,54983,55001,55009,55021,55049,55051,55057,55061,55073,55079,55103,55109,55117,55127,55147,55163,55171,55201,55207,55213,55217,55219,55229,55243,55249,55259,55291,55313,55331,55333,55337,55339,55343,55351,55373,55381,55399,55411,55439,55441,55457,55469,55487,55501,55511,55529,55541,55547,55579,55589,55603,55609,55619,55621,55631,55633,55639,55661,55663,55667,55673,55681,55691,55697,55711,55717,55721,55733,55763,55787,55793,55799,55807,55813,55817,55819,55823,55829,55837,55843,55849,55871,55889,55897,55901,55903,55921,55927,55931,55933,55949,55967,55987,55997,56003,56009,56039,56041,56053,56081,56087,56093,56099,56101,56113,56123,56131,56149,56167,56171,56179,56197,56207,56209,56237,56239,56249,56263,56267,56269,56299,56311,56333,56359,56369,56377,56383,56393,56401,56417,56431,56437,56443,56453,56467,56473,56477,56479,56489,56501,56503,56509,56519,56527,56531,56533,56543,56569,56591,56597,56599,56611,56629,56633,56659,56663,56671,56681,56687,56701,56711,56713,56731,56737,56747,56767,56773,56779,56783,56807,56809,56813,56821,56827,56843,56857,56873,56891,56893,56897,56909,56911,56921,56923,56929,56941,56951,56957,56963,56983,56989,56993,56999,57037,57041,57047,57059,57073,57077,57089,57097,57107,57119,57131,57139,57143,57149,57163,57173,57179,57191,57193,57203,57221,57223,57241,57251,57259,57269,57271,57283,57287,57301,57329,57331,57347,57349,57367,57373,57383,57389,57397,57413,57427,57457,57467,57487,57493,57503,57527,57529,57557,57559,57571,57587,57593,57601,57637,57641,57649,57653,57667,57679,57689,57697,57709,57713,57719,57727,57731,57737,57751,57773,57781,57787,57791,57793,57803,57809,57829,57839,57847,57853,57859,57881,57899,57901,57917,57923,57943,57947,57973,57977,57991,58013,58027,58031,58043,58049,58057,58061,58067,58073,58099,58109,58111,58129,58147,58151,58153,58169,58171,58189,58193,58199,58207,58211,58217,58229,58231,58237,58243,58271,58309,58313,58321,58337,58363,58367,58369,58379,58391,58393,58403,58411,58417,58427,58439,58441,58451,58453,58477,58481,58511,58537,58543,58549,58567,58573,58579,58601,58603,58613,58631,58657,58661,58679,58687,58693,58699,58711,58727,58733,58741,58757,58763,58771,58787,58789,58831,58889,58897,58901,58907,58909,58913,58921,58937,58943,58963,58967,58979,58991,58997,59009,59011,59021,59023,59029,59051,59053,59063,59069,59077,59083,59093,59107,59113,59119,59123,59141,59149,59159,59167,59183,59197,59207,59209,59219,59221,59233,59239,59243,59263,59273,59281,59333,59341,59351,59357,59359,59369,59377,59387,59393,59399,59407,59417,59419,59441,59443,59447,59453,59467,59471,59473,59497,59509,59513,59539,59557,59561,59567,59581,59611,59617,59621,59627,59629,59651,59659,59663,59669,59671,59693,59699,59707,59723,59729,59743,59747,59753,59771,59779,59791,59797,59809,59833,59863,59879,59887,59921,59929,59951,59957,59971,59981,59999,60013,60017,60029,60037,60041,60077,60083,60089,60091,60101,60103,60107,60127,60133,60139,60149,60161,60167,60169,60209,60217,60223,60251,60257,60259,60271,60289,60293,60317,60331,60337,60343,60353,60373,60383,60397,60413,60427,60443,60449,60457,60493,60497,60509,60521,60527,60539,60589,60601,60607,60611,60617,60623,60631,60637,60647,60649,60659,60661,60679,60689,60703,60719,60727,60733,60737,60757,60761,60763,60773,60779,60793,60811,60821,60859,60869,60887,60889,60899,60901,60913,60917,60919,60923,60937,60943,60953,60961,61001,61007,61027,61031,61043,61051,61057,61091,61099,61121,61129,61141,61151,61153,61169,61211,61223,61231,61253,61261,61283,61291,61297,61331,61333,61339,61343,61357,61363,61379,61381,61403,61409,61417,61441,61463,61469,61471,61483,61487,61493,61507,61511,61519,61543,61547,61553,61559,61561,61583,61603,61609,61613,61627,61631,61637,61643,61651,61657,61667,61673,61681,61687,61703,61717,61723,61729,61751,61757,61781,61813,61819,61837,61843,61861,61871,61879,61909,61927,61933,61949,61961,61967,61979,61981,61987,61991,62003,62011,62017,62039,62047,62053,62057,62071,62081,62099,62119,62129,62131,62137,62141,62143,62171,62189,62191,62201,62207,62213,62219,62233,62273,62297,62299,62303,62311,62323,62327,62347,62351,62383,62401,62417,62423,62459,62467,62473,62477,62483,62497,62501,62507,62533,62539,62549,62563,62581,62591,62597,62603,62617,62627,62633,62639,62653,62659,62683,62687,62701,62723,62731,62743,62753,62761,62773,62791,62801,62819,62827,62851,62861,62869,62873,62897,62903,62921,62927,62929,62939,62969,62971,62981,62983,62987,62989,63029,63031,63059,63067,63073,63079,63097,63103,63113,63127,63131,63149,63179,63197,63199,63211,63241,63247,63277,63281,63299,63311,63313,63317,63331,63337,63347,63353,63361,63367,63377,63389,63391,63397,63409,63419,63421,63439,63443,63463,63467,63473,63487,63493,63499,63521,63527,63533,63541,63559,63577,63587,63589,63599,63601,63607,63611,63617,63629,63647,63649,63659,63667,63671,63689,63691,63697,63703,63709,63719,63727,63737,63743,63761,63773,63781,63793,63799,63803,63809,63823,63839,63841,63853,63857,63863,63901,63907,63913,63929,63949,63977,63997,64007,64013,64019,64033,64037,64063,64067,64081,64091,64109,64123,64151,64153,64157,64171,64187,64189,64217,64223,64231,64237,64271,64279,64283,64301,64303,64319,64327,64333,64373,64381,64399,64403,64433,64439,64451,64453,64483,64489,64499,64513,64553,64567,64577,64579,64591,64601,64609,64613,64621,64627,64633,64661,64663,64667,64679,64693,64709,64717,64747,64763,64781,64783,64793,64811,64817,64849,64853,64871,64877,64879,64891,64901,64919,64921,64927,64937,64951,64969,64997,65003,65011,65027,65029,65033,65053,65063,65071,65089,65099,65101,65111,65119,65123,65129,65141,65147,65167,65171,65173,65179,65183,65203,65213,65239,65257,65267,65269,65287,65293,65309,65323,65327,65353,65357,65371,65381,65393,65407,65413,65419,65423,65437,65447,65449,65479,65497,65519,65521] integer-roots-1.0.2.0/Math/NumberTheory/0000755000000000000000000000000007346545000016156 5ustar0000000000000000integer-roots-1.0.2.0/Math/NumberTheory/Roots.hs0000644000000000000000000000125507346545000017623 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots -- Copyright: (c) 2011 Daniel Fischer, 2016-2020 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Calculating integer roots and testing perfect powers. -- module Math.NumberTheory.Roots ( -- * Square roots integerSquareRoot , isSquare , exactSquareRoot -- * Cube roots , integerCubeRoot , isCube , exactCubeRoot -- * /k/-th roots , integerRoot , isKthPower , exactRoot -- * Perfect powers , isPerfectPower , highestPower ) where import Math.NumberTheory.Roots.Squares import Math.NumberTheory.Roots.Cubes import Math.NumberTheory.Roots.General integer-roots-1.0.2.0/Math/NumberTheory/Roots/0000755000000000000000000000000007346545000017264 5ustar0000000000000000integer-roots-1.0.2.0/Math/NumberTheory/Roots/Cubes.hs0000644000000000000000000002541307346545000020666 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.Cubes -- Copyright: (c) 2011 Daniel Fischer, 2016-2020 Andrew Lelechenko -- Licence: MIT -- Maintainer: Daniel Fischer -- -- Functions dealing with cubes. Moderately efficient calculation of integer -- cube roots and testing for cubeness. {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} module Math.NumberTheory.Roots.Cubes ( integerCubeRoot , integerCubeRoot' , exactCubeRoot , isCube , isCube' , isPossibleCube ) where import Data.Bits (finiteBitSize, (.&.)) import GHC.Exts (Int#, Ptr(..), int2Double#, double2Int#, isTrue#, (/##), (**##), (<#)) import Numeric.Natural (Natural) #ifdef MIN_VERSION_integer_gmp import GHC.Exts (quotInt#, (*#), (-#)) import GHC.Integer.GMP.Internals (Integer(..), shiftLInteger, shiftRInteger, sizeofBigNat#) import GHC.Integer.Logarithms (integerLog2#) #define IS S# #define IP Jp# #define bigNatSize sizeofBigNat #else import GHC.Exts (minusWord#, timesWord#, quotWord#) import GHC.Num.BigNat (bigNatSize#) import GHC.Num.Integer (Integer(..), integerLog2#, integerShiftR#, integerShiftL#) #endif import Math.NumberTheory.Utils.BitMask (indexBitSet) -- | For a given \( n \) -- calculate its integer cube root \( \lfloor \sqrt[3]{n} \rfloor \). -- Note that this is not symmetric about 0. -- -- >>> map integerCubeRoot [7, 8, 9] -- [1,2,2] -- >>> map integerCubeRoot [-7, -8, -9] -- [-2,-2,-3] {-# SPECIALISE integerCubeRoot :: Int -> Int, Word -> Word, Integer -> Integer, Natural -> Natural #-} integerCubeRoot :: Integral a => a -> a integerCubeRoot 0 = 0 integerCubeRoot n | n > 0 = integerCubeRoot' n | otherwise = let m = negate n r = if m < 0 then negate . fromInteger $ integerCubeRoot' (negate $ fromIntegral n) else negate (integerCubeRoot' m) in if r*r*r == n then r else (r-1) -- | Calculate the integer cube root of a nonnegative integer @n@, -- that is, the largest integer @r@ such that @r^3 <= n@. -- The precondition @n >= 0@ is not checked. {-# RULES "integerCubeRoot'/Int" integerCubeRoot' = cubeRootInt' "integerCubeRoot'/Word" integerCubeRoot' = cubeRootWord "integerCubeRoot'/Integer" integerCubeRoot' = cubeRootIgr #-} {-# INLINE [1] integerCubeRoot' #-} integerCubeRoot' :: Integral a => a -> a integerCubeRoot' 0 = 0 integerCubeRoot' n = newton3 n (approxCuRt n) -- | Calculate the exact integer cube root if it exists, -- otherwise return 'Nothing'. -- -- >>> map exactCubeRoot [-9, -8, -7, 7, 8, 9] -- [Nothing,Just (-2),Nothing,Nothing,Just 2,Nothing] {-# SPECIALISE exactCubeRoot :: Int -> Maybe Int, Word -> Maybe Word, Integer -> Maybe Integer, Natural -> Maybe Natural #-} exactCubeRoot :: Integral a => a -> Maybe a exactCubeRoot 0 = Just 0 exactCubeRoot n | n < 0 = if m < 0 then fmap (negate . fromInteger) $ exactCubeRoot (negate $ fromIntegral n) else fmap negate (exactCubeRoot m) | isPossibleCube n && r*r*r == n = Just r | otherwise = Nothing where m = negate n r = integerCubeRoot' n -- | Test whether the argument is a perfect cube. -- -- >>> map isCube [-9, -8, -7, 7, 8, 9] -- [False,True,False,False,True,False] {-# SPECIALISE isCube :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isCube :: Integral a => a -> Bool isCube 0 = True isCube n | n > 0 = isCube' n | m > 0 = isCube' m | otherwise = isCube' (negate (fromIntegral n) :: Integer) where m = negate n -- | Test whether a nonnegative integer is a cube. -- Before 'integerCubeRoot' is calculated, a few tests -- of remainders modulo small primes weed out most non-cubes. -- For testing many numbers, most of which aren't cubes, -- this is much faster than @let r = cubeRoot n in r*r*r == n@. -- The condition @n >= 0@ is /not/ checked. {-# SPECIALISE isCube' :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isCube' :: Integral a => a -> Bool isCube' !n = isPossibleCube n && (r*r*r == n) where r = integerCubeRoot' n -- | Test whether a nonnegative number is possibly a cube. -- Only about 0.08% of all numbers pass this test. -- The precondition @n >= 0@ is /not/ checked. {-# SPECIALISE isPossibleCube :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isPossibleCube :: Integral a => a -> Bool isPossibleCube n' = indexBitSet mask512 (fromInteger (n .&. 511)) && indexBitSet mask837 (fromInteger (n `rem` 837)) && indexBitSet mask637 (fromInteger (n `rem` 637)) && indexBitSet mask703 (fromInteger (n `rem` 703)) where n = toInteger n' ---------------------------------------------------------------------- -- Utility Functions -- ---------------------------------------------------------------------- -- Special case for 'Int', a little faster. -- For @n <= 2^64@, the truncated 'Double' is never -- more than one off. Things might overflow for @n@ -- close to @maxBound@, so check for overflow. cubeRootInt' :: Int -> Int cubeRootInt' 0 = 0 cubeRootInt' n | n < c || c < 0 = r-1 | 0 < d && d < n = r+1 | otherwise = r where x = fromIntegral n :: Double r = truncate (x ** (1/3)) c = r*r*r d = c+3*r*(r+1) cubeRootWordLimit :: Word cubeRootWordLimit = if finiteBitSize (0 :: Word) == 64 then 2642245 else 1625 cubeRootWord :: Word -> Word cubeRootWord 0 = 0 cubeRootWord w | r > cubeRootWordLimit = cubeRootWordLimit | w < c = r-1 | c < w && e < w && c < e = r+1 | otherwise = r where r = truncate ((fromIntegral w) ** (1/3) :: Double) c = r*r*r d = 3*r*(r+1) e = c+d cubeRootIgr :: Integer -> Integer cubeRootIgr 0 = 0 cubeRootIgr n = newton3 n (approxCuRt n) {-# SPECIALISE newton3 :: Integer -> Integer -> Integer #-} newton3 :: Integral a => a -> a -> a newton3 n a = go (step a) where step k = (2*k + n `quot` (k*k)) `quot` 3 go k | m < k = go m | otherwise = k where m = step k {-# SPECIALISE approxCuRt :: Integer -> Integer #-} approxCuRt :: Integral a => a -> a approxCuRt 0 = 0 approxCuRt n = fromInteger $ appCuRt (fromIntegral n) -- | approximate cube root, about 50 bits should be correct for large numbers appCuRt :: Integer -> Integer appCuRt (IS i#) = case double2Int# (int2Double# i# **## (1.0## /## 3.0##)) of r# -> IS r# appCuRt n@(IP bn#) | isTrue# ((bigNatSize# bn#) <# thresh#) = floor (fromInteger n ** (1.0/3.0) :: Double) | otherwise = case integerLog2# n of #ifdef MIN_VERSION_integer_gmp l# -> case (l# `quotInt#` 3#) -# 51# of h# -> case shiftRInteger n (3# *# h#) of m -> case floor (fromInteger m ** (1.0/3.0) :: Double) of r -> shiftLInteger r h# #else l# -> case (l# `quotWord#` 3##) `minusWord#` 51## of h# -> case integerShiftR# n (3## `timesWord#` h#) of m -> case floor (fromInteger m ** (1.0/3.0) :: Double) of r -> integerShiftL# r h# #endif where -- threshold for shifting vs. direct fromInteger -- we shift when we expect more than 256 bits thresh# :: Int# thresh# = if finiteBitSize (0 :: Word) == 64 then 5# else 9# -- There's already handling for negative in integerCubeRoot, -- but integerCubeRoot' is exported directly too. appCuRt _ = error "integerCubeRoot': negative argument" ----------------------------------------------------------------------------- -- Generated by 'Math.NumberTheory.Utils.BitMask.vectorToAddrLiteral' mask512 :: Ptr Word mask512 = Ptr "\171\171\170\171\170\171\170\171\171\171\170\171\170\171\170\171\170\171\170\171\170\171\170\171\171\171\170\171\170\171\170\171\170\171\170\171\170\171\170\171\171\171\170\171\170\171\170\171\170\171\170\171\170\171\170\171\171\171\170\171\170\171\170\171"# mask837 :: Ptr Word mask837 = Ptr "\ETX\SOH\NUL\b\b@@@\SOH\NUL\NUL\n\NUL0\DLE \NUL\NUL\NUL\EOT\b\EOT\NULP\NUL\NUL\128\ETX\NUL\STX\DLE\NUL\NUL\128@\129\NUL\NUL\NUL\EOT \NUL\160\NUL\NUL\NUL\ENQ\NUL\DLE\b0\NUL\NUL\NUL\ETX\EOT\STX\NUL(\NUL\NUL@\SOH\NUL\SOH\b\NUL\NUL@\160@\NUL\NUL\NUL\STX\DLE\NULp\NUL\NUL\128\STX\NUL\b\EOT\b\NUL\NUL\NUL\SOH\STX\ETX\NUL\DC4\NUL\NUL\160\128\128\NUL\EOT\EOT\NUL \DLE"# mask637 :: Ptr Word mask637 = Ptr "\ETX!\NUL\b\EOT\NUL\NUL\STX\SOH@\b\DC4\b\SOH@ \NUL\NUL\DLE\b\NULB\160@\CAN\NUL\STX\SOH\NUL\128@\NUL\DLE\STX\ENQB@\DLE\b\NUL\NUL\EOT\130\128\DLE(\DLE\STX\128@\NUL\NUL \DLE\NUL\134@\129\DLE\NUL\EOT\STX\NUL\NUL\129\NUL \EOT\n\132\NUL \DLE\NUL\NUL\b\EOT\NUL!\DLE"# mask703 :: Ptr Word mask703 = Ptr "\ETX\t\NUL\140` \NUL\NUL\DC1\b\DLE\SOH\128\NUL\NUL&@\DLE\NUL\128\NUL\b\b\128\NUL\NUL\SOH!\DLE\DLE\NUL\SOH\f\n\STX`\NUL\ETX\SOH\NUL\f@\160\NUL\NUL\ENQ\STX0\NUL\128\192\NUL\ACK@P0\128\NUL\b\b\132\128\NUL\NUL\SOH\DLE\DLE\NUL\SOH\NUL\b\STXd\NUL\NUL\SOH\128\b\DLE\136\NUL\NUL\EOT\ACK1\NUL\144@"# -- -- not very discriminating, but cheap, so it's an overall gain -- cr512 :: V.Vector Bool -- cr512 = runST $ do -- ar <- MV.replicate 512 True -- let note s i -- | i < 512 = MV.unsafeWrite ar i False >> note s (i+s) -- | otherwise = return () -- note 4 2 -- note 8 4 -- note 32 16 -- note 64 32 -- note 256 128 -- MV.unsafeWrite ar 256 False -- V.unsafeFreeze ar -- -- Remainders modulo @3^3 * 31@ -- cubeRes837 :: V.Vector Bool -- cubeRes837 = runST $ do -- ar <- MV.replicate 837 False -- let note 837 = return () -- note k = MV.unsafeWrite ar ((k*k*k) `rem` 837) True >> note (k+1) -- note 0 -- V.unsafeFreeze ar -- -- Remainders modulo @7^2 * 13@ -- cubeRes637 :: V.Vector Bool -- cubeRes637 = runST $ do -- ar <- MV.replicate 637 False -- let note 637 = return () -- note k = MV.unsafeWrite ar ((k*k*k) `rem` 637) True >> note (k+1) -- note 0 -- V.unsafeFreeze ar -- -- Remainders modulo @19 * 37@ -- cubeRes703 :: V.Vector Bool -- cubeRes703 = runST $ do -- ar <- MV.replicate 703 False -- let note 703 = return () -- note k = MV.unsafeWrite ar ((k*k*k) `rem` 703) True >> note (k+1) -- note 0 -- V.unsafeFreeze ar integer-roots-1.0.2.0/Math/NumberTheory/Roots/Fourth.hs0000644000000000000000000002140107346545000021065 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.Squares -- Copyright: (c) 2011 Daniel Fischer, 2016-2020 Andrew Lelechenko -- Licence: MIT -- Maintainer: Daniel Fischer -- -- Functions dealing with fourth powers. Efficient calculation of integer fourth -- roots and efficient testing for being a square's square. {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} module Math.NumberTheory.Roots.Fourth ( integerFourthRoot , integerFourthRoot' , exactFourthRoot , isFourthPower , isFourthPower' , isPossibleFourthPower ) where import Data.Bits (finiteBitSize, (.&.)) import GHC.Exts (Int#, Ptr(..), int2Double#, double2Int#, isTrue#, sqrtDouble#, (<#)) import Numeric.Natural (Natural) #ifdef MIN_VERSION_integer_gmp import GHC.Exts (uncheckedIShiftRA#, (*#), (-#)) import GHC.Integer.GMP.Internals (Integer(..), shiftLInteger, shiftRInteger, sizeofBigNat#) import GHC.Integer.Logarithms (integerLog2#) #define IS S# #define IP Jp# #define bigNatSize sizeofBigNat #else import GHC.Exts (uncheckedShiftRL#, minusWord#, timesWord#) import GHC.Num.BigNat (bigNatSize#) import GHC.Num.Integer (Integer(..), integerLog2#, integerShiftR#, integerShiftL#) #endif import Math.NumberTheory.Utils.BitMask (indexBitSet) -- | Calculate the integer fourth root of a nonnegative number, -- that is, the largest integer @r@ with @r^4 <= n@. -- Throws an error on negaitve input. {-# SPECIALISE integerFourthRoot :: Int -> Int, Word -> Word, Integer -> Integer, Natural -> Natural #-} integerFourthRoot :: Integral a => a -> a integerFourthRoot n | n < 0 = error "integerFourthRoot: negative argument" | otherwise = integerFourthRoot' n -- | Calculate the integer fourth root of a nonnegative number, -- that is, the largest integer @r@ with @r^4 <= n@. -- The condition is /not/ checked. {-# RULES "integerFourthRoot'/Int" integerFourthRoot' = biSqrtInt "integerFourthRoot'/Word" integerFourthRoot' = biSqrtWord "integerFourthRoot'/Integer" integerFourthRoot' = biSqrtIgr #-} {-# INLINE [1] integerFourthRoot' #-} integerFourthRoot' :: Integral a => a -> a integerFourthRoot' 0 = 0 integerFourthRoot' n = newton4 n (approxBiSqrt n) -- | Returns @Nothing@ if @n@ is not a fourth power, -- @Just r@ if @n == r^4@ and @r >= 0@. {-# SPECIALISE exactFourthRoot :: Int -> Maybe Int, Word -> Maybe Word, Integer -> Maybe Integer, Natural -> Maybe Natural #-} exactFourthRoot :: Integral a => a -> Maybe a exactFourthRoot 0 = Just 0 exactFourthRoot n | n < 0 = Nothing | isPossibleFourthPower n && r2*r2 == n = Just r | otherwise = Nothing where r = integerFourthRoot' n r2 = r*r -- | Test whether an integer is a fourth power. -- First nonnegativity is checked, then the unchecked -- test is called. {-# SPECIALISE isFourthPower :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isFourthPower :: Integral a => a -> Bool isFourthPower 0 = True isFourthPower n = n > 0 && isFourthPower' n -- | Test whether a nonnegative number is a fourth power. -- The condition is /not/ checked. If a number passes the -- 'isPossibleFourthPower' test, its integer fourth root -- is calculated. {-# SPECIALISE isFourthPower' :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isFourthPower' :: Integral a => a -> Bool isFourthPower' n = isPossibleFourthPower n && r2*r2 == n where r = integerFourthRoot' n r2 = r*r -- | Test whether a nonnegative number is a possible fourth power. -- The condition is /not/ checked. -- This eliminates about 99.958% of numbers. {-# SPECIALISE isPossibleFourthPower :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isPossibleFourthPower :: Integral a => a -> Bool isPossibleFourthPower n' = indexBitSet mask256 (fromInteger (n .&. 255)) && indexBitSet mask425 (fromInteger (n `rem` 425)) && indexBitSet mask377 (fromInteger (n `rem` 377)) where n = toInteger n' {-# SPECIALISE newton4 :: Integer -> Integer -> Integer #-} newton4 :: Integral a => a -> a -> a newton4 n a = go (step a) where step k = (3*k + n `quot` (k*k*k)) `quot` 4 go k | m < k = go m | otherwise = k where m = step k {-# SPECIALISE approxBiSqrt :: Integer -> Integer #-} approxBiSqrt :: Integral a => a -> a approxBiSqrt = fromInteger . appBiSqrt . fromIntegral -- Find a fairly good approximation to the fourth root. -- About 48 bits should be correct for large Integers. appBiSqrt :: Integer -> Integer appBiSqrt (IS i#) = IS (double2Int# (sqrtDouble# (sqrtDouble# (int2Double# i#)))) appBiSqrt n@(IP bn#) | isTrue# ((bigNatSize# bn#) <# thresh#) = floor (sqrt . sqrt $ fromInteger n :: Double) | otherwise = case integerLog2# n of #ifdef MIN_VERSION_integer_gmp l# -> case uncheckedIShiftRA# l# 2# -# 47# of h# -> case shiftRInteger n (4# *# h#) of m -> case floor (sqrt $ sqrt $ fromInteger m :: Double) of r -> shiftLInteger r h# #else l# -> case uncheckedShiftRL# l# 2# `minusWord#` 47## of h# -> case integerShiftR# n (4## `timesWord#` h#) of m -> case floor (sqrt $ sqrt $ fromInteger m :: Double) of r -> integerShiftL# r h# #endif where -- threshold for shifting vs. direct fromInteger -- we shift when we expect more than 256 bits thresh# :: Int# thresh# = if finiteBitSize (0 :: Word) == 64 then 5# else 9# -- There's already a check for negative in integerFourthRoot, -- but integerFourthRoot' is exported directly too. appBiSqrt _ = error "integerFourthRoot': negative argument" ----------------------------------------------------------------------------- -- Generated by 'Math.NumberTheory.Utils.BitMask.vectorToAddrLiteral' mask256 :: Ptr Word mask256 = Ptr "\ETX\NUL\ETX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL\STX\NUL"# mask425 :: Ptr Word mask425 = Ptr "\ETX\NUL!\NUL\NUL\NUL\f\NUL\NUL\NULB\NUL \EOT\NUL\NUL\NUL\SOH\NUL\NUL@\b\NUL\132\NUL\SOH\NUL \STX\NUL\NUL\b\SOH\128\DLE\NUL\NUL\NUL\EOT\NUL\NUL\NUL!\NUL\DLE\STX\128\NUL\128\NUL\NUL\NUL \NUL"# mask377 :: Ptr Word mask377 = Ptr "\ETX\NUL\SOH \NUL\NUL0\NUL\STXD\130@\NUL\b \NUL\NUL\b\EOT\SOH \ACK\NUL\NUL@\DLE\NUL\NUL\NUL\NUL\NUL\SOH!\NUL\NUL@\NUL\NUL\NUL\n@\NUL\b\NUL\NUL\DLE \NUL"# -- biSqRes256 :: V.Vector Bool -- biSqRes256 = runST $ do -- ar <- MV.replicate 256 False -- let note 257 = return () -- note i = MV.unsafeWrite ar i True >> note (i+16) -- MV.unsafeWrite ar 0 True -- MV.unsafeWrite ar 16 True -- note 1 -- V.unsafeFreeze ar -- biSqRes425 :: V.Vector Bool -- biSqRes425 = runST $ do -- ar <- MV.replicate 425 False -- let note 154 = return () -- note i = MV.unsafeWrite ar ((i*i*i*i) `rem` 425) True >> note (i+1) -- note 0 -- V.unsafeFreeze ar -- biSqRes377 :: V.Vector Bool -- biSqRes377 = runST $ do -- ar <- MV.replicate 377 False -- let note 144 = return () -- note i = MV.unsafeWrite ar ((i*i*i*i) `rem` 377) True >> note (i+1) -- note 0 -- V.unsafeFreeze ar ----------------------------------------------------------------------------- -- Specialisations for Int, Word, and Integer biSqRootIntLimit :: Int biSqRootIntLimit = if finiteBitSize (0 :: Word) == 64 then 55108 else 215 biSqrtInt :: Int -> Int biSqrtInt 0 = 0 biSqrtInt n | r > biSqRootIntLimit = biSqRootIntLimit | n < r4 = r-1 | otherwise = r where x :: Double x = fromIntegral n -- timed faster than x**0.25, never too small r = truncate (sqrt (sqrt x)) r2 = r*r r4 = r2*r2 biSqRootWordLimit :: Word biSqRootWordLimit = if finiteBitSize (0 :: Word) == 64 then 65535 else 255 biSqrtWord :: Word -> Word biSqrtWord 0 = 0 biSqrtWord n | r > biSqRootWordLimit = biSqRootWordLimit | n < r4 = r-1 | otherwise = r where x :: Double x = fromIntegral n r = truncate (sqrt (sqrt x)) r2 = r*r r4 = r2*r2 biSqrtIgr :: Integer -> Integer biSqrtIgr 0 = 0 biSqrtIgr n = newton4 n (approxBiSqrt n) integer-roots-1.0.2.0/Math/NumberTheory/Roots/General.hs0000644000000000000000000003536407346545000021210 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.General -- Copyright: (c) 2011 Daniel Fischer, 2016-2020 Andrew Lelechenko -- Licence: MIT -- Maintainer: Daniel Fischer -- -- Calculating integer roots and determining perfect powers. -- The algorithms are moderately efficient. -- {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} {-# LANGUAGE ViewPatterns #-} module Math.NumberTheory.Roots.General ( integerRoot , exactRoot , isKthPower , isPerfectPower , highestPower ) where #include "MachDeps.h" import Data.Bits (countTrailingZeros, shiftL, shiftR) import Data.List (foldl', sortBy) import Data.Maybe (isJust) import GHC.Exts (Int(..), Word(..), word2Int#, int2Double#, double2Int#, isTrue#, Ptr(..), indexWord16OffAddr#, (/##), (**##)) #if MIN_VERSION_base(4,16,0) import GHC.Exts (word16ToWord#) #endif #ifdef WORDS_BIGENDIAN import GHC.Exts (byteSwap16#) #endif import Numeric.Natural (Natural) #ifdef MIN_VERSION_integer_gmp import GHC.Exts (int2Word#, quotInt#, (<#), (*#), (-#), (+#)) import GHC.Integer.GMP.Internals (Integer(..), shiftLInteger, shiftRInteger) import GHC.Integer.Logarithms (integerLog2#) #define IS S# #else import GHC.Exts (plusWord#, minusWord#, timesWord#, quotWord#, ltWord#) import GHC.Num.Integer (Integer(..), integerLog2#, integerShiftR#, integerShiftL#) #endif import qualified Math.NumberTheory.Roots.Squares as P2 import qualified Math.NumberTheory.Roots.Cubes as P3 import qualified Math.NumberTheory.Roots.Fourth as P4 import Math.NumberTheory.Primes.Small import Math.NumberTheory.Utils.FromIntegral (wordToInt) -- | For a positive power \( k \) and -- a given \( n \) -- return the integer \( k \)-th root \( \lfloor \sqrt[k]{n} \rfloor \). -- Throw an error if \( k \le 0 \) or if \( n \le 0 \) and \( k \) is even. -- -- >>> integerRoot 6 65 -- 2 -- >>> integerRoot 5 243 -- 3 -- >>> integerRoot 4 624 -- 4 -- >>> integerRoot 3 (-124) -- -5 -- >>> integerRoot 1 5 -- 5 {-# SPECIALISE integerRoot :: Int -> Int -> Int, Int -> Word -> Word, Int -> Integer -> Integer, Int -> Natural -> Natural, Word -> Int -> Int, Word -> Word -> Word, Word -> Integer -> Integer, Word -> Natural -> Natural, Integer -> Integer -> Integer, Natural -> Natural -> Natural #-} integerRoot :: (Integral a, Integral b) => b -> a -> a integerRoot 1 n = n integerRoot 2 n = P2.integerSquareRoot n integerRoot 3 n = P3.integerCubeRoot n integerRoot 4 n = P4.integerFourthRoot n integerRoot k n | k < 1 = error "integerRoot: negative exponent or exponent 0" | n < 0 && even k = error "integerRoot: negative radicand for even exponent" | n < 0 = let r = negate . fromInteger . integerRoot k . negate $ fromIntegral n in if r^k == n then r else (r-1) | n == 0 = 0 | n < 31 = 1 | kTooLarge = 1 | otherwise = fromInteger $ newtonK (toInteger k) (toInteger n) a where a = appKthRoot (fromIntegral k) (toInteger n) kTooLarge = (toInteger k /= toInteger (fromIntegral k `asTypeOf` n)) -- k doesn't fit in n's type || (toInteger k > toInteger (maxBound :: Int)) -- 2^k doesn't fit in Integer #ifdef MIN_VERSION_integer_gmp || (I# (integerLog2# (toInteger n)) < fromIntegral k) -- n < 2^k #else || (W# (integerLog2# (toInteger n)) < fromIntegral k) -- n < 2^k #endif -- | For a positive exponent \( k \) -- calculate the exact integer \( k \)-th root of the second argument if it exists, -- otherwise return 'Nothing'. -- -- >>> map (uncurry exactRoot) [(6, 65), (5, 243), (4, 624), (3, -124), (1, 5)] -- [Nothing,Just 3,Nothing,Nothing,Just 5] exactRoot :: (Integral a, Integral b) => b -> a -> Maybe a exactRoot 1 n = Just n exactRoot 2 n = P2.exactSquareRoot n exactRoot 3 n = P3.exactCubeRoot n exactRoot 4 n = P4.exactFourthRoot n exactRoot k n | n == 1 = Just 1 | k < 1 = Nothing | n < 0 && even k = Nothing | n < 0 = let m = negate n in if m < 0 then fmap (fromInteger . negate) (exactRoot k (negate (toInteger n))) else fmap negate (exactRoot k m) | n < 2 = Just n | n < 31 = Nothing | kTooLarge = Nothing | otherwise = case k `rem` 12 of 0 | c4 && c3 && ok -> Just r | otherwise -> Nothing 2 | c2 && ok -> Just r | otherwise -> Nothing 3 | c3 && ok -> Just r | otherwise -> Nothing 4 | c4 && ok -> Just r | otherwise -> Nothing 6 | c3 && c2 && ok -> Just r | otherwise -> Nothing 8 | c4 && ok -> Just r | otherwise -> Nothing 9 | c3 && ok -> Just r | otherwise -> Nothing 10 | c2 && ok -> Just r | otherwise -> Nothing _ | ok -> Just r | otherwise -> Nothing where k' :: Int k' = fromIntegral k r = integerRoot k' n c2 = P2.isPossibleSquare n c3 = P3.isPossibleCube n c4 = P4.isPossibleFourthPower n ok = r^k == n kTooLarge = (toInteger k /= toInteger (fromIntegral k `asTypeOf` n)) -- k doesn't fit in n's type || (toInteger k > toInteger (maxBound :: Int)) -- 2^k doesn't fit in Integer #ifdef MIN_VERSION_integer_gmp || (I# (integerLog2# (toInteger n)) < fromIntegral k) -- n < 2^k #else || (W# (integerLog2# (toInteger n)) < fromIntegral k) -- n < 2^k #endif -- | For a positive exponent \( k \) test whether the second argument -- is a perfect \( k \)-th power. -- -- >>> map (uncurry isKthPower) [(6, 65), (5, 243), (4, 624), (3, -124), (1, 5)] -- [False,True,False,False,True] isKthPower :: (Integral a, Integral b) => b -> a -> Bool isKthPower k n = isJust (exactRoot k n) -- | Test whether the argument is a non-trivial perfect power -- (e. g., square, cube, etc.). -- -- >>> map isPerfectPower [0..10] -- [True,True,False,False,True,False,False,False,True,True,False] -- >>> map isPerfectPower [-10..0] -- [False,False,True,False,False,False,False,False,False,True,True] isPerfectPower :: Integral a => a -> Bool isPerfectPower n | n == 0 || n == 1 = True | otherwise = k > 1 where (_,k) = highestPower n -- | For \( n \not\in \{ -1, 0, 1 \} \) -- find the largest exponent \( k \) for which -- an exact integer \( k \)-th root \( r \) exists. -- Return \( (r, k) \). -- -- For \( n \in \{ -1, 0, 1 \} \) arbitrarily large exponents exist; -- by arbitrary convention 'highestPower' returns \( (n, 3) \). -- -- >>> map highestPower [0..10] -- [(0,3),(1,3),(2,1),(3,1),(2,2),(5,1),(6,1),(7,1),(2,3),(3,2),(10,1)] -- >>> map highestPower [-10..0] -- [(-10,1),(-9,1),(-2,3),(-7,1),(-6,1),(-5,1),(-4,1),(-3,1),(-2,1),(-1,3),(0,3)] highestPower :: Integral a => a -> (a, Word) highestPower n' | abs n <= 1 = (n', 3) | n < 0 = case integerHighPower (negate n) of (r,e) -> case countTrailingZeros e of k -> (negate $ fromInteger (sqr k r), e `shiftR` k) | otherwise = case integerHighPower n of (r,e) -> (fromInteger r, e) where n :: Integer n = toInteger n' sqr :: Int -> Integer -> Integer sqr 0 m = m sqr k m = sqr (k-1) (m*m) ------------------------------------------------------------------------------------------ -- Auxiliary functions -- ------------------------------------------------------------------------------------------ newtonK :: Integer -> Integer -> Integer -> Integer newtonK k n a = go (step a) where step m = ((k - 1) * m + n `quot` m ^ (k - 1)) `quot` k go m | l < m = go l | otherwise = m where l = step m -- find an approximation to the k-th root -- here, k > 4 and n > 31 appKthRoot :: Int -> Integer -> Integer appKthRoot (I# k#) (IS n#) = IS (double2Int# (int2Double# n# **## (1.0## /## int2Double# k#))) #ifdef MIN_VERSION_integer_gmp appKthRoot k@(I# k#) n | k >= 256 = 1 `shiftLInteger` (integerLog2# n `quotInt#` k# +# 1#) | otherwise = case integerLog2# n of l# -> case l# `quotInt#` k# of 0# -> 1 1# -> 3 2# -> 5 3# -> 11 h# | isTrue# (h# <# 500#) -> floor (scaleFloat (I# h#) (fromInteger (n `shiftRInteger` (h# *# k#)) ** (1/fromIntegral k) :: Double)) | otherwise -> floor (scaleFloat 400 (fromInteger (n `shiftRInteger` (h# *# k#)) ** (1/fromIntegral k) :: Double)) `shiftLInteger` (h# -# 400#) #else appKthRoot k@(fromIntegral -> W# k#) n | k >= 256 = 1 `integerShiftL#` (integerLog2# n `quotWord#` k# `plusWord#` 1##) | otherwise = case integerLog2# n of l# -> case l# `quotWord#` k# of 0## -> 1 1## -> 3 2## -> 5 3## -> 11 h# | isTrue# (h# `ltWord#` 500##) -> floor (scaleFloat (I# (word2Int# h#)) (fromInteger (n `integerShiftR#` (h# `timesWord#` k#)) ** (1/fromIntegral k) :: Double)) | otherwise -> floor (scaleFloat 400 (fromInteger (n `integerShiftR#` (h# `timesWord#` k#)) ** (1/fromIntegral k) :: Double)) `integerShiftL#` (h# `minusWord#` 400##) #endif -- assumption: argument is > 1 integerHighPower :: Integer -> (Integer, Word) integerHighPower n | n < 4 = (n,1) | otherwise = case splitOff 2 n of (e2,m) | m == 1 -> (2,e2) | otherwise -> findHighPower e2 (if e2 == 0 then [] else [(2,e2)]) m r smallOddPrimes where r = P2.integerSquareRoot m findHighPower :: Word -> [(Integer, Word)] -> Integer -> Integer -> [Integer] -> (Integer, Word) findHighPower 1 pws m _ _ = (foldl' (*) m [p^e | (p,e) <- pws], 1) findHighPower e pws 1 _ _ = (foldl' (*) 1 [p^(ex `quot` e) | (p,ex) <- pws], e) findHighPower e pws m s (p:ps) | s < p = findHighPower 1 pws m s [] | otherwise = case splitOff p m of (0,_) -> findHighPower e pws m s ps (k,r) -> findHighPower (gcd k e) ((p,k):pws) r (P2.integerSquareRoot r) ps findHighPower e pws m _ [] = finishPower e pws m splitOff :: Integer -> Integer -> (Word, Integer) splitOff !_ 0 = (0, 0) -- prevent infinite loop splitOff p n = go 0 n where go !k m = case m `quotRem` p of (q, 0) -> go (k + 1) q _ -> (k, m) {-# INLINABLE splitOff #-} smallOddPrimes :: [Integer] smallOddPrimes = takeWhile (< spBound) $ map (\(I# k#) -> IS (word2Int# ( #if MIN_VERSION_base(4,16,0) #ifdef WORDS_BIGENDIAN byteSwap16# (word16ToWord# (indexWord16OffAddr# smallPrimesAddr# k#)) #else word16ToWord# (indexWord16OffAddr# smallPrimesAddr# k#) #endif #else #ifdef WORDS_BIGENDIAN byteSwap16# (indexWord16OffAddr# smallPrimesAddr# k#) #else indexWord16OffAddr# smallPrimesAddr# k# #endif #endif ))) [1 .. smallPrimesLength - 1] where !(Ptr smallPrimesAddr#) = smallPrimesPtr spBEx :: Word spBEx = 14 spBound :: Integer spBound = 2^spBEx -- n large, has no prime divisors < spBound finishPower :: Word -> [(Integer, Word)] -> Integer -> (Integer, Word) finishPower e pws n | n < (1 `shiftL` wordToInt (2*spBEx)) = (foldl' (*) n [p^ex | (p,ex) <- pws], 1) -- n is prime | e == 0 = rawPower maxExp n | otherwise = go divs where #ifdef MIN_VERSION_integer_gmp maxExp = (W# (int2Word# (integerLog2# n))) `quot` spBEx #else maxExp = (W# (integerLog2# n)) `quot` spBEx #endif divs = divisorsTo maxExp e go [] = (foldl' (*) n [p^ex | (p,ex) <- pws], 1) go (d:ds) = case exactRoot d n of Just r -> (foldl' (*) r [p^(ex `quot` d) | (p,ex) <- pws], d) Nothing -> go ds rawPower :: Word -> Integer -> (Integer, Word) rawPower mx n | mx < 2 = (n,1) | mx == 2 = case P2.exactSquareRoot n of Just r -> (r,2) Nothing -> (n,1) rawPower mx n = case P4.exactFourthRoot n of Just r -> case rawPower (mx `quot` 4) r of (m,e) -> (m, 4*e) Nothing -> case P2.exactSquareRoot n of Just r -> case rawOddPower (mx `quot` 2) r of (m,e) -> (m, 2*e) Nothing -> rawOddPower mx n rawOddPower :: Word -> Integer -> (Integer, Word) rawOddPower mx n | mx < 3 = (n,1) rawOddPower mx n = case P3.exactCubeRoot n of Just r -> case rawOddPower (mx `quot` 3) r of (m,e) -> (m, 3*e) Nothing -> badPower mx n badPower :: Word -> Integer -> (Integer, Word) badPower mx n | mx < 5 = (n,1) | otherwise = go 1 mx n (takeWhile (<= mx) $ scanl (+) 5 $ cycle [2,4]) where go !e b m (k:ks) | b < k = (m,e) | otherwise = case exactRoot k m of Just r -> go (e*k) (b `quot` k) r (k:ks) Nothing -> go e b m ks go e _ m [] = (m,e) -- | List divisors of n, which are <= mx. divisorsTo :: Word -> Word -> [Word] divisorsTo mx n = sortBy (flip compare) $ go [1] n (2 : 3 : 5 : prs) where -- unP p m = (k, m / p ^ k), where k is as large as possible such that p ^ k still divides m unP :: Word -> Word -> (Word, Word) unP p m = goP 0 m where goP :: Word -> Word -> (Word, Word) goP !i j = case j `quotRem` p of (q,r) | r == 0 -> goP (i+1) q | otherwise -> (i,j) mset k = filter (<= mx) . map (* k) prs :: [Word] prs = 7 : filter prm (scanl (+) 11 $ cycle [2, 4, 2, 4, 6, 2, 6, 4]) prm :: Word -> Bool prm k = td prs where td (p:ps) = (p*p > k) || (k `rem` p /= 0 && td ps) td [] = True go !st m (p:ps) | m == 1 = st | m < p*p = st ++ mset m st | otherwise = case unP p m of (0,_) -> go st m ps -- iterate f x = [x, f x, f (f x)...] (k,r) -> go (concat (take (wordToInt k + 1) (iterate (mset p) st))) r ps go st m [] = go st m [m+1] integer-roots-1.0.2.0/Math/NumberTheory/Roots/Squares.hs0000644000000000000000000002014707346545000021247 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.Squares -- Copyright: (c) 2011 Daniel Fischer, 2016-2020 Andrew Lelechenko -- Licence: MIT -- Maintainer: Daniel Fischer -- -- Functions dealing with squares. Efficient calculation of integer square roots -- and efficient testing for squareness. {-# LANGUAGE BangPatterns #-} {-# LANGUAGE MagicHash #-} module Math.NumberTheory.Roots.Squares ( -- * Square root calculation integerSquareRoot , integerSquareRoot' , integerSquareRootRem , integerSquareRootRem' , exactSquareRoot -- * Tests for squares , isSquare , isSquare' , isPossibleSquare ) where import Data.Bits (finiteBitSize, (.&.)) import GHC.Exts (Ptr(..)) import Numeric.Natural (Natural) import Math.NumberTheory.Roots.Squares.Internal import Math.NumberTheory.Utils.BitMask (indexBitSet) -- | For a non-negative input \( n \) -- calculate its integer square root \( \lfloor \sqrt{n} \rfloor \). -- Throw an error on negative input. -- -- >>> integerSquareRoot 99 -- 9 -- >>> integerSquareRoot 100 -- 10 -- >>> integerSquareRoot 101 -- 10 {-# SPECIALISE integerSquareRoot :: Int -> Int, Word -> Word, Integer -> Integer, Natural -> Natural #-} integerSquareRoot :: Integral a => a -> a integerSquareRoot n | n < 0 = error "integerSquareRoot: negative argument" | otherwise = integerSquareRoot' n -- | Calculate the integer square root of a non-negative number @n@, -- that is, the largest integer @r@ with @r*r <= n@. -- The precondition @n >= 0@ is not checked. {-# RULES "integerSquareRoot'/Int" integerSquareRoot' = isqrtInt' "integerSquareRoot'/Word" integerSquareRoot' = isqrtWord "integerSquareRoot'/Integer" integerSquareRoot' = isqrtInteger #-} {-# INLINE [1] integerSquareRoot' #-} integerSquareRoot' :: Integral a => a -> a integerSquareRoot' = isqrtA -- | For a non-negative input \( n \) -- calculate its integer square root \( r = \lfloor \sqrt{n} \rfloor \) -- and remainder \( s = n - r^2 \). -- Throw an error on negative input. -- -- >>> integerSquareRootRem 99 -- (9,18) -- >>> integerSquareRootRem 100 -- (10,0) -- >>> integerSquareRootRem 101 -- (10,1) {-# SPECIALISE integerSquareRootRem :: Int -> (Int, Int), Word -> (Word, Word), Integer -> (Integer, Integer), Natural -> (Natural, Natural) #-} integerSquareRootRem :: Integral a => a -> (a, a) integerSquareRootRem n | n < 0 = error "integerSquareRootRem: negative argument" | otherwise = integerSquareRootRem' n -- | Calculate the integer square root of a non-negative number as well as -- the difference of that number with the square of that root, that is if -- @(s,r) = integerSquareRootRem' n@ then @s^2 <= n == s^2+r < (s+1)^2@. -- The precondition @n >= 0@ is not checked. {-# RULES "integerSquareRootRem'/Integer" integerSquareRootRem' = karatsubaSqrt #-} {-# INLINE [1] integerSquareRootRem' #-} integerSquareRootRem' :: Integral a => a -> (a, a) integerSquareRootRem' n = (s, n - s * s) where s = integerSquareRoot' n -- | Calculate the exact integer square root if it exists, -- otherwise return 'Nothing'. -- -- >>> map exactSquareRoot [-100, 99, 100, 101] -- [Nothing,Nothing,Just 10,Nothing] {-# SPECIALISE exactSquareRoot :: Int -> Maybe Int, Word -> Maybe Word, Integer -> Maybe Integer, Natural -> Maybe Natural #-} exactSquareRoot :: Integral a => a -> Maybe a exactSquareRoot n | n >= 0 , isPossibleSquare n , (r, 0) <- integerSquareRootRem' n = Just r | otherwise = Nothing -- | Test whether the argument is a perfect square. -- -- >>> map isSquare [-100, 99, 100, 101] -- [False,False,True,False] {-# SPECIALISE isSquare :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isSquare :: Integral a => a -> Bool isSquare n = n >= 0 && isSquare' n -- | Test whether the input (a non-negative number) @n@ is a square. -- The same as 'isSquare', but without the negativity test. -- Faster if many known positive numbers are tested. -- -- The precondition @n >= 0@ is not tested, passing negative -- arguments may cause any kind of havoc. {-# SPECIALISE isSquare' :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isSquare' :: Integral a => a -> Bool isSquare' n | isPossibleSquare n , (_, 0) <- integerSquareRootRem' n = True | otherwise = False -- | Test whether a non-negative number may be a square. -- Non-negativity is not checked, passing negative arguments may -- cause any kind of havoc. -- -- First the remainder modulo 256 is checked (that can be calculated -- easily without division and eliminates about 82% of all numbers). -- After that, the remainders modulo 9, 25, 7, 11 and 13 are tested -- to eliminate altogether about 99.436% of all numbers. {-# SPECIALISE isPossibleSquare :: Int -> Bool, Word -> Bool, Integer -> Bool, Natural -> Bool #-} isPossibleSquare :: Integral a => a -> Bool isPossibleSquare n' = indexBitSet mask256 (fromInteger (n .&. 255)) && indexBitSet mask693 (fromInteger (n `rem` 693)) && indexBitSet mask325 (fromInteger (n `rem` 325)) where n = toInteger n' ----------------------------------------------------------------------------- -- Generated by 'Math.NumberTheory.Utils.BitMask.vectorToAddrLiteral' mask256 :: Ptr Word mask256 = Ptr "\DC3\STX\ETX\STX\DC2\STX\STX\STX\DC3\STX\STX\STX\DC2\STX\STX\STX\DC2\STX\ETX\STX\DC2\STX\STX\STX\DC2\STX\STX\STX\DC2\STX\STX\STX"# mask693 :: Ptr Word mask693 = Ptr "\DC3\STXA\STX0\NUL\STX\EOTI\NUL\STX\t\CAN\NUL\NULB\164\NUL\DC1\EOT\b\STX\NUL@P\128@\NUL\STX\t\128 \SOH\DLE\NUL\SOH\130$\NUL\128\DC4(\NUL\NUL\SOH\DC2\NUL\f\STX\DC4\SOH\NUL \b\NUL\"\NUL\128\EOT`\144\NUL\b\129\NULE\DC2\DLE@\STX\EOT\NUL\129\NUL\t\b\EOT\SOH\194\128\NUL\DLE\EOT\NUL\DLE\NUL\NUL"# mask325 :: Ptr Word mask325 = Ptr "\DC3B\SOH&\144\NUL\n!%\140\STXH0\SOH\DC4BJ\b\ENQ\144@\STX(\132\148\DLE\n \131\EOTP\f)!\DC4@\STX\EM\160\DLE\DC2"# -- -- Make an array indicating whether a remainder is a square remainder. -- sqRemArray :: Int -> V.Vector Bool -- sqRemArray md = runST $ do -- ar <- MV.replicate md False -- let !stop = (md `quot` 2) + 1 -- fill k -- | k < stop = MV.unsafeWrite ar ((k*k) `rem` md) True >> fill (k+1) -- | otherwise = return () -- MV.unsafeWrite ar 0 True -- MV.unsafeWrite ar 1 True -- fill 2 -- V.unsafeFreeze ar -- sr256 :: V.Vector Bool -- sr256 = sqRemArray 256 -- sr693 :: V.Vector Bool -- sr693 = sqRemArray 693 -- sr325 :: V.Vector Bool -- sr325 = sqRemArray 325 ----------------------------------------------------------------------------- -- Specialisations for Int, Word, and Integer -- For @n <= 2^64@, the result of -- -- > truncate (sqrt $ fromIntegral n) -- -- is never too small and never more than one too large. -- The multiplication doesn't overflow for 32 or 64 bit Ints. isqrtInt' :: Int -> Int isqrtInt' n | n < r*r = r-1 | otherwise = r where !r = (truncate :: Double -> Int) . sqrt $ fromIntegral n -- With -O2, that should be translated to the below {- isqrtInt' n@(I# i#) | r# *# r# ># i# = I# (r# -# 1#) | otherwise = I# r# where !r# = double2Int# (sqrtDouble# (int2Double# i#)) -} -- Same for Word. isqrtWord :: Word -> Word isqrtWord n | n < (r*r) -- Double interprets values near maxBound as 2^64, we don't have that problem for 32 bits || finiteBitSize (0 :: Word) == 64 && r == 4294967296 = r-1 | otherwise = r where !r = (fromIntegral :: Int -> Word) . (truncate :: Double -> Int) . sqrt $ fromIntegral n {-# INLINE isqrtInteger #-} isqrtInteger :: Integer -> Integer isqrtInteger = fst . karatsubaSqrt integer-roots-1.0.2.0/Math/NumberTheory/Roots/Squares/0000755000000000000000000000000007346545000020707 5ustar0000000000000000integer-roots-1.0.2.0/Math/NumberTheory/Roots/Squares/Internal.hs0000644000000000000000000001213307346545000023017 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.Squares.Internal -- Copyright: (c) 2011 Daniel Fischer, 2016-2020 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Internal functions dealing with square roots. End-users should not import this module. {-# LANGUAGE BangPatterns #-} {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} module Math.NumberTheory.Roots.Squares.Internal ( karatsubaSqrt , isqrtA ) where import Data.Bits (finiteBitSize, unsafeShiftL, unsafeShiftR, (.&.), (.|.)) import GHC.Exts (Int(..), Int#, isTrue#, int2Double#, sqrtDouble#, double2Int#, (<#)) #ifdef MIN_VERSION_integer_gmp import GHC.Exts (uncheckedIShiftRA#, (*#), (-#)) import GHC.Integer.GMP.Internals (Integer(..), shiftLInteger, shiftRInteger, sizeofBigNat#) import GHC.Integer.Logarithms (integerLog2#) #define IS S# #define IP Jp# #define bigNatSize sizeofBigNat #else import GHC.Exts (uncheckedShiftRL#, word2Int#, minusWord#, timesWord#) import GHC.Num.BigNat (bigNatSize#) import GHC.Num.Integer (Integer(..), integerLog2#, integerShiftR#, integerShiftL#) #endif -- Find approximation to square root in 'Integer', then -- find the integer square root by the integer variant -- of Heron's method. Takes only a handful of steps -- unless the input is really large. {-# SPECIALISE isqrtA :: Integer -> Integer #-} isqrtA :: Integral a => a -> a isqrtA 0 = 0 isqrtA n = heron n (fromInteger . appSqrt . fromIntegral $ n) -- Heron's method for integers. First make one step to ensure -- the value we're working on is @>= r@, then we have -- @k == r@ iff @k <= step k@. {-# SPECIALISE heron :: Integer -> Integer -> Integer #-} heron :: Integral a => a -> a -> a heron n a = go (step a) where step k = (k + n `quot` k) `quot` 2 go k | m < k = go m | otherwise = k where m = step k -- Find a fairly good approximation to the square root. -- At most one off for small Integers, about 48 bits should be correct -- for large Integers. appSqrt :: Integer -> Integer appSqrt (IS i#) = IS (double2Int# (sqrtDouble# (int2Double# i#))) appSqrt n@(IP bn#) | isTrue# ((bigNatSize# bn#) <# thresh#) = floor (sqrt $ fromInteger n :: Double) | otherwise = case integerLog2# n of #ifdef MIN_VERSION_integer_gmp l# -> case uncheckedIShiftRA# l# 1# -# 47# of h# -> case shiftRInteger n (2# *# h#) of m -> case floor (sqrt $ fromInteger m :: Double) of r -> shiftLInteger r h# #else l# -> case uncheckedShiftRL# l# 1# `minusWord#` 47## of h# -> case integerShiftR# n (2## `timesWord#` h#) of m -> case floor (sqrt $ fromInteger m :: Double) of r -> integerShiftL# r h# #endif where -- threshold for shifting vs. direct fromInteger -- we shift when we expect more than 256 bits thresh# :: Int# thresh# = if finiteBitSize (0 :: Word) == 64 then 5# else 9# -- There's already a check for negative in integerSquareRoot, -- but integerSquareRoot' is exported directly too. appSqrt _ = error "integerSquareRoot': negative argument" -- Integer square root with remainder, using the Karatsuba Square Root -- algorithm from -- Paul Zimmermann. Karatsuba Square Root. [Research Report] RR-3805, 1999, -- pp.8. karatsubaSqrt :: Integer -> (Integer, Integer) karatsubaSqrt 0 = (0, 0) karatsubaSqrt n | lgN < 2300 = let s = isqrtA n in (s, n - s * s) | otherwise = if lgN .&. 2 /= 0 then karatsubaStep k (karatsubaSplit k n) else -- before we split n into 4 part we must ensure that the first part -- is at least 2^k/4, since this doesn't happen here we scale n by -- multiplying it by 4 let n' = n `unsafeShiftL` 2 (s, r) = karatsubaStep k (karatsubaSplit k n') r' | s .&. 1 == 0 = r | otherwise = r + double s - 1 in (s `unsafeShiftR` 1, r' `unsafeShiftR` 2) where k = lgN `unsafeShiftR` 2 + 1 #ifdef MIN_VERSION_integer_gmp lgN = I# (integerLog2# n) #else lgN = I# (word2Int# (integerLog2# n)) #endif karatsubaStep :: Int -> (Integer, Integer, Integer, Integer) -> (Integer, Integer) karatsubaStep k (a3, a2, a1, a0) | r >= 0 = (s, r) | otherwise = (s - 1, r + double s - 1) where r = cat u a0 - q * q s = s' `unsafeShiftL` k + q (q, u) = cat r' a1 `quotRem` double s' (s', r') = karatsubaSqrt (cat a3 a2) cat x y = x `unsafeShiftL` k .|. y {-# INLINE cat #-} karatsubaSplit :: Int -> Integer -> (Integer, Integer, Integer, Integer) karatsubaSplit k n0 = (a3, a2, a1, a0) where a3 = n3 n3 = n2 `unsafeShiftR` k a2 = n2 .&. m n2 = n1 `unsafeShiftR` k a1 = n1 .&. m n1 = n0 `unsafeShiftR` k a0 = n0 .&. m m = 1 `unsafeShiftL` k - 1 double :: Integer -> Integer double x = x `unsafeShiftL` 1 {-# INLINE double #-} integer-roots-1.0.2.0/Math/NumberTheory/Utils/0000755000000000000000000000000007346545000017256 5ustar0000000000000000integer-roots-1.0.2.0/Math/NumberTheory/Utils/BitMask.hs0000644000000000000000000000277407346545000021156 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Utils.BitMask -- Copyright: (c) 2020 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Bit mask utilities. -- {-# LANGUAGE CPP #-} {-# LANGUAGE MagicHash #-} module Math.NumberTheory.Utils.BitMask ( indexBitSet -- , vectorToAddrLiteral ) where #include "MachDeps.h" import Data.Bits (countTrailingZeros, finiteBitSize, testBit, (.&.)) import GHC.Exts (Int(..), Word(..), Ptr(..), iShiftRL#, indexWordOffAddr#) #ifdef WORDS_BIGENDIAN import GHC.Exts (byteSwap#) #endif -- import Data.Bits (unsafeShiftL) -- import Data.List (unfoldr) -- import Data.Char (chr) indexBitSet :: Ptr Word -> Int -> Bool indexBitSet (Ptr addr#) i@(I# i#) = word `testBit` (i .&. (fbs - 1)) where fbs = finiteBitSize (0 :: Word) logFbs# = case countTrailingZeros fbs of I# l# -> l# word# = indexWordOffAddr# addr# (i# `iShiftRL#` logFbs#) #ifdef WORDS_BIGENDIAN word = W# (byteSwap# word#) #else word = W# word# #endif -- vectorToAddrLiteral :: [Bool] -> String -- vectorToAddrLiteral = map (chr . toByte . padTo8) . unfoldr go -- where -- go :: [a] -> Maybe ([a], [a]) -- go [] = Nothing -- go xs = Just (take 8 xs, drop 8 xs) -- padTo8 :: [Bool] -> [Bool] -- padTo8 xs -- | length xs >= 8 = xs -- | otherwise = xs ++ replicate (8 - length xs) False -- toByte :: [Bool] -> Int -- toByte xs = sum $ map (\i -> if xs !! i then 1 `unsafeShiftL` i else 0) [0..7] integer-roots-1.0.2.0/Math/NumberTheory/Utils/FromIntegral.hs0000644000000000000000000000222307346545000022202 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Utils.FromIntegral -- Copyright: (c) 2017 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Monomorphic `fromIntegral`. -- module Math.NumberTheory.Utils.FromIntegral ( wordToInt , wordToInteger , intToWord , intToInteger , naturalToInteger , integerToNatural , integerToWord , integerToInt ) where import Numeric.Natural (Natural) wordToInt :: Word -> Int wordToInt = fromIntegral {-# INLINE wordToInt #-} wordToInteger :: Word -> Integer wordToInteger = fromIntegral {-# INLINE wordToInteger #-} intToWord :: Int -> Word intToWord = fromIntegral {-# INLINE intToWord #-} intToInteger :: Int -> Integer intToInteger = fromIntegral {-# INLINE intToInteger #-} naturalToInteger :: Natural -> Integer naturalToInteger = fromIntegral {-# INLINE naturalToInteger #-} integerToNatural :: Integer -> Natural integerToNatural = fromIntegral {-# INLINE integerToNatural #-} integerToWord :: Integer -> Word integerToWord = fromIntegral {-# INLINE integerToWord #-} integerToInt :: Integer -> Int integerToInt = fromIntegral {-# INLINE integerToInt #-} integer-roots-1.0.2.0/README.md0000644000000000000000000000602107346545000014120 0ustar0000000000000000# integer-roots [![Hackage](http://img.shields.io/hackage/v/integer-roots.svg)](https://hackage.haskell.org/package/integer-roots) [![Stackage LTS](http://stackage.org/package/integer-roots/badge/lts)](http://stackage.org/lts/package/integer-roots) [![Stackage Nightly](http://stackage.org/package/integer-roots/badge/nightly)](http://stackage.org/nightly/package/integer-roots) Calculating integer roots and testing perfect powers of arbitrary precision. ## Integer square root The [integer square root](https://en.wikipedia.org/wiki/Integer_square_root) (`integerSquareRoot`) of a non-negative integer _n_ is the greatest integer _m_ such that . Alternatively, in terms of the [floor function](https://en.wikipedia.org/wiki/Floor_and_ceiling_functions), . For example, ```haskell > integerSquareRoot 99 9 > integerSquareRoot 101 10 ``` It is tempting to implement `integerSquareRoot` via `sqrt :: Double -> Double`: ```haskell integerSquareRoot :: Integer -> Integer integerSquareRoot = truncate . sqrt . fromInteger ``` However, this implementation is faulty: ```haskell > integerSquareRoot (3037000502^2) 3037000501 > integerSquareRoot (2^1024) == 2^1024 True ``` The problem here is that `Double` can represent only a limited subset of integers without precision loss. Once we encounter larger integers, we lose precision and obtain all kinds of wrong results. This library features a polymorphic, efficient and robust routine `integerSquareRoot :: Integral a => a -> a`, which computes integer square roots by [Karatsuba square root algorithm](https://hal.inria.fr/inria-00072854/PDF/RR-3805.pdf) without intermediate `Double`s. ## Integer cube roots The integer cube root (`integerCubeRoot`) of an integer _n_ equals to . Again, a naive approach is to implement `integerCubeRoot` via `Double`-typed computations: ```haskell integerCubeRoot :: Integer -> Integer integerCubeRoot = truncate . (** (1/3)) . fromInteger ``` Here the precision loss is even worse than for `integerSquareRoot`: ```haskell > integerCubeRoot (4^3) 3 > integerCubeRoot (5^3) 4 ``` That is why we provide a robust implementation of `integerCubeRoot :: Integral a => a -> a`, which computes roots by [generalized Heron algorithm](https://en.wikipedia.org/wiki/Nth_root_algorithm). ## Higher powers In spirit of `integerSquareRoot` and `integerCubeRoot` this library covers the general case as well, providing `integerRoot :: (Integral a, Integral b) => b -> a -> a` to compute integer _k_-th roots of arbitrary precision. There is also `highestPower` routine, which tries hard to represent its input as a power with as large exponent as possible. This is a useful function in number theory, e. g., elliptic curve factorisation. ```haskell > map highestPower [2..10] [(2,1),(3,1),(2,2),(5,1),(6,1),(7,1),(2,3),(3,2),(10,1)] ``` integer-roots-1.0.2.0/changelog.md0000644000000000000000000000026207346545000015113 0ustar0000000000000000# 1.0.2.0 * More fixes for big-endian architectures. # 1.0.1.0 * Fixes for big-endian architectures. # 1.0.0.1 * Compatibility fixes for GHC 9.2. # 1.0 * Initial release. integer-roots-1.0.2.0/integer-roots.cabal0000644000000000000000000000452307346545000016433 0ustar0000000000000000name: integer-roots version: 1.0.2.0 cabal-version: >=1.10 build-type: Simple license: MIT license-file: LICENSE copyright: (c) 2011 Daniel Fischer, 2016-2021 Andrew Lelechenko. maintainer: Andrew Lelechenko andrew dot lelechenko at gmail dot com homepage: https://github.com/Bodigrim/integer-roots bug-reports: https://github.com/Bodigrim/integer-roots/issues synopsis: Integer roots and perfect powers description: Calculating integer roots and testing perfect powers of arbitrary precision. Originally part of package. category: Math, Algorithms, Number Theory author: Daniel Fischer, Andrew Lelechenko tested-with: GHC ==8.0.2 GHC ==8.2.2 GHC ==8.4.4 GHC ==8.6.5 GHC ==8.8.4 GHC ==8.10.7 GHC ==9.0.1 GHC ==9.2.1 extra-source-files: changelog.md README.md source-repository head type: git location: https://github.com/Bodigrim/integer-roots library build-depends: base >=4.9 && <5 if impl(ghc < 9.0) build-depends: integer-gmp <1.2 else build-depends: ghc-bignum < 1.3 exposed-modules: Math.NumberTheory.Roots other-modules: Math.NumberTheory.Primes.Small Math.NumberTheory.Roots.Cubes Math.NumberTheory.Roots.Fourth Math.NumberTheory.Roots.General Math.NumberTheory.Roots.Squares Math.NumberTheory.Roots.Squares.Internal Math.NumberTheory.Utils.BitMask Math.NumberTheory.Utils.FromIntegral default-language: Haskell2010 ghc-options: -Wall -Widentities -Wcompat test-suite integer-roots-tests build-depends: base >=4.9 && <5, integer-roots, smallcheck >=1.2 && <1.3, tasty >=0.10, tasty-hunit >=0.9 && <0.11, tasty-quickcheck >=0.9 && <0.11, tasty-smallcheck >=0.8 && <0.9 other-modules: Math.NumberTheory.Roots.CubesTests Math.NumberTheory.Roots.FourthTests Math.NumberTheory.Roots.GeneralTests Math.NumberTheory.Roots.SquaresTests Math.NumberTheory.TestUtils Math.NumberTheory.TestUtils.Wrappers type: exitcode-stdio-1.0 main-is: Test.hs default-language: Haskell2010 hs-source-dirs: test-suite ghc-options: -Wall -Widentities -Wcompat test-suite integer-roots-doctests type: exitcode-stdio-1.0 main-is: Doctest.hs hs-source-dirs: test-suite build-depends: base, doctest >= 0.8 default-language: Haskell2010 integer-roots-1.0.2.0/test-suite/0000755000000000000000000000000007346545000014750 5ustar0000000000000000integer-roots-1.0.2.0/test-suite/Doctest.hs0000644000000000000000000000012107346545000016703 0ustar0000000000000000import Test.DocTest main :: IO () main = doctest ["Math/NumberTheory/Roots.hs"] integer-roots-1.0.2.0/test-suite/Math/NumberTheory/Roots/0000755000000000000000000000000007346545000021372 5ustar0000000000000000integer-roots-1.0.2.0/test-suite/Math/NumberTheory/Roots/CubesTests.hs0000644000000000000000000001003007346545000024004 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.CubesTests -- Copyright: (c) 2016 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Tests for Math.NumberTheory.Roots.Cubes -- {-# OPTIONS_GHC -fno-warn-type-defaults #-} module Math.NumberTheory.Roots.CubesTests ( testSuite ) where import Data.Bits import Test.Tasty import Test.Tasty.HUnit import Math.NumberTheory.Roots import Math.NumberTheory.TestUtils -- | Check that 'integerCubeRoot' returns the largest integer @m@ with @m^3 <= n@. integerCubeRootProperty :: Integral a => AnySign a -> Bool integerCubeRootProperty (AnySign n) = toInteger m ^ 3 <= toInteger n && toInteger n < (toInteger m + 1) ^ 3 where m = integerCubeRoot n -- | Specialized to trigger 'cubeRootInt''. integerCubeRootProperty_Int :: AnySign Int -> Bool integerCubeRootProperty_Int = integerCubeRootProperty -- | Specialized to trigger 'cubeRootWord'. integerCubeRootProperty_Word :: AnySign Word -> Bool integerCubeRootProperty_Word = integerCubeRootProperty -- | Specialized to trigger 'cubeRootIgr'. integerCubeRootProperty_Integer :: AnySign Integer -> Bool integerCubeRootProperty_Integer = integerCubeRootProperty -- | Check that 'integerCubeRoot' returns the largest integer @m@ with @m^3 <= n@, where @n@ has form @k@^3-1. integerCubeRootProperty2 :: Integral a => AnySign a -> Bool integerCubeRootProperty2 (AnySign k) = k == 0 || toInteger m ^ 3 <= toInteger n && toInteger n < (toInteger m + 1) ^ 3 where n = k ^ 3 - 1 m = integerCubeRoot n -- | Specialized to trigger 'cubeRootInt''. integerCubeRootProperty2_Int :: AnySign Int -> Bool integerCubeRootProperty2_Int = integerCubeRootProperty2 -- | Specialized to trigger 'cubeRootWord'. integerCubeRootProperty2_Word :: AnySign Word -> Bool integerCubeRootProperty2_Word = integerCubeRootProperty2 -- | Check that 'integerCubeRoot' of 2^63-1 is 2^21-1, not 2^21. integerCubeRootSpecialCase1_Int :: Assertion integerCubeRootSpecialCase1_Int = assertEqual "integerCubeRoot" (integerCubeRoot (maxBound :: Int)) (2 ^ 21 - 1) -- | Check that 'integerCubeRoot' of 2^63-1 is 2^21-1, not 2^21. integerCubeRootSpecialCase1_Word :: Assertion integerCubeRootSpecialCase1_Word = assertEqual "integerCubeRoot" (integerCubeRoot (maxBound `div` 2 :: Word)) (2 ^ 21 - 1) -- | Check that 'integerCubeRoot' of 2^64-1 is 2642245. integerCubeRootSpecialCase2 :: Assertion integerCubeRootSpecialCase2 = assertEqual "integerCubeRoot" (integerCubeRoot (maxBound :: Word)) 2642245 -- | Check that the number 'isCube' iff its 'integerCubeRoot' is exact. isCubeProperty :: Integral a => AnySign a -> Bool isCubeProperty (AnySign n) = (n /= m ^ 3 && not t) || (n == m ^ 3 && t) where t = isCube n m = integerCubeRoot n -- | Check that 'exactCubeRoot' returns an exact integer cubic root -- and is consistent with 'isCube'. exactCubeRootProperty :: Integral a => AnySign a -> Bool exactCubeRootProperty (AnySign n) = case exactCubeRoot n of Nothing -> not (isCube n) Just m -> isCube n && n == m ^ 3 testSuite :: TestTree testSuite = testGroup "Cubes" [ testGroup "integerCubeRoot" $ [ testIntegralProperty "generic" integerCubeRootProperty , testSmallAndQuick "generic Int" integerCubeRootProperty_Int , testSmallAndQuick "generic Word" integerCubeRootProperty_Word , testSmallAndQuick "generic Integer" integerCubeRootProperty_Integer , testIntegralProperty "almost cube" integerCubeRootProperty2 , testSmallAndQuick "almost cube Int" integerCubeRootProperty2_Int , testSmallAndQuick "almost cube Word" integerCubeRootProperty2_Word ] ++ if finiteBitSize (0 :: Word) /= 64 then [] else [ testCase "maxBound :: Int" integerCubeRootSpecialCase1_Int , testCase "maxBound / 2 :: Word" integerCubeRootSpecialCase1_Word , testCase "maxBound :: Word" integerCubeRootSpecialCase2 ] , testIntegralProperty "isCube" isCubeProperty , testIntegralProperty "exactCubeRoot" exactCubeRootProperty ] integer-roots-1.0.2.0/test-suite/Math/NumberTheory/Roots/FourthTests.hs0000644000000000000000000001132507346545000024222 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.FourthTests -- Copyright: (c) 2016 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Tests for Math.NumberTheory.Roots.Fourth -- {-# OPTIONS_GHC -fno-warn-type-defaults #-} module Math.NumberTheory.Roots.FourthTests ( testSuite ) where import Data.Bits import Test.Tasty import Test.Tasty.HUnit import Math.NumberTheory.Roots import Math.NumberTheory.TestUtils integerFourthRoot :: Integral a => a -> a integerFourthRoot = integerRoot 4 {-# INLINE integerFourthRoot #-} isFourthPower :: Integral a => a -> Bool isFourthPower = isKthPower 4 {-# INLINE isFourthPower #-} exactFourthRoot :: Integral a => a -> Maybe a exactFourthRoot = exactRoot 4 {-# INLINE exactFourthRoot #-} -- | Check that 'integerFourthRoot' returns the largest integer @m@ with @m^4 <= n@. -- -- (m + 1) ^ 4 /= n && (m + 1) ^ 3 >= n `div` (m + 1) -- means -- (m + 1) ^ 4 > n -- but without overflow for bounded types integerFourthRootProperty :: Integral a => NonNegative a -> Bool integerFourthRootProperty (NonNegative n) = m >= 0 && m ^ 4 <= n && (m + 1) ^ 4 /= n && (m + 1) ^ 3 >= n `div` (m + 1) where m = integerFourthRoot n -- | Specialized to trigger 'biSqrtInt'. integerFourthRootProperty_Int :: NonNegative Int -> Bool integerFourthRootProperty_Int = integerFourthRootProperty -- | Specialized to trigger 'biSqrtWord'. integerFourthRootProperty_Word :: NonNegative Word -> Bool integerFourthRootProperty_Word = integerFourthRootProperty -- | Specialized to trigger 'biSqrtIgr'. integerFourthRootProperty_Integer :: NonNegative Integer -> Bool integerFourthRootProperty_Integer = integerFourthRootProperty -- | Check that 'integerFourthRoot' returns the largest integer @m@ with @m^4 <= n@, , where @n@ has form @k@^4-1. integerFourthRootProperty2 :: Integral a => Positive a -> Bool integerFourthRootProperty2 (Positive k) = n < 0 || m >= 0 && m ^ 4 <= n && (m + 1) ^ 4 /= n && (m + 1) ^ 3 >= n `div` (m + 1) where n = k ^ 4 - 1 m = integerFourthRoot n -- | Specialized to trigger 'biSqrtInt. integerFourthRootProperty2_Int :: Positive Int -> Bool integerFourthRootProperty2_Int = integerFourthRootProperty2 -- | Specialized to trigger 'biSqrtWord'. integerFourthRootProperty2_Word :: Positive Word -> Bool integerFourthRootProperty2_Word = integerFourthRootProperty2 -- | Check that 'integerFourthRoot' of 2^60-1 is 2^15-1, not 2^15. integerFourthRootSpecialCase1_Int :: Assertion integerFourthRootSpecialCase1_Int = assertEqual "integerFourthRoot" (integerFourthRoot (maxBound `div` 8 :: Int)) (2 ^ 15 - 1) -- | Check that 'integerFourthRoot' of 2^60-1 is 2^15-1, not 2^15. integerFourthRootSpecialCase1_Word :: Assertion integerFourthRootSpecialCase1_Word = assertEqual "integerFourthRoot" (integerFourthRoot (maxBound `div` 16 :: Word)) (2 ^ 15 - 1) -- | Check that 'integerFourthRoot' of 2^64-1 is 2^16-1, not 2^16. integerFourthRootSpecialCase2 :: Assertion integerFourthRootSpecialCase2 = assertEqual "integerFourthRoot" (integerFourthRoot (maxBound :: Word)) (2 ^ 16 - 1) -- | Check that the number 'isFourthPower' iff its 'integerFourthRoot' is exact. isFourthPowerProperty :: Integral a => AnySign a -> Bool isFourthPowerProperty (AnySign n) = (n < 0 && not t) || (n /= m ^ 4 && not t) || (n == m ^ 4 && t) where t = isFourthPower n m = integerFourthRoot n -- | Check that 'exactFourthRoot' returns an exact integer root of fourth power -- and is consistent with 'isFourthPower'. exactFourthRootProperty :: Integral a => AnySign a -> Bool exactFourthRootProperty (AnySign n) = case exactFourthRoot n of Nothing -> not (isFourthPower n) Just m -> isFourthPower n && n == m ^ 4 testSuite :: TestTree testSuite = testGroup "Fourth" [ testGroup "integerFourthRoot" $ [ testIntegralProperty "generic" integerFourthRootProperty , testSmallAndQuick "generic Int" integerFourthRootProperty_Int , testSmallAndQuick "generic Word" integerFourthRootProperty_Word , testSmallAndQuick "generic Integer" integerFourthRootProperty_Integer , testIntegralProperty "almost Fourth" integerFourthRootProperty2 , testSmallAndQuick "almost Fourth Int" integerFourthRootProperty2_Int , testSmallAndQuick "almost Fourth Word" integerFourthRootProperty2_Word ] ++ if finiteBitSize (0 :: Word) /= 64 then [] else [ testCase "maxBound / 8 :: Int" integerFourthRootSpecialCase1_Int , testCase "maxBound / 16 :: Word" integerFourthRootSpecialCase1_Word , testCase "maxBound :: Word" integerFourthRootSpecialCase2 ] , testIntegralProperty "isFourthPower" isFourthPowerProperty , testIntegralProperty "exactFourthRoot" exactFourthRootProperty ] integer-roots-1.0.2.0/test-suite/Math/NumberTheory/Roots/GeneralTests.hs0000644000000000000000000001131307346545000024325 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.GeneralTests -- Copyright: (c) 2016 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Tests for Math.NumberTheory.Roots.General -- {-# OPTIONS_GHC -fno-warn-type-defaults #-} module Math.NumberTheory.Roots.GeneralTests ( testSuite ) where import Test.Tasty import Test.Tasty.HUnit import Test.Tasty.QuickCheck as QC import Numeric.Natural import Math.NumberTheory.Roots import Math.NumberTheory.TestUtils -- | Check that 'integerRoot' @pow@ returns the largest integer @m@ with @m^pow <= n@. integerRootProperty :: (Integral a, Integral b) => AnySign a -> Power b -> Bool integerRootProperty (AnySign n) (Power pow) = (even pow && n < 0) || (pow == 1 && root == n) || (toInteger root ^ pow <= toInteger n && toInteger n < toInteger (root + 1) ^ pow) where root = integerRoot pow n integerRootHugeProperty :: Huge Natural -> Large Word -> Bool integerRootHugeProperty (Huge n) (Large pow') = pow == 0 || toInteger root ^ pow <= toInteger n && toInteger n < toInteger (root + 1) ^ pow where pow = pow' `mod` 2000 root = integerRoot pow n -- | Check that the number 'isKthPower' iff its 'integerRoot' is exact. isKthPowerProperty :: (Integral a, Integral b) => AnySign a -> Power b -> Bool isKthPowerProperty (AnySign n) (Power pow) = (even pow && n < 0 && not t) || (n /= root ^ pow && not t) || (n == root ^ pow && t) where t = isKthPower pow n root = integerRoot pow n -- | Check that 'exactRoot' returns an exact integer root -- and is consistent with 'isKthPower'. exactRootProperty :: (Integral a, Integral b) => AnySign a -> Power b -> Bool exactRootProperty (AnySign n) (Power pow) = case exactRoot pow n of Nothing -> not (isKthPower pow n) Just root -> isKthPower pow n && n == root ^ pow -- | Check that 'isPerfectPower' is consistent with 'highestPower'. isPerfectPowerProperty :: Integral a => AnySign a -> Bool isPerfectPowerProperty (AnySign n) = (k > 1 && t) || (k == 1 && not t) where t = isPerfectPower n (_, k) = highestPower n -- | Check that the first component of 'highestPower' is square-free. highestPowerProperty :: Integral a => AnySign a -> Bool highestPowerProperty (AnySign n) = (n + 1 `elem` [0, 1, 2] && k == 3) || (b ^ k == n && b' == b && k' == 1) where (b, k) = highestPower n (b', k') = highestPower b highestPowerProperty2 :: Integral a => AnySign a -> Bool highestPowerProperty2 (AnySign n) = case k of 1 -> not (isSquare n) && not (isCube n) 2 -> isSquare n && not (isCube n) 3 -> n + 1 `elem` [0, 1, 2] || (not (isSquare n) && isCube n) 4 -> isSquare n && not (isCube n) _ -> all (\l -> isKthPower l n == (k `mod` l == 0)) [1..k] where (_, k) = highestPower n highestPowerSpecialCases :: [Assertion] highestPowerSpecialCases = -- Freezes before d44a13b. [ a ( 1013582159576576 , 1013582159576576 , 1) -- Freezes before d44a13b. , a ( 1013582159576576 ^ 7 , 1013582159576576 , 7) , a ( 9 :: Int , 3 , 2) , a ( -2 ^ 63 :: Int , -2 :: Int , 63) , a ( (2 ^ 63 - 1) ^ 21 , 2 ^ 63 - 1 , 21) , a ( 576116746989720969230211509779286598589421531472851155101032940901763389787901933902294777750323196846498573545522289802689311975294763847414975335235584 , 576116746989720969230211509779286598589421531472851155101032940901763389787901933902294777750323196846498573545522289802689311975294763847414975335235584 , 1) , a ( -340282366920938463500268095579187314689 , -340282366920938463500268095579187314689 , 1) , a ( 268398749 :: Int , 268398749 :: Int , 1) , a ( 118372752099 :: Int , 118372752099 :: Int , 1) , a ( 1409777209 :: Int , 37547 :: Int , 2) , a ( -6277101735386680764856636523970481806547819498980467802113 , -18446744073709551617 , 3) , a ( -18446744073709551619 ^ 5 , -18446744073709551619 , 5) ] where a (n, b, k) = assertEqual "highestPower" (b, k) (highestPower n) testSuite :: TestTree testSuite = testGroup "General" [ testIntegralProperty "integerRoot 1" (`integerRootProperty` 1) , testIntegral2Property "integerRoot" integerRootProperty , QC.testProperty "big integerRoot" integerRootHugeProperty , testIntegral2Property "isKthPower" isKthPowerProperty , testIntegral2Property "exactRoot" exactRootProperty , testIntegralProperty "isPerfectPower" isPerfectPowerProperty , testGroup "highestPower" ( testIntegralProperty "highestPower" highestPowerProperty : testIntegralProperty "highestPower 2" highestPowerProperty2 : zipWith (\i a -> testCase ("special case " ++ show i) a) [1..] highestPowerSpecialCases ) ] integer-roots-1.0.2.0/test-suite/Math/NumberTheory/Roots/SquaresTests.hs0000644000000000000000000001114007346545000024371 0ustar0000000000000000-- | -- Module: Math.NumberTheory.Roots.SquaresTests -- Copyright: (c) 2016 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Tests for Math.NumberTheory.Roots.Squares -- {-# OPTIONS_GHC -fno-warn-type-defaults #-} module Math.NumberTheory.Roots.SquaresTests ( testSuite ) where import Data.Bits import Test.Tasty import Test.Tasty.HUnit import Math.NumberTheory.Roots import Math.NumberTheory.TestUtils -- | Check that 'integerSquareRoot' returns the largest integer @m@ with @m*m <= n@. -- -- (m + 1) ^ 2 /= n && m + 1 >= n `div` (m + 1) -- means -- (m + 1) ^ 2 > n -- but without overflow for bounded types integerSquareRootProperty :: Integral a => NonNegative a -> Bool integerSquareRootProperty (NonNegative n) = m >= 0 && m * m <= n && (m + 1) ^ 2 /= n && m + 1 >= n `div` (m + 1) where m = integerSquareRoot n -- | Specialized to trigger 'isqrtInt''. integerSquareRootProperty_Int :: NonNegative Int -> Bool integerSquareRootProperty_Int = integerSquareRootProperty -- | Specialized to trigger 'isqrtWord'. integerSquareRootProperty_Word :: NonNegative Word -> Bool integerSquareRootProperty_Word = integerSquareRootProperty -- | Specialized to trigger 'isqrtInteger'. integerSquareRootProperty_Integer :: NonNegative Integer -> Bool integerSquareRootProperty_Integer = integerSquareRootProperty -- | Check that 'integerSquareRoot' returns the largest integer @m@ with @m*m <= n@, where @n@ has form @k@^2-1. integerSquareRootProperty2 :: Integral a => Positive a -> Bool integerSquareRootProperty2 (Positive k) = n < 0 || m >= 0 && m * m <= n && (m + 1) ^ 2 /= n && m + 1 >= n `div` (m + 1) where n = k ^ 2 - 1 m = integerSquareRoot n -- | Specialized to trigger 'isqrtInt''. integerSquareRootProperty2_Int :: Positive Int -> Bool integerSquareRootProperty2_Int = integerSquareRootProperty2 -- | Specialized to trigger 'isqrtWord'. integerSquareRootProperty2_Word :: Positive Word -> Bool integerSquareRootProperty2_Word = integerSquareRootProperty2 -- | Specialized to trigger 'isqrtInteger'. integerSquareRootProperty2_Integer :: Positive Integer -> Bool integerSquareRootProperty2_Integer = integerSquareRootProperty2 -- | Check that 'integerSquareRoot' of 2^62-1 is 2^31-1, not 2^31. integerSquareRootSpecialCase1_Int :: Assertion integerSquareRootSpecialCase1_Int = assertEqual "integerSquareRoot" (integerSquareRoot (maxBound `div` 2 :: Int)) (2 ^ 31 - 1) -- | Check that 'integerSquareRoot' of 2^62-1 is 2^31-1, not 2^31. integerSquareRootSpecialCase1_Word :: Assertion integerSquareRootSpecialCase1_Word = assertEqual "integerSquareRoot" (integerSquareRoot (maxBound `div` 4 :: Word)) (2 ^ 31 - 1) -- | Check that 'integerSquareRoot' of 2^64-1 is 2^32-1, not 2^32. integerSquareRootSpecialCase2 :: Assertion integerSquareRootSpecialCase2 = assertEqual "integerSquareRoot" (integerSquareRoot (maxBound :: Word)) (2 ^ 32 - 1) -- | Check that the number 'isSquare' iff its 'integerSquareRoot' is exact. isSquareProperty :: Integral a => AnySign a -> Bool isSquareProperty (AnySign n) = (n < 0 && not t) || (n /= m * m && not t) || (n == m * m && t) where t = isSquare n m = integerSquareRoot n -- | Check that 'exactSquareRoot' returns an exact integer square root -- and is consistent with 'isSquare'. exactSquareRootProperty :: Integral a => AnySign a -> Bool exactSquareRootProperty (AnySign n) = case exactSquareRoot n of Nothing -> not (isSquare n) Just m -> isSquare n && n == m * m testSuite :: TestTree testSuite = testGroup "Squares" [ testGroup "integerSquareRoot" $ [ testIntegralProperty "generic" integerSquareRootProperty , testSmallAndQuick "generic Int" integerSquareRootProperty_Int , testSmallAndQuick "generic Word" integerSquareRootProperty_Word , testSmallAndQuick "generic Integer" integerSquareRootProperty_Integer , testIntegralProperty "almost square" integerSquareRootProperty2 , testSmallAndQuick "almost square Int" integerSquareRootProperty2_Int , testSmallAndQuick "almost square Word" integerSquareRootProperty2_Word , testSmallAndQuick "almost square Integer" integerSquareRootProperty2_Integer ] ++ if finiteBitSize (0 :: Word) /= 64 then [] else [ testCase "maxBound / 2 :: Int" integerSquareRootSpecialCase1_Int , testCase "maxBound / 4 :: Word" integerSquareRootSpecialCase1_Word , testCase "maxBound :: Word" integerSquareRootSpecialCase2 ] , testIntegralProperty "isSquare" isSquareProperty , testIntegralProperty "exactSquareRoot" exactSquareRootProperty ] integer-roots-1.0.2.0/test-suite/Math/NumberTheory/0000755000000000000000000000000007346545000020264 5ustar0000000000000000integer-roots-1.0.2.0/test-suite/Math/NumberTheory/TestUtils.hs0000644000000000000000000003056107346545000022565 0ustar0000000000000000-- | -- Module: Math.NumberTheory.TestUtils -- Copyright: (c) 2016 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Utils to test Math.NumberTheory -- {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE CPP #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableSuperClasses #-} {-# OPTIONS_GHC -fconstraint-solver-iterations=0 #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Math.NumberTheory.TestUtils ( Positive(..) , NonNegative(..) , AnySign(..) , Power(..) , Huge(..) , testIntegralProperty , testIntegral2Property , testSmallAndQuick ) where import Test.SmallCheck.Series (Positive(..), NonNegative(..), Serial(..)) import Test.Tasty import Test.Tasty.SmallCheck as SC import Test.Tasty.QuickCheck as QC hiding (Positive(..), NonNegative(..), generate) import Data.Bits import Data.Int import Data.Kind import Data.Word import Numeric.Natural import Math.NumberTheory.TestUtils.Wrappers instance Arbitrary Natural where arbitrary = fromInteger <$> (arbitrary `suchThat` (>= 0)) shrink = map fromInteger . filter (>= 0) . shrink . toInteger #if !MIN_VERSION_smallcheck(1,2,0) instance Functor NonNegative where fmap f (NonNegative x) = NonNegative (f x) instance (Num a, Bounded a) => Bounded (NonNegative a) where minBound = NonNegative 0 maxBound = NonNegative (maxBound :: a) instance Functor Positive where fmap f (Positive x) = Positive (f x) instance (Num a, Bounded a) => Bounded (Positive a) where minBound = Positive 1 maxBound = Positive (maxBound :: a) #endif ------------------------------------------------------------------------------- -- https://www.cs.ox.ac.uk/projects/utgp/school/andres.pdf, p. 21 -- :k Compose = (k1 -> Constraint) -> (k2 -> k1) -> (k2 -> Constraint) class (f (g x)) => (f `Compose` g) x instance (f (g x)) => (f `Compose` g) x type family ConcatMap (w :: Type -> Constraint) (cs :: [Type]) :: Constraint where ConcatMap w '[] = () ConcatMap w (c ': cs) = (w c, ConcatMap w cs) type family Matrix (as :: [Type -> Constraint]) (w :: Type -> Type) (bs :: [Type]) :: Constraint where Matrix '[] w bs = () Matrix (a ': as) w bs = (ConcatMap (a `Compose` w) bs, Matrix as w bs) type TestableIntegral wrapper = ( Matrix '[Arbitrary, Show, Serial IO] wrapper '[Int, Int8, Int16, Int32, Int64, Word, Word8, Word16, Word32, Word64, Integer, Natural] , Matrix '[Arbitrary, Show] wrapper '[Large Int, Large Word, Huge Integer, Huge Natural] , Matrix '[Bounded, Integral] wrapper '[Int, Word] , Num (wrapper Integer) , Num (wrapper Natural) , Functor wrapper ) testIntegralProperty :: forall wrapper bool. (TestableIntegral wrapper, SC.Testable IO bool, QC.Testable bool) => String -> (forall a. (Integral a, Bits a, Show a) => wrapper a -> bool) -> TestTree testIntegralProperty name f = testGroup name [ SC.testProperty "smallcheck Int" (f :: wrapper Int -> bool) , SC.testProperty "smallcheck Word" (f :: wrapper Word -> bool) , SC.testProperty "smallcheck Integer" (f :: wrapper Integer -> bool) , SC.testProperty "smallcheck Natural" (f :: wrapper Natural -> bool) , QC.testProperty "quickcheck Int" (f :: wrapper Int -> bool) , QC.testProperty "quickcheck Int8" (f :: wrapper Int8 -> bool) , QC.testProperty "quickcheck Int16" (f :: wrapper Int16 -> bool) , QC.testProperty "quickcheck Int32" (f :: wrapper Int32 -> bool) , QC.testProperty "quickcheck Int64" (f :: wrapper Int64 -> bool) , QC.testProperty "quickcheck Word" (f :: wrapper Word -> bool) , QC.testProperty "quickcheck Word8" (f :: wrapper Word8 -> bool) , QC.testProperty "quickcheck Word16" (f :: wrapper Word16 -> bool) , QC.testProperty "quickcheck Word32" (f :: wrapper Word32 -> bool) , QC.testProperty "quickcheck Word64" (f :: wrapper Word64 -> bool) , QC.testProperty "quickcheck Integer" (f :: wrapper Integer -> bool) , QC.testProperty "quickcheck Natural" (f :: wrapper Natural -> bool) , QC.testProperty "quickcheck Large Int" ((f :: wrapper Int -> bool) . getLarge) , QC.testProperty "quickcheck Large Word" ((f :: wrapper Word -> bool) . getLarge) , QC.testProperty "quickcheck Huge Integer" ((f :: wrapper Integer -> bool) . getHuge) , QC.testProperty "quickcheck Huge Natural" ((f :: wrapper Natural -> bool) . getHuge) ] testIntegral2Property :: forall wrapper1 wrapper2 bool. (TestableIntegral wrapper1, TestableIntegral wrapper2, SC.Testable IO bool, QC.Testable bool) => String -> (forall a1 a2. (Integral a1, Integral a2, Bits a1, Bits a2, Show a1, Show a2) => wrapper1 a1 -> wrapper2 a2 -> bool) -> TestTree testIntegral2Property name f = testGroup name [ SC.testProperty "smallcheck Int Int" (f :: wrapper1 Int -> wrapper2 Int -> bool) , SC.testProperty "smallcheck Int Word" (f :: wrapper1 Int -> wrapper2 Word -> bool) , SC.testProperty "smallcheck Int Integer" (f :: wrapper1 Int -> wrapper2 Integer -> bool) , SC.testProperty "smallcheck Int Natural" (f :: wrapper1 Int -> wrapper2 Natural -> bool) , SC.testProperty "smallcheck Word Int" (f :: wrapper1 Word -> wrapper2 Int -> bool) , SC.testProperty "smallcheck Word Word" (f :: wrapper1 Word -> wrapper2 Word -> bool) , SC.testProperty "smallcheck Word Integer" (f :: wrapper1 Word -> wrapper2 Integer -> bool) , SC.testProperty "smallcheck Word Natural" (f :: wrapper1 Word -> wrapper2 Natural -> bool) , SC.testProperty "smallcheck Integer Int" (f :: wrapper1 Integer -> wrapper2 Int -> bool) , SC.testProperty "smallcheck Integer Word" (f :: wrapper1 Integer -> wrapper2 Word -> bool) , SC.testProperty "smallcheck Integer Integer" (f :: wrapper1 Integer -> wrapper2 Integer -> bool) , SC.testProperty "smallcheck Integer Natural" (f :: wrapper1 Integer -> wrapper2 Natural -> bool) , SC.testProperty "smallcheck Natural Int" (f :: wrapper1 Natural -> wrapper2 Int -> bool) , SC.testProperty "smallcheck Natural Word" (f :: wrapper1 Natural -> wrapper2 Word -> bool) , SC.testProperty "smallcheck Natural Integer" (f :: wrapper1 Natural -> wrapper2 Integer -> bool) , SC.testProperty "smallcheck Natural Natural" (f :: wrapper1 Natural -> wrapper2 Natural -> bool) , QC.testProperty "quickcheck Int Int" (f :: wrapper1 Int -> wrapper2 Int -> bool) , QC.testProperty "quickcheck Int Int8" (f :: wrapper1 Int -> wrapper2 Int8 -> bool) , QC.testProperty "quickcheck Int Word" (f :: wrapper1 Int -> wrapper2 Word -> bool) , QC.testProperty "quickcheck Int Word8" (f :: wrapper1 Int -> wrapper2 Word8 -> bool) , QC.testProperty "quickcheck Int Integer" (f :: wrapper1 Int -> wrapper2 Integer -> bool) , QC.testProperty "quickcheck Int Natural" (f :: wrapper1 Int -> wrapper2 Natural -> bool) , QC.testProperty "quickcheck Int8 Int" (f :: wrapper1 Int8 -> wrapper2 Int -> bool) , QC.testProperty "quickcheck Int8 Int8" (f :: wrapper1 Int8 -> wrapper2 Int8 -> bool) , QC.testProperty "quickcheck Int8 Word" (f :: wrapper1 Int8 -> wrapper2 Word -> bool) , QC.testProperty "quickcheck Int8 Word8" (f :: wrapper1 Int8 -> wrapper2 Word8 -> bool) , QC.testProperty "quickcheck Int8 Integer" (f :: wrapper1 Int8 -> wrapper2 Integer -> bool) , QC.testProperty "quickcheck Int8 Natural" (f :: wrapper1 Int8 -> wrapper2 Natural -> bool) , QC.testProperty "quickcheck Word Int" (f :: wrapper1 Word -> wrapper2 Int -> bool) , QC.testProperty "quickcheck Word Int8" (f :: wrapper1 Word -> wrapper2 Int8 -> bool) , QC.testProperty "quickcheck Word Word" (f :: wrapper1 Word -> wrapper2 Word -> bool) , QC.testProperty "quickcheck Word Word8" (f :: wrapper1 Word -> wrapper2 Word8 -> bool) , QC.testProperty "quickcheck Word Integer" (f :: wrapper1 Word -> wrapper2 Integer -> bool) , QC.testProperty "quickcheck Word Natural" (f :: wrapper1 Word -> wrapper2 Natural -> bool) , QC.testProperty "quickcheck Word8 Int" (f :: wrapper1 Word8 -> wrapper2 Int -> bool) , QC.testProperty "quickcheck Word8 Int8" (f :: wrapper1 Word8 -> wrapper2 Int8 -> bool) , QC.testProperty "quickcheck Word8 Word" (f :: wrapper1 Word8 -> wrapper2 Word -> bool) , QC.testProperty "quickcheck Word8 Word8" (f :: wrapper1 Word8 -> wrapper2 Word8 -> bool) , QC.testProperty "quickcheck Word8 Integer" (f :: wrapper1 Word8 -> wrapper2 Integer -> bool) , QC.testProperty "quickcheck Word8 Natural" (f :: wrapper1 Word8 -> wrapper2 Natural -> bool) , QC.testProperty "quickcheck Integer Int" (f :: wrapper1 Integer -> wrapper2 Int -> bool) , QC.testProperty "quickcheck Integer Int8" (f :: wrapper1 Integer -> wrapper2 Int8 -> bool) , QC.testProperty "quickcheck Integer Word" (f :: wrapper1 Integer -> wrapper2 Word -> bool) , QC.testProperty "quickcheck Integer Word8" (f :: wrapper1 Integer -> wrapper2 Word8 -> bool) , QC.testProperty "quickcheck Integer Integer" (f :: wrapper1 Integer -> wrapper2 Integer -> bool) , QC.testProperty "quickcheck Integer Natural" (f :: wrapper1 Integer -> wrapper2 Natural -> bool) , QC.testProperty "quickcheck Natural Int" (f :: wrapper1 Natural -> wrapper2 Int -> bool) , QC.testProperty "quickcheck Natural Int8" (f :: wrapper1 Natural -> wrapper2 Int8 -> bool) , QC.testProperty "quickcheck Natural Word" (f :: wrapper1 Natural -> wrapper2 Word -> bool) , QC.testProperty "quickcheck Natural Word8" (f :: wrapper1 Natural -> wrapper2 Word8 -> bool) , QC.testProperty "quickcheck Natural Integer" (f :: wrapper1 Natural -> wrapper2 Integer -> bool) , QC.testProperty "quickcheck Natural Natural" (f :: wrapper1 Natural -> wrapper2 Natural -> bool) , QC.testProperty "quickcheck Large Int Int" ((f :: wrapper1 Int -> wrapper2 Int -> bool) . fmap getLarge) , QC.testProperty "quickcheck Large Int Word" ((f :: wrapper1 Int -> wrapper2 Word -> bool) . fmap getLarge) , QC.testProperty "quickcheck Large Int Integer" ((f :: wrapper1 Int -> wrapper2 Integer -> bool) . fmap getLarge) , QC.testProperty "quickcheck Large Int Natural" ((f :: wrapper1 Int -> wrapper2 Natural -> bool) . fmap getLarge) , QC.testProperty "quickcheck Large Word Int" ((f :: wrapper1 Word -> wrapper2 Int -> bool) . fmap getLarge) , QC.testProperty "quickcheck Large Word Word" ((f :: wrapper1 Word -> wrapper2 Word -> bool) . fmap getLarge) , QC.testProperty "quickcheck Large Word Integer" ((f :: wrapper1 Word -> wrapper2 Integer -> bool) . fmap getLarge) , QC.testProperty "quickcheck Large Word Natural" ((f :: wrapper1 Word -> wrapper2 Natural -> bool) . fmap getLarge) , QC.testProperty "quickcheck Huge Integer Int" ((f :: wrapper1 Integer -> wrapper2 Int -> bool) . fmap getHuge) , QC.testProperty "quickcheck Huge Integer Word" ((f :: wrapper1 Integer -> wrapper2 Word -> bool) . fmap getHuge) , QC.testProperty "quickcheck Huge Integer Integer" ((f :: wrapper1 Integer -> wrapper2 Integer -> bool) . fmap getHuge) , QC.testProperty "quickcheck Huge Integer Natural" ((f :: wrapper1 Integer -> wrapper2 Natural -> bool) . fmap getHuge) , QC.testProperty "quickcheck Huge Natural Int" ((f :: wrapper1 Natural -> wrapper2 Int -> bool) . fmap getHuge) , QC.testProperty "quickcheck Huge Natural Word" ((f :: wrapper1 Natural -> wrapper2 Word -> bool) . fmap getHuge) , QC.testProperty "quickcheck Huge Natural Integer" ((f :: wrapper1 Natural -> wrapper2 Integer -> bool) . fmap getHuge) , QC.testProperty "quickcheck Huge Natural Natural" ((f :: wrapper1 Natural -> wrapper2 Natural -> bool) . fmap getHuge) ] testSmallAndQuick :: (SC.Testable IO a, QC.Testable a) => String -> a -> TestTree testSmallAndQuick name f = testGroup name [ SC.testProperty "smallcheck" f , QC.testProperty "quickcheck" f ] integer-roots-1.0.2.0/test-suite/Math/NumberTheory/TestUtils/0000755000000000000000000000000007346545000022224 5ustar0000000000000000integer-roots-1.0.2.0/test-suite/Math/NumberTheory/TestUtils/Wrappers.hs0000644000000000000000000001153207346545000024365 0ustar0000000000000000-- | -- Module: Math.NumberTheory.TestUtils.Wrappers -- Copyright: (c) 2016 Andrew Lelechenko -- Licence: MIT -- Maintainer: Andrew Lelechenko -- -- Utils to test Math.NumberTheory -- {-# LANGUAGE DeriveFoldable #-} {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveTraversable #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE StandaloneDeriving #-} {-# OPTIONS_GHC -fno-warn-orphans #-} module Math.NumberTheory.TestUtils.Wrappers ( AnySign(..) , Power(..) , Huge(..) ) where import Control.Applicative import Data.Functor.Classes import Test.Tasty.QuickCheck as QC hiding (Positive(..), NonNegative(..)) import Test.SmallCheck.Series (Positive(..), NonNegative(..), Serial(..), Series) ------------------------------------------------------------------------------- -- AnySign newtype AnySign a = AnySign { getAnySign :: a } deriving (Eq, Ord, Read, Show, Num, Enum, Bounded, Integral, Real, Functor, Foldable, Traversable, Arbitrary) instance (Monad m, Serial m a) => Serial m (AnySign a) where series = AnySign <$> series instance Eq1 AnySign where liftEq eq (AnySign a) (AnySign b) = a `eq` b instance Ord1 AnySign where liftCompare cmp (AnySign a) (AnySign b) = a `cmp` b instance Show1 AnySign where liftShowsPrec shw _ p (AnySign a) = shw p a ------------------------------------------------------------------------------- -- Positive from smallcheck instance (Num a, Ord a, Arbitrary a) => Arbitrary (Positive a) where arbitrary = Positive <$> (arbitrary `suchThat` (> 0)) shrink (Positive x) = Positive <$> filter (> 0) (shrink x) instance Eq1 Positive where liftEq eq (Positive a) (Positive b) = a `eq` b instance Ord1 Positive where liftCompare cmp (Positive a) (Positive b) = a `cmp` b instance Show1 Positive where liftShowsPrec shw _ p (Positive a) = shw p a ------------------------------------------------------------------------------- -- NonNegative from smallcheck instance (Num a, Ord a, Arbitrary a) => Arbitrary (NonNegative a) where arbitrary = NonNegative <$> (arbitrary `suchThat` (>= 0)) shrink (NonNegative x) = NonNegative <$> filter (>= 0) (shrink x) instance Eq1 NonNegative where liftEq eq (NonNegative a) (NonNegative b) = a `eq` b instance Ord1 NonNegative where liftCompare cmp (NonNegative a) (NonNegative b) = a `cmp` b instance Show1 NonNegative where liftShowsPrec shw _ p (NonNegative a) = shw p a ------------------------------------------------------------------------------- -- Huge newtype Huge a = Huge { getHuge :: a } deriving (Eq, Ord, Read, Show, Num, Enum, Bounded, Integral, Real, Functor, Foldable, Traversable) instance (Num a, Arbitrary a) => Arbitrary (Huge a) where arbitrary = do Positive l <- arbitrary ds <- vector l return $ Huge $ foldl1 (\acc n -> acc * 2 ^ (63 :: Int) + n) ds instance Eq1 Huge where liftEq eq (Huge a) (Huge b) = a `eq` b instance Ord1 Huge where liftCompare cmp (Huge a) (Huge b) = a `cmp` b instance Show1 Huge where liftShowsPrec shw _ p (Huge a) = shw p a ------------------------------------------------------------------------------- -- Power newtype Power a = Power { getPower :: a } deriving (Eq, Ord, Read, Show, Num, Enum, Bounded, Integral, Real, Functor, Foldable, Traversable) instance (Monad m, Num a, Ord a, Serial m a) => Serial m (Power a) where series = Power <$> series `suchThatSerial` (> 0) instance (Num a, Ord a, Integral a, Arbitrary a) => Arbitrary (Power a) where arbitrary = Power <$> arbitrarySizedNatural `suchThat` (> 0) shrink (Power x) = Power <$> filter (> 0) (shrink x) instance Eq1 Power where liftEq eq (Power a) (Power b) = a `eq` b instance Ord1 Power where liftCompare cmp (Power a) (Power b) = a `cmp` b instance Show1 Power where liftShowsPrec shw _ p (Power a) = shw p a ------------------------------------------------------------------------------- -- Odd newtype Odd a = Odd { getOdd :: a } deriving (Eq, Ord, Read, Show, Num, Enum, Bounded, Integral, Real, Functor, Foldable, Traversable) instance (Monad m, Serial m a, Integral a) => Serial m (Odd a) where series = Odd <$> series `suchThatSerial` odd instance (Integral a, Arbitrary a) => Arbitrary (Odd a) where arbitrary = Odd <$> (arbitrary `suchThat` odd) shrink (Odd x) = Odd <$> filter odd (shrink x) instance Eq1 Odd where liftEq eq (Odd a) (Odd b) = a `eq` b instance Ord1 Odd where liftCompare cmp (Odd a) (Odd b) = a `cmp` b instance Show1 Odd where liftShowsPrec shw _ p (Odd a) = shw p a ------------------------------------------------------------------------------- -- Utils suchThatSerial :: Series m a -> (a -> Bool) -> Series m a suchThatSerial s p = s >>= \x -> if p x then pure x else empty integer-roots-1.0.2.0/test-suite/Test.hs0000644000000000000000000000122507346545000016223 0ustar0000000000000000import Test.Tasty import Test.Tasty.QuickCheck import Test.Tasty.SmallCheck import qualified Math.NumberTheory.Roots.CubesTests as Cubes import qualified Math.NumberTheory.Roots.FourthTests as Fourth import qualified Math.NumberTheory.Roots.GeneralTests as General import qualified Math.NumberTheory.Roots.SquaresTests as Squares main :: IO () main = defaultMain $ adjustOption (\(QuickCheckTests n) -> QuickCheckTests (max n 10000)) $ adjustOption (\(SmallCheckDepth n) -> SmallCheckDepth (max n 100)) $ tests tests :: TestTree tests = testGroup "All" [ Squares.testSuite , Cubes.testSuite , Fourth.testSuite , General.testSuite ]