The original code (~7.2s on my laptop).
import System.Random
import System.CPUTime
rainfall :: [Int] -> Int
rainfall xs = sum (zipWith (-) mins xs)| // Faster solution for: | |
| // http://www.boyter.org/2017/03/golang-solution-faster-equivalent-java-solution/ | |
| // With threading. | |
| // g++ -std=c++11 -Wall -Wextra -O3 -pthread | |
| // On my computer (i5-6600K 3.50 GHz 4 cores), takes about ~160 ms after the CPU | |
| // has warmed up, or ~80 ms if the CPU is cold (due to Turbo Boost). | |
| // How it works: Start by generating a list of losing states -- states where the | |
| // game can end in one turn. Generate a new list of states by running the game |
The original code (~7.2s on my laptop).
import System.Random
import System.CPUTime
rainfall :: [Int] -> Int
rainfall xs = sum (zipWith (-) mins xs)A problem that I've seen beginners run into in Haskell or PureScript a couple of times now is how to generate a List of random numbers. It's a common requirement for little games (which make for great first projects) to generate these, and it definitely seems to be a stumbling block.
Randomness is considered a side effect in purely functional languages, which means that to generate them you usually need access to Eff/IO, which in turn means we need to deal with Monads. And while generating a single random number is usually pretty easy with do-notation, the typical intuition beginners have built when going from single values to a collection is to use map, but that fails.