<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Tahoma
}
--></style></head>
<body class='hmmessage'><div dir='ltr'>
Well, playing with Haskell I have literally trasnlated my c++ program <div><a href="http://shootout.alioth.debian.org/u64q/program.php?test=fannkuchredux&lang=gpp&id=3">http://shootout.alioth.debian.org/u64q/program.php?test=fannkuchredux&lang=gpp&id=3</a><div>and got decent performance but not that good in comparison</div><div>with c++ </div></div><div>On my machine Haskell runs 52 secs while c++ 30 secs.</div><div>(There is Haskell entry that is fastest but unfortunately does not runs on </div><div>test machine is on par with c++</div><div><a href="http://shootout.alioth.debian.org/u64q/program.php?test=fannkuchredux&lang=ghc&id=3" style="font-size: 10pt;">http://shootout.alioth.debian.org/u64q/program.php?test=fannkuchredux&lang=ghc&id=3</a></div><div>)</div><div>There is something which I have missing since programs</div><div>are identical.</div><div>Aa with previous entries you gurus here helped a lot in both help</div><div>and learning experience.</div><div>I simply love Haskell ;)</div><div>I plan to contribute this program as it is much faster than current running</div><div>entry <a href="http://shootout.alioth.debian.org/u64q/program.php?test=fannkuchredux&lang=ghc&id=2" style="font-size: 10pt;">http://shootout.alioth.debian.org/u64q/program.php?test=fannkuchredux&lang=ghc&id=2</a></div><div>even if it is multithreaded and my is not.</div><div><br></div><div>This is program:</div><div><br></div><div><div>{-# LANGUAGE CPP, BangPatterns #-}</div><div>{- The Computer Language Benchmarks Game</div><div><br></div><div> http://shootout.alioth.debian.org/</div><div><br></div><div> contributed by Branimir Maksimovic</div><div><br></div><div>-}</div><div><br></div><div>import System.Environment</div><div>import Text.Printf</div><div>import Data.Bits</div><div><br></div><div>import qualified Data.Vector.Unboxed.Mutable as VM</div><div>import qualified Data.Vector.Generic.Mutable as VG</div><div>import qualified Data.Vector.Unboxed as V</div><div><br></div><div>main = do</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>n <- getArgs >>= readIO.head</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>(checksum,maxflips) <- fannkuch n</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>printf "%d\nPfannkuchen(%d) = %d\n" checksum n maxflips</div><div><br></div><div>fannkuch n = do</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>!perm <- V.unsafeThaw $ V.fromList [1..n]</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>!tperm <- VG.new n</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>!cnt <- VG.replicate n 0</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>let</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>loop :: Int -> Int -> Int -> IO(Int,Int)</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>loop !c !m !pc = do</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>!b <- next_permutation perm n cnt</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>if b == False then return (c,m) </div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>else do</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>VM.unsafeCopy tperm perm</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>!flips <- count_flips tperm 0</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>loop (c + (if pc .&. 1 == 0 then flips else -flips))</div><div><span class="Apple-tab-span" style="white-space:pre">                                        </span> (max m flips)</div><div><span class="Apple-tab-span" style="white-space:pre">                                        </span> (pc+1)</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>r <- loop 0 0 1</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>return r</div><div><br></div><div><br></div><div>next_permutation :: VM.IOVector Int -> Int -> VM.IOVector Int-> IO(Bool)</div><div>next_permutation !perm !n !cnt = </div><div><span class="Apple-tab-span" style="white-space:pre">        </span>do </div><div><span class="Apple-tab-span" style="white-space:pre">                </span>!i <- loop 1</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>if(i >= n) </div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>then return False</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>else do</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>!v <- VM.unsafeRead cnt i</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>VM.unsafeWrite cnt i (v+1)</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>return True</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>where </div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>loop :: Int -> IO(Int)</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>loop !i </div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>| i < n = do</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span> !tmp <- VM.unsafeRead perm 0</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span> let </div><div><span class="Apple-tab-span" style="white-space:pre">                                        </span>rotate :: Int -> IO()</div><div><span class="Apple-tab-span" style="white-space:pre">                                        </span>rotate !j = </div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span>if j >= i</div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span>then do</div><div><span class="Apple-tab-span" style="white-space:pre">                                                        </span>VM.unsafeWrite perm i tmp</div><div><span class="Apple-tab-span" style="white-space:pre">                                                        </span>return ()</div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span>else do</div><div><span class="Apple-tab-span" style="white-space:pre">                                                        </span>!v <- VM.unsafeRead perm (j+1)</div><div><span class="Apple-tab-span" style="white-space:pre">                                                        </span>VM.unsafeWrite perm j v</div><div><span class="Apple-tab-span" style="white-space:pre">                                                        </span>rotate (j+1)</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span> rotate 0</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span> !v <- VM.unsafeRead cnt i</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span> if v >= i</div><div><span class="Apple-tab-span" style="white-space:pre">                                        </span>then do</div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span>VM.unsafeWrite cnt i 0</div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span>loop (i+1)</div><div><span class="Apple-tab-span" style="white-space:pre">                                        </span>else return i</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>| otherwise = return i</div><div><span class="Apple-tab-span" style="white-space:pre">                                                </span></div><div>count_flips :: VM.IOVector Int -> Int -> IO(Int)</div><div>count_flips !tperm !flips = do</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>!f <- VM.unsafeRead tperm 0</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>if f == 1 </div><div><span class="Apple-tab-span" style="white-space:pre">                </span>then</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>return flips</div><div><span class="Apple-tab-span" style="white-space:pre">                </span>else do </div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>VG.reverse $ VM.unsafeSlice 0 f tperm</div><div><span class="Apple-tab-span" style="white-space:pre">                        </span>count_flips tperm (flips+1)</div></div><div><br></div><div><br></div><div><br></div>                                            </div></body>
</html>