2010-10-21 58 views
3

我現在正在努力處理這些代碼。我想確定一個整數是否爲11,根據我所讀到的,當它的數字的和(一次+,一次 - )可以被11整除時,一個整數就可以被整除爲11.測試Ints的可分性11

例如:56518可以被11整除,因爲8-1 + 5-6 + 5 = 11,11可以被11整除。

我怎樣才能在Haskell中寫下來?提前致謝。

+3

任何錯誤使用模? – delnan 2010-10-21 17:16:35

+0

@Justin ifan意思是'。'作爲數千和單位之間的分隔符,而不是小數點。 – Yitz 2010-10-21 17:18:18

+0

@Justin:在某些語言環境中,'.'被用作千位分隔符(而'''爲小數點),所以他可能意思是'56518'。 – sepp2k 2010-10-21 17:18:37

回答

12

一些x是整除y如果它是當y劃分其餘0,所以你可以做

divisibleBy11 x = x `rem` 11 == 0 
+1

非常感謝你。有沒有其他方法可以獲得相同的結果? – marco 2010-10-21 17:25:44

+1

@範:是的,不少。最普通的是,你可以用'mod'替換'rem'。你也可以創建一個包含11的倍數的列表或集合,然後檢查數字是否在那裏,或者你可以使用你在問題中提到的規則,但這會慢很多。但是其中的任何一個比使用'mod'或'rem'都要慢很多。 – sepp2k 2010-10-21 17:30:16

+0

Pointfree: ''divBy11 =(== 0)。 ('rem' 11)'' – 2017-02-06 18:23:35

7

IFAN我敢肯定,你知道,在現實生活中你會使用modrem對於這個簡單的例子,但你問的算法很有趣。這裏有一個有趣的方式來做到這一點,強調哈斯克爾的功能性質:

digits = map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10) 

divisible11 = (== 0) . head . dropWhile (>= 11) . iterate (reduce11 . digits) 
    where 
    reduce11 []  = 0 
    reduce11 (d:ds) = foldl combine d $ zip (cycle [(-), (+)]) ds 
    combine d (op, d') = d `op` d' 
+0

這正是我所期待的。非常感謝你的幫助 – marco 2010-10-21 17:38:58

0

......怎麼

mod11 n | n < 0 = 11 - mod11 (-n) 
     | n < 11 = n 
     | otherwise = mod11 $ (n `mod` 10) - (n `div` 10) 
2

當然,divmod是快,但爲什麼不呢?我認爲問題是一個數字轉換到數字的列表:

toDigits = map (read . (:[])) . show 

56518被轉換成字符串"56518"和字符串(每個位)在每個碼元轉換爲字符串本身map (:[]),在這點我們有["5","6","5","1","8"],我們讀取每個單個數字字符串作爲整數值:[5,6,5,1,8]。完成。現在

我們可以計算出的數字之和是這樣的:

sumDigits x = sum (zipWith (*) (cycle [1,-1]) (reverse (toDigits x))) 

cycle [1,-1],使無限列表[1, -1, 1, -1, ...],我們與數字(toDigit x)反轉列表進行配對,並乘以每對的元素。所以我們有[8, -1, 5, -6, 5]及其總和。

現在,我們可以遞歸地做到這一點:

isDivisible x 
    | x == 11 || x == 0 = True 
    | x < 11   = False 
    | x > 11   = isDivisible (sumDigits x)