fromEnumについて
Twitterで流れてきたこれを見て、あれ?と思ったので調べてみました
fromEnum???
数字ならその数字を、文字なら、文字コードを返すらしい。
ghciで調べてみる
Prelude> :t fromEnum fromEnum :: Enum a => a -> Int
なるほど
列挙型ならいいのか
というわけで、ちょっと試しに
Prelude> data Num = Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten deriving (Enum , Show) Prelude> fromEnum One 1 Prelude> fromEnum Nine 9
この場合はインデックスを返すらしい(?)
という事は
Prelude> :i Bool data Bool = False | True -- Defined in `GHC.Types' Prelude> fromEnum (1==1) 1 Prelude> fromEnum (1==2) 0
これだけの事だったのか。
ちなみに…
数列表記も列挙型ならいいらしいので
Prelude> data Num = Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten deriving (Enum , Show) Prelude> [Zero .. Ten] [Zero,One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten] Prelude> [Zero, Two ..] [Zero,Two,Four,Six,Eight,Ten]
こんなことも出来ちゃうみたいです。
FFIを使ってみよう
FFIを使ってHaskellからC++の関数を呼び出してみました。
まずC++のコード
#include <iostream> extern "C" { void hello() { std::cout << "Hello World!" << std::endl; } }
大切なのは「extern "C" {}」を忘れないことです。
そしてHaskellは
{-# LANGUAGE ForeignFunctionInterface #-} main = c_hello foreign import ccall "hello" c_hello :: IO ()
こんな感じです
あとは、
$ g++ -c hello.cpp
$ ghc -lstdc++ --make main.hs hello.o
これでOKです。
$ ./main Hello World!
こんな感じに出来ます。
情報によるとghcが64bitコードに対応してないらしい(?)ので
g++に-m32オプションをつけて下さい。
Problem 22
Problem 22です。
import Data.List import Data.Maybe import Control.Applicative score = sum . map (fromMaybe 0 . flip lookup (zip ['A'..'Z'] [1..26])) main = do names <- (sort . list) <$> getContents print . (foldr (\(x, y) s -> s + x * y) 0) . zip [1..] $ map score names where list x = read $ "[" ++ x ++ "]"
# ./p22 < name.txt
こんな感じです。
Problem 21
Problem 21です。
import Data.List main = print . sum . filter isAmicable $ [1..10000] isAmicable n = n == (sumDivisors . sumDivisors $ n) && n /= sumDivisors n sumDivisors n = sum . filter (\x -> (n `mod` x) == 0) $ [1..n-1]
遅いです。
Problem 20
Problem 20です。
import Data.Char (digitToInt) main = print . sum . map digitToInt $ show . product $ [1..100]
シンプルに計算するだけで簡単に出来ました。
Problem 19
今回は、Problem 19です。
import Data.Time.Calendar import Data.Time.Calendar.WeekDate main = print . length $ [d | d <- [fromGregorian y m 1 | y <- [1901..2000], m <- [1..12]], let (_, _, w) = toWeekDate d, w == 7]
Haskellなら簡単でした。