ワンライナーHaskellでグレゴリオオンリーのツェラーの公式を書いた
はじめに
こんにちはゾディアックです。
この記事はアドベントカレンダー
PMOB Advent Calendar 2018 - Adventar
13日目の記事です。
尿意を催してきたので、急いで書かせて貰います。
ツェラーの公式
西暦と月と日を引数とし、曜日を返す関数です。
ツェラーの公式 - Wikipedia
詳しくはググってください。今回はグレゴリオ歴オンリーです。
故に恒常的に
とする。
パパっとやって、終りっ
以下がコード(関数)です。ghciとかでやってください。
y:year, m:month, d:dayです。
1,2月が前年分の13,14月に変貌させないといけない使用なのですが、
if文や三項演算子みたいなものを使用して実装すると、
我が感覚的にキモいと思いました。
そこでmonthの、
を
に対応させる関数を片手間で考えました。
yearも対応して1,2月のときには前年に対応させる必要があります。
考えたのがこれです。
以下が完全コード(純粋関数)です。今度最適化します。
greZel y m d = ["MON","TUE","WED","THU","FRI","SAT","SUN"]!!((d+(26*((m+12-12*((m+12)`div`15)+1))`div`10)+(y+((m+12)`div`15)-1)`mod`100+((y+((m+12)`div`15)-1)`mod`100)`div`4+5*((y+((m+12)`div`15)-1)`div`100)+((y+((m+12)`div`15)-1)`div`100)`div`4+5)`mod`7)
えぐいので書き換えると
greZel y m d = ["MON","TUE","WED","THU","FRI","SAT","SUN"]!! ((d +(26*((m+12-12*((m+12)`div`15)+1))`div`10) +(y+((m+12)`div`15)-1)`mod`100 +((y+((m+12)`div`15)-1)`mod`100)`div`4 +5*((y+((m+12)`div`15)-1)`div`100) +((y+((m+12)`div`15)-1)`div`100)`div`4 +5) `mod`7)
もっというと
greZel y m d = ["MON","TUE","WED","THU","FRI","SAT","SUN"]!! ((d +(26*(m1+1))`div`10 +y2 +y2`div`4 +ga +5)`mod`7) where m1 = m+12 - 12*((m+12) `div` 15) y1 = y + ((m+12) `div` 15) - 1 y2 = y1 `mod` 100 c = y1 `div` 100 ga = 5*c + c `div` 4
最後に
久々にコード書きました。
ワンライナーとか馬鹿なので絶対にやらない方がいいです。
赤ワイン昨日買ったばっかなのにもう無いのはおかしいと思う。
双方向赤青LEDにおける高速交流のデューティ比制御による色彩制御
はじめに
こんにちはゾディアックです。
この記事はアドベントカレンダー
PMOB Advent Calendar 2018 - Adventar
6日目の記事です。
只今著者は良い気分であります。
又、投稿が遅れて申し訳無いという気持ちも相まって、
割りと親切に書こうと決意致しました所存であります。
どうか御覚悟をといったところでしょうか。
双方向赤青LEDに関して
最近秋月電子で発売された、
電流を流す向きで赤と青別の色が光る
(向きは忘れただってどっちでもいいし)LEDで、
私が勝手に双方向と呼んでいるだけです。
足は二本だけ。
これです
2色LED 赤・青 5mm 2端子 OSRBP25111A (10個入): LED(発光ダイオード) 秋月電子通商-電子部品・ネット通販
端子が二端子なので、どのように使うか考えていました。
メカニカルリレー触ってたら気が付いた
最近は、二回路C接点メカニカルリレーに触れてみたんですが、
コイルの音がカチカチと鳴るもので、とても良いものです。
一番左がコイルで、コイルに電圧を加える可否で、
右のスイッチを切り替えられるもので、切り替え時に音が鳴る。
詰まりは、1-16が0[V]の時に4-6と13-11で導通し、
1-16が5[V]の時に4-8と13-9で導通するということです。
然しコイルに電流をある程度供給する必要があり、
さもないと切り替わりません。
これを使うメリットは大いにあります。
一つは一つの入力での複数スイッチの自動制御が可能なことです。
一々手でやらなくて良いのですよ。
二つ目は高い絶縁性です。コイル部分と制御回路が独立されている故に、
コイル部分と制御する回路で、電圧の異なる回路で使えますね。
これです
5V小型リレー 接点容量:2A 2回路C接点 941H−2C−5D: パーツ一般 秋月電子通商-電子部品・ネット通販
接点というのも種類がありますが、今回使ったのはC接点です。
これが割りと肝となってきます。
OFF時に導通する回路とON時に導通する回路があるのが重要であります。
そこでこういう回路を考えてみたわけです。
コイルOFFの時に赤が光り、ONの時に青が光ります。
CRDというのは定電流ダイオードのことで、一定の電流を流します。
ここでは20[mA]です。LEDは流せる電流が大体決まっていて、
流しすぎると発熱で燃えます。
ここでですよ。このコイル切り替えを高速でやったら、
一体どうなると思いますか。
赤と青が同時に光って見える筈です。
人間の目はアホです。蛍光灯のglimpseさえ知覚できないのです。
ですから、人間の目を欺くくらいは、比較的に容易でしょう。
然しながら、リレーのコイル駆動はそんなに高速に行えません(物理的に)。
故にどうすべきか。
FETとか使ってみようか
field-effect-transistor の略で、従来とは構造の異なるトランジスタです。
スイッチングとか高速に動作してくれるので、
高速駆動制御したい今回は重宝しました。
それに論理回路ってトランジスタだけで構成できるんですよ。
ONOFFの繰り返しの周期的出力をパルスと呼びますが、
パルスにnot回路をかますと反転して返ってきます。
更にnot回路をかませば出力は元に戻ります。
こんな回路を考えてみました。
使ったFET
NchパワーMOSFET 2SK4017(Q) (60V5A): 半導体 秋月電子通商-電子部品・ネット通販
安価で速く小さくてお手頃、pチャンネルです。
できたやつ
ブレボに刺して使えます。
本来ブレボは高周波向きませんが、まあめんどいので良いです。
パルス発生のオシレーター
お馴染みのタイマーic555を使ってパルスを得ます。
ボリュームを変えると周波数やデューティ比を調節できます。
できましたよ
低周波。波打ってます。
高周波
カメラって凄くて、
高周波でも「さては高周波だなテメー」
と易々と看破してきます。故に波打つ訳です多分。
点滅を高速にすることで、同時点灯に見えるのと、
デューティ比制御で色彩コントロールもまあ成功です。
最後に
寒いですね。
RGBカラーセンサでRGBでLED分光表示してみた(ポータブル)。
まえがき
どうもお久しぶりのゾディアックです。この記事はアドベントカレンダー
adventar.org
の二日目の記事です。
RGBカラーセンサとは
RGBのそれぞれの波長に反応するセンサ。それぞれの波長に対して入力を受けた時に電流を流すようになる(多分そう)。使ったのはこれ
akizukidenshi.com
一応言っておきますと、部品を理解する上ではデータシート必読です。お願いします。
乾電池の1.5[V]を5[V]に昇圧する
すみません乾電池を1本使う前提なのですが、LEDはまず1.5[V]では光らないでしょう。なので5[V]に昇圧するわけなのですが、使った回路はアップコンバータのこれです。
参考文献
trend-neta.com
この回路は1WならパワーLEDという電流をめっちゃ要するめっちゃ明るいLEDにも使えることは確認済みです。最大供給電流は500[mA]なので、まあイケるでしょうと思っていました。
5[V]電源でRGBカラーセンサとLEDの発光に分配
このRGBカラーセンサには電圧を印加します。5[V]印加して、特定の波長が入力された時に出力が発生します。その出力では足りないので、オペアンプ(LM324)で出力を増幅して、FETにかましてLEDを光らせます。トランジスタのスイッチング動作にて。
回路はこれ
参考文献
www.footfoot.tokyo
直接発光する光源にカラーセンサを押し当ててもいいのですが、それでは味気ないので、この人は白色LEDの照り返しの返ってきた波長を読み取って、対象物の色が何色か判断するものを作っています。
実際に作ってみた
制作物として実際出来たもの
照り返しさせる白色LEDはON-OFFが切り替えられます(LED上のスイッチで)。パワー供給も、電池以外で別途5[V]印加して使えて(右上のスイッチで電源切り替え)、電池とか使いたくない或いはもったいないなって時にも出来ます。左下スイッチは大元の電源スイッチです。青色が光っているのは、机上の電気(白色LED)の波長が青っぽいからでしょうかね。
机上のLED
akizukidenshi.com
実験です。この煙草、ガラムといいます。タールが33mgあるやつです。俺はいつもこれ吸ってます。美味しいですよ。パッケージ赤いですね。
赤色のパッケージにかざすと
赤色が光る。正解。
私の作ったもののメリット
ポータブルであり、いつでも何処でも、「この光に何色が含まれているかな」という調査が可能。
発展的に考えていること
暗号への応用で、RGBLEDとカラーセンサの対応で、精密なものにすればパターン的に連続なものであるから、相当強固な暗号が築けるのではないかという仮設を立てています。そうでなくてもLEDとセンサのペア数を増やせばどうだろう。
あとがき
酔っ払いながら記事書きましたごめんなさい。four roses(ウイスキー)おいしいですね。
コラッツの問題をHaskellで書いてみた
おちんちんなんかにまけないんだからねっ!///
先ず結論を言おう。
おちんちんに負けました...
おちんちんに負けないために毎月末に快楽天を買っています。もちろん紙媒体です。電子書籍は味気ないとマキシマの旦那も言っている。
コラッツの問題とは
簡単に説明すると任意(日本語的な意味で)の1以上の自然数から始まる数列で、偶数ならば次項を割る2したものとして、奇数ならば3倍して1を足したものとする漸化式です。IQが1なので全く意味がわかりませんが、任意(forallの意味で)の1以上の自然数から初めて1に収束するという予想だそうです。まだ証明されていません。数学者ポール・エルデシュは「数学はまだこの種の問題に対する用意ができていない」と述べています。解決した人に500ドルを提供するという懸賞問題です。おちんちんなんかにまけないんだからね?///
やってみた
以下がコード。
collatz x | x == 1 = [1] | x `mod` 2 == 0 = [x] ++ collatz (x `div` 2) | x `mod` 2 /= 0 = [x] ++ collatz (x*3+1)
無限リストです。x に初期値をかませます。
wikipediaにもありますが、初期値に27を選ぶと、数列の生成が111ステップにもなり、最大値が9232まで膨れ上がります。
この問題の肝は不確定性だと思っていて、任意の1以上の数から始められることと、そこから生成される数列が予想できないというところですかね。ゴルドバッハ予想と関連があったりするのかなあ(もにゃもにゃ)。
ではでは。
Haskellで行列式を計算する
プログラムコード
まぁ前々回のブログでも書きましたけど、
今読んでる「関数プログラミング珠玉のアルゴリズムデザイン」って本の内容そのままです。
これです。
この行列式演算のアルゴリズムは、Chioのピボット濃縮アルゴリズムである。
Chió Pivotal Condensation -- from Wolfram MathWorld
ここみて。
Chioのピボット濃縮アルゴリズムだが、これは比較的速い。
どれくらい速いかとか、何で速いか、とかは、は忘れた。
自分で調べろ。人に聞くな。
以下がコード。
condense = map (map det . pair . uncurry zip) . pair where pair (x:xs) = map ((,) x) xs det ((a,b),(c,d)) = a * d - b * c det :: [[Integer]] -> Integer det [[x]] = x det xss = case break ((/= 0) . head) xss of (yss,[]) -> 0 (yss,zs:zss) -> let x = det (condense (zs : yss ++ zss)) d = head zs ^ (length xss - 2) y = x `div` d in if even (length yss) then y else -y cd k = map (map det . pair . uncurry zip) . pair where pair (x:xs) = map ((,) x) xs det ((a,b),(c,d)) = (a * d - b * c) `div` k det' :: Integer -> [[Integer]] -> Integer det' k [[x]] = x det' k xss = case break ((/= 0) . head) xss of (yss,[]) -> 0 (yss,zs:zss) -> let x = det' (head zs) (cd k (zs : yss ++ zss)) in if even (length yss) then x else -x
暇だったら加筆します。
ではでは。
Haskellで上位者問題を解く
酒の神「バッカス」
おはようございます。
しょうがないからBlack日課飲んでます。
こういう世の中なんですよ今の日本は。
資本主義と見せかけて社会主義っぽくもある気持ち悪さ。
そして根本的な教育の方針の欠陥。
大学とかこういう場に来て尚実感してこういう感想に至った次第です。
この国は終わりです。海外へ逃げる準備をした方がいいですよ皆さん。
色々な信念とか思想を人々はもっていますけれでも、
先入観とか言ったイドラは違います。これは良くないです。
「人間思ったほど客観視出来てはいない」それはそうですが、だから諦めるのか?という感じではあります。
冷静になって自分を切り離して客観視する努力は必要なのであります。
まぁせめてProkrustesbettのあやまちを犯さないようにしたい。
生きろ
最近生きながらにして死んでいる人が多い気がする。
ケルケゴールは「死に至る病」で、
「無自覚者も死に至る病を患う」といっています。
でもでも、無自覚者って、本人の感覚としては、
絶望を知らないんですから、とても幸せなんだと思いますけど。
いやでも、「人間は動物より勝っているからこそ、言いかえれば人間は自己であり精神であるからこそ、絶望することができるのである」
かもしれませんね。
人間の生きる骨は「愚鈍さ」と「慣れ」な気がしてきましたからね。
そもそも人間ってなんだろうって思うけれども、
「最低限の理性と、知的好奇心とか、精神を持っていて魂が輝いている生物」
こんな定義をしたら個人的にこの眼で見て人間だなと感じた人は少ない。
まぁこれは人間はこう有るべきみたいな、私の個人的な理想像でもあるので、
あんまり気にしないでくださいというか、些か強引すぎますかねぇ。
御託はいいから講釈垂れてよ
このフレーズは「げんがくさばいば」さんから拝借しました。
私の尊敬する人の一人です。
title的に考えますと今回は「Haskellで上位者問題を解く」ですね。
まぁ前々回のブログでも書きましたけど、
今読んでる「関数プログラミング珠玉のアルゴリズムデザイン」って本の内容そのままです。
これです。
今回は第二章です。
「上位者問題」ってご存知でしょうか。
説明いたしますと、配列の一つの要素に対して、その上位者とは、
その要素の右側に有り、その要素より大きい要素をいいます。
つまり、上位者は配列x[]で「かつ」ですかね。
例えば「APPLE」という文字列で考えた時に、
A;0,B;1..といったふうに割り当てた時、
それぞれの文字の持つ上位者の数、上位者数は、
[('A',4),('E',0),('L',0),('P',0),('P',0)]
となります。この場合、最大値はAの4となります。
こういったふうにして、文字列の最大上位者数を求めていきます。
当たり前だけどHaskellでな
今回もHaskellで、しかも分割統治法を使います。
皆さんの身近な分割統治法の例ですと、「クイックソート」とかそうですね。
問題を小さくして、その小さい問題を解いて元の大きさの問題を解いたことにする、というものだと思ってます。
まぁみなさんは生まれながらにしてHaskellはわかると思うので大丈夫でしょう。
以下がコードです。
import Data.List join 0 txs [] = txs join n [] tys = tys join n txs@((x,c) : txs') tys@((y,d) : tys') | x < y = (x,c+n) : join n txs' tys | x >= y = (y,d) : join (n-1) txs tys' table [x] = [(x,0)] table xs = join (m-n) (table ys) (table zs) where m = length xs n = m `div` 2 (ys,zs) = splitAt n xs msc s = maximum $ map snd (table s)
これはさっきもいいましたが、
「文字列の最大上位者数」を求めます。
その関数はmscですね。msc (文字列)という風にご利用ください。
msc関数を説明しますと、その引数(s)をまずtable関数で受けます。
table関数はタプルにして、各文字とその上位者数の組にして、
その全部をリストにして返します。
table関数はO()らしいです。
となると当然mscも同じくそうなることがわかりますね。
終わりです。投げやりかもしれませんね。すみません、
ではでは。
そうだ俺が怠惰の罪だ
おはよう
おはよう。さっき起きたよ。
流石にヤバイ。単位大丈夫かしら。
それとね。僕はね、
「C言語なんて書きたくない!!!」
「ポインタなんて知るか!!!しね!!!」
うーん。ポインタでごちゃごちゃやってるの読みにく過ぎる。
あれだ、でもちゃんとやるよ。
ただ、もうちょっと時間がいるな。
その前に、大学にちゃんと行かないとね。
それはそうと、ウィリアム・ギブスンの「ニューロマンサー」を、
今読んでいてはまってるんですけど、
サイバーパンク最高か。
お尻を出した子一等賞って感じである。
Haskellはいいぞ
Haskellの特殊な機能というわけではなくて、Haskellに有る機能、
便利な機能が集約されている。
つい最近、「一瞬でHaskellで円周率を一億桁計算する」みたいな、
そういう記事を見つけた。
一億桁を630秒くらいで計算してやるとかいうものであった。
これ↓
Haskellで円周率1億桁を計算する、あるいは円周率計算にHaskellの多倍長整数の改良を見る - 純粋関数空間
でもね、俺のPCでコンパイルして実行したら、390秒だった。
めっちゃ速かった。
恐らくだけど、ByteStringとか使ってbit列扱えるやつとか、
並列処理で速くなるっしょ!って
思ってたんだけど、
どうやらかなり複雑な実装されてるっぽい(わからなかった)
多倍長整数の演算がgmpによって実装されており、高速であるらしい。
並列処理もしてない。
並列化は意味なくて、やってもあんまり速くならないらしい。
そもそもの乗算、これは、FFTで実装されているらしいが、
これ自体を並列化しないと意味がないっぽい。
実装どうやってされてんの?
ってここで思ったわけで、ちょっと調べた。
以下が実装なのか?
Springerの「Intelligent Computer Mathematics」を参考にした。
-- Implementation of Cooley-Tukey algorithm in Haskell fft :: [Complex Double] -> [Complex Double] fft f = mix [fft (l @+ r), fft ((l @- r)@* w)] where (l, r) = splitAt (length f `div` 2) f mix = concat . transpose (@+) f g = zipWith (+) f g -- @-, @* analog -- w is list of powers of an n-th primitive root of unit -- FFT-based multiplication modulo x^n - 1 in Haskell (%*%) :: (Num a) => [a] -> [a] -> [a] (%*%) f g = unlift $ ifft ((fft $ lift f) @* (fft $ lift g)) -- where lift :: (Num a) => [a] -> [Complex Double] -- unlift :: [Complex Double] -> [Int] -- ifft is the inverse fft, basicly thesame fft with -- different twiddle factors. -- And (@*) is still element-wise multiplication
Haskellの乗算はめっちゃ速い。
Computing the factorialで考えると、
NaiveC++よりNaiveHaskellの方が全然速いくらいである。
FFTだからなのだろうか。
おわり。
ではでは。