如何解决最后一个数字
我正在Codewar中解决Last digit of a huge number。
我设法找到一种计算odd number ^ odd number
和odd number ^ even number
的方法。但是,由于数字与其幂的mod之间的关系不明显,所以我陷入了even ^ even/odd
中。
这就是我设法得到的:
lastDigit :: [Integer] -> Integer
lastDigit = (`rem` 10) . go
where
go [] = 1
go [x] = x
go (x : y : r)
| odd x && odd y = x ^ (go (y : r) `rem` (x + 1))
| odd x && even y = x ^ (foldMod y (go r) (x + 1))
| otherwise = -- any hint?
foldMod :: Integer -> Integer -> Integer -> Integer
foldMod _ 0 _ = 1
foldMod base 1 modulo = base `rem` modulo
foldMod base power modulo = (base * foldMod base (power -1) modulo) `rem` modulo
任何人都可以对偶数情况给出一些提示吗?
解决方法
我建议重新考虑您的方法,并从更通用的功能开始。具体来说,您可以计算
powMod :: Integer -> [Integer] -> Integer
powMod base exponents
在哪里计算问题mod base
中描述的指数塔?请注意,在递归时,您将使用不同的base
进行递归-因为各个第一指数的循环长度不一定是base
的所有约数。例如,在以10为底的数字中,最后四个数字为7个周期的第一个指数(而不是每十个)出现一次。权力的最后一位像这样:
x 0 1 2 3 4 5 6 7
7^x `mod` 10 1 7 9 3 1 7 9 3
您还需要注意以下情况:在到达的最终周期中,第一个指数本身不是其本身;例如,在基数4中,我们有:
x 0 1 2 3 4 5 6 7
2^x `mod` 4 1 2 0 0 0 0 0 0
因此,即使循环长度为x `mod` 1
,也无法查看 just 2^x `mod` 4
并推断出1
是什么。 (还有其他示例,例如2^x `mod` 12
,其中循环长于1,但其中仍然没有原始的2
。)
您不需要计算整数就可以知道最后一位,有一些快速方法和不太快的方法都可以计算最后一位,而不必担心其他所有数字。
一种可以在 O(log b)时间中计算 a b 的简单方法是利用以下等式:>
(a×b)mod m =((a mod m)×(b mod m))mod m 。
这意味着我们每次都可以计算最后一位数字并进行处理。因此,这意味着只要我们可以表示最大为81的所有数字,就可以计算 a b mod m powMod m a b
:
powMod :: Int -> Int -> Int -> Int
powMod m = go
where go _ 0 = 1
go a b | even n = r
| otherwise = (x * r) `mod` m
where r = go ((a*a) `mod` m) (div b 2) `mod` m
如果我们假设我们可以计算模数,除以2,并在恒定时间内检查值是否为偶数,等等,则在 O(log b)中运行。
但是我们甚至可以通过查找周期来更快地做到这一点。假设我们必须计算7的幂,那么7 ^ 0是1,7 ^ 1是7,7 ^ 2 mod 10 = 9,依此类推。我们可以制作一个带有乘法的表:
× │ 0 1 2 3 4 5 6 7 8 9 ──┼───────────────────── 0 │ 0 0 0 0 0 0 0 0 0 0 1 │ 1 2 3 4 5 6 7 8 9 2 │ 4 6 8 0 2 4 8 6 3 │ 9 2 5 8 1 4 7 4 │ 6 0 4 8 2 6 5 │ 5 0 5 0 5 6 │ 6 2 8 4 7 │ 9 6 3 8 | 4 2 9 | 1
因此,如果我们以7的幂为单位查看最后一位,我们将看到:
power │ │ last digit ────────────────────────── 0 │ │ 1 1 │ 7*1 │ 7 2 │ 7*7 │ 9 3 │ 7*9 │ 3 4 │ 7*3 │ 1
因此,这意味着存在一个循环,实际上是在每次乘以7之后,我们移至下一个状态,并因此获得以下图形:
1 → 7 → 9 → 3
↖_______________/
因此,这意味着循环的长度为四。因此,这意味着如果我们必须将7乘以例如374的幂,那么我们知道这是93个长度为4的循环,因此没有影响,还有两个额外的移动,因此我们知道 7 393 为9,无需计算此数字。由于此类循环的最大长度为10,因此可以在固定时间内确定十进制数字的最后一位。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。