2013-12-18 52 views
0

我有一種有趣的問題,過去幾天我一直無法解決。Modula Mathematics and Triple

在Haskell,我的方法:

c :: Int->(Int,Int,Int) 
c x = ... 

考慮到返回值的三個元素是A,B,C,使得返回值是(A,B,C),則該函數應取的輸入值,並進行如下操作:

增加1的值,並且在由1

同時減少x如果在任何時候一個等於25,則在下一步驟a設置爲0並且b增加1,x減少1.

如果在任何時候b等於25,則在下一步驟b被設置爲0(因此還有一個被設置爲0)和c增加1,x由1

如果降低在任何時間a,b和c是等於25,那麼它們都被重置爲0,並在接下來的步驟返回值將是(1,0,0),x由1

例如降低,對於x = 20,返回值是(20,0,0),對於x = 29,返回值是(3,1,0)

如何最好地實現這個任何想法?

+0

難道我們假設'了','B'和'C'啓動在0?另外,是否有任何理由按照書面實現算法,或者你是否也接受使用'quot'和'rem'的簡單表達式? – jwodder

+0

是的,對不起!忘了提及! – MrD

+0

你確定'29'的值是'(3,1,0)'而不是'(4,1,0)'? – Xymostech

回答

1

一對夫婦的問題,在這裏我不知道你是知道的:

  • 在Haskell,我有方法

    不,你不知道! c只是一個功能。 (我們在Haskell中稱之爲「方法」也是函數,但是在類型類中聲明的函數)函數與OO語言中的方法完全不同,您可能會想到這些方法。尤其是...

  • 這是不可能的「設定」的任何值。在Haskell中,只要有人使用它們,所有變量都會被定義一次。你不能只改變它們。你可以談談「替換」,這對(a,b,c) -> (a,b,c)形式的「更新功能」有意義。但這不適用於你的例子。

    x是一個參數,所以功能並沒有什麼價值可能需要在所有的任何發言權。你的意思是什麼「減少1 x」真的試圖descibe xa之間的相關。更正確的方式做,這將是「如果x增加一,隨後a也增加1」。

你可能確實知道這一點,但還沒有真正吸收過功能上的思維方式。通過這樣的一系列步驟來描述函數應該產生的功能通常不是很好。

你的要求可能會更加精確和簡單的配方,但它需要一些術語。首先剝離一切不必要的。

您在這裏有兩個基本不相干的數字:一個元組,以及最大。

  • c' max 0 ≡ 0:很顯然,沒有什麼會在原則上,如果你到了34元組和每個條目35248.的最大值因此,我們應該考慮,而不是一個功能

    c' :: Int -> Int -> Int 
    

    以下要求改變。和c' max (x+1) ≡ 1 + c' max x,提供...

  • 結果不會比max大。如果我們達到了這個限制,那麼結果應該被「折回」到0,然後從那裏開始,每步增加x,再次增加。

現在,事實證明(你需要知道的一點),每一種常見的編程語言都有這樣一個內置函數,它叫做mod

GHCI> 0`mod` 26
GHCI> 1`mod` 26
GHCI> 2`mod` 26
GHCI> 24`mod` 26
GHCI> 25`mod` 26
GHCI> 26`mod` 26
GHCI> 27`mod` 26

然後我們要在那些其他的元組元素得到。想想b如何相關x。基本上,從0x的範圍具有「分區」,其中a增加。這些分區的大小是maxb表示您經常超出限制的次數,或者等同於您已經走過的分區數。那麼有多少分區適合這個範圍?那麼,這只是部門!但是一個特殊的分區,舍入整數除法,因爲你只走過一部分的分區不算。在Haskell,可以使用div該(或quot):

GHCI> 1`div` 26
GHCI> 25`div` 26
GHCI> 26`div` 26
GHCI> 36`div` 26
GHCI> 52`div` 26

這不是b已經足夠,因爲......

GHCI> 2352`div` 26

b應該再侷限於max。那麼,但你可以簡單地使用mod

對於c,我們可以應用相同的推理,但分兩步進行。然後,函數可能看起來像:

c'' :: Int -> Int -> (Int, Int, Int) 
c'' max x = (a' `mod` max, b' `mod` max, c' `mod` max) 
where a' = x 
     b' = x `div` max 
     c' = b' `div` max 

顯然,這裏有一個模式:的`div` max重複應用,並在所有的結果叫`mod` max。因此,該函數可以輕鬆地使用可變長度元組(列表!)並自動執行這些步驟。

+0

一個問題(聽起來很愚蠢),爲什麼'和'? – MrD

+1

@DarioP:它們只是名稱,Haskell允許在標識符中使用撇號。這只是一個編碼約定,通常指定'x'和'x''在某種程度上是相關的。 – Vitus

0

這個工程....

map ord $ showIntAtBase 26 chr 29 "" 

(你將需要導入數字和Data.Char)通過這個

如果你真的想在元組的形式你的答案,管答案

convertToTuple [x] = (x, 0, 0) 
convertToTuple [y, x] = (x, y, 0) 
convertToTuple (z:y:x:_) = (x, y, z) 
0

我簡單地做,

c x = (rem x 26, rem (div x 25) 26, rem (div x (26*26)) 26) 

它給

c 20 = (20,0,0) 
c 29 = (3,1,0) 

更迂腐,

​​

運行,

foldl (\x _ -> succDS x) (zeroDS 26) [1..29] 

應該給

Digits [Digit 3 26,Digit 1 26] 

或比較熟悉,

foldl (\x _ -> succDS x) (zeroDS 10) [1..100] 

應該導致,

Digits [Digit 0 10,Digit 0 10,Digit 1 10]