absint :: VInt -> Int absint (x:xs) = mulbplus x xs mulbplus x [] = x mulbplus x0 (x1:xs) = mulbplus (x0 * b + x1) xsっていうのを考えればいいことは分かった。これを…
type VInt2 = (Bool,VInt) -- true is >=0 vadd2 :: VInt2 -> VInt2 -> VInt2 vadd2 (xb,xs) (yb,ys) | xb==True && yb==True = (True,vadd xs ys) | xb==False && yb == False = (False,vadd xs ys) | xb==True && yb ==False && vleq xs ys = (False,vsub ys xs) | xb==True && yb ==False && vless ys xs = (True,vsub xs ys) | xb==False && xb == True = vadd2 (yb,ys) (xb,xs) vsub2 :: VInt2 -> VInt2 -> VInt2 vsub2 x (yb,ys) = vadd2 x ((not yb),ys)
digitToInt :: Char -> Int digitToInt c | isDigit c = fromEnum c - fromEnum '0' | c >= 'a' && c <= 'f' = fromEnum c - fromEnum 'a' + 10 | c >= 'A' && c <= 'F' = fromEnum c - fromEnum 'A' + 10 | otherwise = error "Char.digitToInt: not a digit" isDigit c = c >= '0' && c <= '9' digit c = digitToInt c inv = pack . map digit pack :: [Int]->VInt pack s = foldl (time10add) [0] s where time10add xs y = vadd (map (10*) xs) [y]"223"をb=100にすると[2,23]になった。いいはず
-- thinking b is 10000 outv (x:xs) = i2ddiv "" x ++ foldl (len4digit) "" xs i2c :: Int -> Char i2c x = toEnum (fromEnum '0' + x) i2ddiv s x | 0 <= x && x <= 9 = s++[toEnum (fromEnum '0' + x)] | otherwise = (i2ddiv (i2ddiv s (x `div` 10)) (x `mod` 10)) len4digit s x = s ++ [i2c (x `div` 1000),i2c ((x `div` 100) `mod` 10),i2c ((x `div` 10) `mod` 10),i2c (x `mod` 10)]
特定の人たちへ。
正直よくわかんないけど縮約(reduction)した結果が等しいよねってことを言えばいい気がする。 たぶん。
以下のように定義すると後の説明が楽な気がします。
absint :: VInt -> Int absint xs = mulplus nall xs where mulplus :: Int -> VInt -> Int mulplus n xs | n < 0 = 0 | otherwise = b^n * head(xs) + (mulplus (n-1) (tail xs)) nall = length(xs) - 1
説明としてはこんな感じ。縮約できるから~
absint([0] ++ xs) = mulplus (nall+1) ([0] ++ xs) = mulplus nall (xs) = absint xs
これもたぶん関数の定義使って変形すればOK
negate xs = norm・map neg xs = norm [-x0, -x1, -x2, .... , -xn]
vsub [0] xs = norm (zipwith (-) (align [0], xs)) = norm (zipwith (-) [0,0,0,0,....,0] xs) = norm [-x0, -x1, ....., -xn]
digitは文字列から数字のリストを与えます。
"12345"→['1', '2','3','4','5']→(たぶんここがmapの意味)→[1,2,3,4,5]
後はpackでb進数に直します。VIntは[Int]という定義なのでb=2なら
[1,2,3,4,5]→[1,1,0,0,0,0,0,0,1,1,1,0,0,1]
たぶん可能?
vmul xs ys = foldl (+) [] (psums xs ys) = ((...( [] (+) ps1) (+) ps2 (+)...) (+) psn) = ((....( vadd []++[0] ps1) (+) ps2 ....) (+) psn) = (((....(ps1 (+) ps2 ) (+) ps3) .....) (+) psn) = foldl1 (+) (psums xs ys)
flipとreverseを使えばできます。演算子を全て入れ替えればなんでもできます。
知らんかった・・・・つまりこういうことか
vmuls xs ys = foldr1 (flip (+)) (reverse psums xs ys)
normがバグバグです。 先生に日本語が通じません。 先生、normがまだバグバグです。
知ってる人にはあたりまえなんだろうけど、一応
foldlは最初に二項演算子と「種」とリストを受け取ります
foldl1には種はありません。リストに対してそのまま演算を行ないます。
つまり、
型で書くと、
ただ一つの型変数しかでてこない。