Hatena::ブログ(Diary)

計算機と戯れる日々 このページをアンテナに追加 RSSフィード

2011-09-25

problem38

パンデジタル数になるのは 少なくともn<=9

連結される数はn=2のとき最初が4桁と次が5桁になるので 4999<x<9999 という軛がある。

面倒なので x<9999 , 2<=n<=10で実装すると

import Data.List

main = print $ maximum $concat $ map g [9..9999]

f::Int->Int->Int
f x y = read $foldl (++)  [] $map show $zipWith (*) [x,x..] [1..y]

g x = filter isPandigital $ map (x `f`) [2..9]

isPandigital x = "123456789" == ( sort $ show x)

concatしているところと isPandigital がちょっとダサイがまあいいでしょう。

Prelude Main> 932718654
(1.26 secs, 2637538728 bytes)

problem39

まあ、そのまま。

sortByなりmaximumByなりがData.Ordのcomparingを使わないといけないのがruby比較して面倒

import Data.List
import Data.Ord

main = print $ p

p = maximumBy (comparing length) $ group $ sort [x+y+z|x<-[1..998],y<-[x..998-x],z<-[y..998-x-y],x<=y,y<z,z^2==x^2+y^2]

problem 40

着陸したら全く終わらなかった。


main = print $ p

p = map (d.(10^)) [0..6]

d x = (g 190000)!!(x-1)

g x = foldl f "" [1..x]
      where f x y = x++(show y)

ちょっとカンニングして以下。

Prelude Data.Char> product [digitToInt $ ([0..] >>= show) !! x | x<- take 7 $ iterate (*10) 1]
210
(0.06 secs, 132123632 bytes)

concatMapの実装がすごいんだろうなー なぜこんなに速いのか理解できない。

2011-09-17

problem 33

いまいち美しくない。

Prelude List> let f a b c d = ((a==c && (a*10+b)/(c*10+d)==b/d)||(a==d&&(a*10+b)/(c*10+d)==b/c)||(b==c&&(a*10+b)/(c*10+d)==a/d)||(b==d&&(a*10+b)/(c*10+d)==a/c))&&(b/=0&&d/=0)&&(a/=c&&b/=d) in  map product $ transpose [[x,y]|x<-[10..99],y<-[10..99], div x y<1,f (read [(show x)!!0]) (read [(show x)!!1]) (read [(show y)!!0]) (read [(show y)!!1])]
[387296,38729600]
it :: [Integer]
(0.20 secs, 124395232 bytes)

problem34

なぜ5桁以内かを言えていない。

Prelude List> let f x=foldr (*) 1 [1..x]; g x=x==(sum $ map (f.read.(:[])) $show x)  in sum [x|x<-[3..100000],g x]
40730
it :: Integer
(5.22 secs, 3383707256 bytes)

problem35

ローテート関数が見つからなかったので自作

Prelude Data.Numbers.Primes> let g (x,y) = y++x ;f::Int->[Int];f x = map (read.g.(`splitAt` (show x))) [1..((length.show) x)-1] in length [x|x<-[1..1000000],isPrime x,all isPrime $ f x]
55
it :: Int
(3.13 secs, 4809034056 bytes)

probelm36

基数変換がダサい

Prelude> let d2b x = if (div x 2)/=0 then (d2b (div x 2))++[mod x 2] else [mod x 2]  in sum [x|x<-[1..1000000],show x==reverse (show x),d2b x==reverse (d2b x)]
872187
it :: Integer
(1.20 secs, 877606456 bytes)

problem37

primesとtailsを使ったので楽にできた。

Prelude Data.List Data.Numbers.Primes> let f x= all (isPrime.read) $ filter (/=[]) $ tails (show x) ++ (map reverse (tails (reverse (show x)))) in sum $ take 11 [x|x<-primes,x>10,f x]
748317
it :: Integer
(4.51 secs, 2714735608 bytes)

2011-07-09

chshを使用せずにログイン時のシェルを変える

chsh -s を使用せずにログイン時のシェルを変える

zshに変えられないとき

.bash_loginに以下を追記

if [ -f /bin/zsh ]; then exec zsh ; fi

これだとzshの無いマシンでも安心

.screenrcに以下を追記

shell zsh

2011-07-03

rubyのscanはブロック無のほうが便利

String.scan(re){ブロック}がstringを返すのでStringオブジェクト拡張した。

class String
  def scanA(exp)                # scan(re)ブロック無しと同じ                                                             
    r=[]
    scan(exp){|i|r.push(yield i)}
    r
  end
end

そしたら。ブロックなしのscan(re)は返り値が配列だったorz

>> "abcde".scan(/../)
=> ["ab", "cd"]
>> "abcdefghi".scan(/(..)./)
=> [["ab"], ["de"], ["gh"]]
>> "abcdefghi".scan(/(..)(.)/)
=> [["ab", "c"], ["de", "f"], ["gh", "i"]]

rubyの car,cdr もしくは haskellにおける head tail last init

rubycar,cdr もしくは haskellにおける head tail last initについて

haskellにおける head tail lastはそれぞれ

>> [1, 2, 3, 4, 5].first
=> 1
>> [1, 2, 3, 4, 5].drop(1)
=> [2, 3, 4, 5]
>> [1, 2, 3, 4, 5].last
=> 5

だとおもう。でもなんかinit(最後の要素をのぞく)がmodule Enumerableになさそう。

>> module Enumerable ; def init ; self.take(self.size-1) ; end; end
=> nil
>> [1, 2, 3, 4, 5].init
=> [1, 2, 3, 4]

なんでないのかな。せめて drop_from_last(n)みたいなのでもあればいいのに…(last->behindかな?)

2011-07-02

sudo でファイルにアペンド

sudoファイルに追記するとき

$ sudo echo aaa >> a

パーミッションがないときエラーになってしまうのでこういう時には sudo tee -aを使う

$ echo aaa >> sudo tee -a a