projecteuler.net की समस्या को हल करने में # 31 [स्पोइलर्स अहिड] (ब्रिटिश सिक्कों के साथ 2 £ बनाने के तरीकों की संख्या गिनती), मैं गतिशील प्रोग्रामिंग का उपयोग करना चाहता था। मैं OCaml के साथ शुरू किया, और छोटी और बहुत ही कुशल निम्नलिखित प्रोग्रामिंग लिखा है:हास्केल में गतिशील प्रोग्रामिंग का उपयोग करना? [चेतावनी: ProjectEuler 31 समाधान अंदर]
open Num
let make_dyn_table amount coins =
let t = Array.make_matrix (Array.length coins) (amount+1) (Int 1) in
for i = 1 to (Array.length t) - 1 do
for j = 0 to amount do
if j < coins.(i) then
t.(i).(j) <- t.(i-1).(j)
else
t.(i).(j) <- t.(i-1).(j) +/ t.(i).(j - coins.(i))
done
done;
t
let _ =
let t = make_dyn_table 200 [|1;2;5;10;20;50;100;200|] in
let last_row = Array.length t - 1 in
let last_col = Array.length t.(last_row) - 1 in
Printf.printf "%s\n" (string_of_num (t.(last_row).(last_col)))
यह मेरा लैपटॉप पर ~ 8ms में निष्पादित करता है। यदि मैं 200 पेंस से दस लाख तक की राशि बढ़ाता हूं, तो प्रोग्राम को अभी भी दो सेकंड से भी कम समय में एक जवाब मिल जाता है।
मैंने प्रोग्राम को हास्केल (जो कि निश्चित रूप से मजेदार नहीं था) में अनुवाद किया है, और हालांकि यह 200 पेंस के सही जवाब के साथ समाप्त हो जाता है, अगर मैं उस संख्या को 10000 तक बढ़ाता हूं, तो मेरा लैपटॉप एक डरावना ठहराव (बहुत सारे ताड़ना)।
import Data.Array
createDynTable :: Int -> Array Int Int -> Array (Int, Int) Int
createDynTable amount coins =
let numCoins = (snd . bounds) coins
t = array ((0, 0), (numCoins, amount))
[((i, j), 1) | i <- [0 .. numCoins], j <- [0 .. amount]]
in t
populateDynTable :: Array (Int, Int) Int -> Array Int Int -> Array (Int, Int) Int
populateDynTable t coins =
go t 1 0
where go t i j
| i > maxX = t
| j > maxY = go t (i+1) 0
| j < coins ! i = go (t // [((i, j), t ! (i-1, j))]) i (j+1)
| otherwise = go (t // [((i, j), t!(i-1,j) + t!(i, j - coins!i))]) i (j+1)
((_, _), (maxX, maxY)) = bounds t
changeCombinations amount coins =
let coinsArray = listArray (0, length coins - 1) coins
dynTable = createDynTable amount coinsArray
dynTable' = populateDynTable dynTable coinsArray
((_, _), (i, j)) = bounds dynTable
in
dynTable' ! (i, j)
main =
print $ changeCombinations 200 [1,2,5,10,20,50,100,200]
मैं किसी को जो हास्केल अच्छी तरह से जानता कि क्यों इस समाधान का प्रदर्शन इतना बुरा है से सुनने के लिए खुशी होगी: यहाँ कोड है।
Fwiw, मैं बहुत डैनियल से @ augustss के जवाब के करीब कुछ किया होता। – luqui
यह केवल सूचियों और दाएं फोल्ड का उपयोग करके अधिक कुशलता से किया जा सकता था। http://stackoverflow.com/questions/36699695 –