ZODIACの黙示録

なにもしないことをする

ワンライナーHaskellでグレゴリオオンリーのツェラーの公式を書いた

はじめに

こんにちはゾディアックです。
この記事はアドベントカレンダー
PMOB Advent Calendar 2018 - Adventar
13日目の記事です。
尿意を催してきたので、急いで書かせて貰います。
f:id:zodi_G12:20181213200049j:plain

ツェラーの公式

西暦と月と日を引数とし、曜日を返す関数です。
ツェラーの公式 - Wikipedia
詳しくはググってください。今回はグレゴリオ歴オンリーです。
故に恒常的に
 \Gamma = 5C+ \lfloor \frac{C}{4} \rfloor
とする。
f:id:zodi_G12:20181213200135j:plain

パパっとやって、終りっ

以下がコード(関数)です。ghciとかでやってください。
y:year, m:month, d:dayです。
1,2月が前年分の13,14月に変貌させないといけない使用なのですが、
if文や三項演算子みたいなものを使用して実装すると、
我が感覚的にキモいと思いました。
そこでmonthの、
 1,2,3,4,5,6,7,8,9,10,11,12

 13,14,3,4,5,6,7,8,9,10,11,12
に対応させる関数を片手間で考えました。
yearも対応して1,2月のときには前年に対応させる必要があります。
考えたのがこれです。
 m = (m+12) - 12(\lfloor \frac{m+12}{15} \rfloor)
以下が完全コード(純粋関数)です。今度最適化します。

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)

f:id:zodi_G12:20181213201608j:plain

えぐいので書き換えると

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

f:id:zodi_G12:20181213210232j:plain

最後に

久々にコード書きました。
ワンライナーとか馬鹿なので絶対にやらない方がいいです。
赤ワイン昨日買ったばっかなのにもう無いのはおかしいと思う。
f:id:zodi_G12:20181213192055j:plain

双方向赤青LEDにおける高速交流のデューティ比制御による色彩制御

はじめに

こんにちはゾディアックです。
この記事はアドベントカレンダー
PMOB Advent Calendar 2018 - Adventar
6日目の記事です。
只今著者は良い気分であります。
又、投稿が遅れて申し訳無いという気持ちも相まって、
割りと親切に書こうと決意致しました所存であります。
どうか御覚悟をといったところでしょうか。

双方向赤青LEDに関して

最近秋月電子で発売された、
電流を流す向きで赤と青別の色が光る
(向きは忘れただってどっちでもいいし)LEDで、
私が勝手に双方向と呼んでいるだけです。
f:id:zodi_G12:20181206140326j:plain
足は二本だけ。
これです
2色LED 赤・青 5mm 2端子 OSRBP25111A (10個入): LED(発光ダイオード) 秋月電子通商-電子部品・ネット通販
端子が二端子なので、どのように使うか考えていました。

カニカルリレー触ってたら気が付いた

最近は、二回路C接点メカニカルリレーに触れてみたんですが、
コイルの音がカチカチと鳴るもので、とても良いものです。
f:id:zodi_G12:20181206135642j:plain
一番左がコイルで、コイルに電圧を加える可否で、
右のスイッチを切り替えられるもので、切り替え時に音が鳴る。
詰まりは、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時に導通する回路があるのが重要であります。
そこでこういう回路を考えてみたわけです。
f:id:zodi_G12:20181206153212j:plain
コイルOFFの時に赤が光り、ONの時に青が光ります。
CRDというのは定電流ダイオードのことで、一定の電流を流します。
ここでは20[mA]です。LEDは流せる電流が大体決まっていて、
流しすぎると発熱で燃えます。

ここでですよ。このコイル切り替えを高速でやったら、
一体どうなると思いますか。
赤と青が同時に光って見える筈です。
f:id:zodi_G12:20181206160807j:plain
人間の目はアホです。蛍光灯のglimpseさえ知覚できないのです。
ですから、人間の目を欺くくらいは、比較的に容易でしょう。
然しながら、リレーのコイル駆動はそんなに高速に行えません(物理的に)。
故にどうすべきか。

FETとか使ってみようか

field-effect-transistor の略で、従来とは構造の異なるトランジスタです。
スイッチングとか高速に動作してくれるので、
高速駆動制御したい今回は重宝しました。
それに論理回路ってトランジスタだけで構成できるんですよ。
f:id:zodi_G12:20181206161347p:plain
ONOFFの繰り返しの周期的出力をパルスと呼びますが、
パルスにnot回路をかますと反転して返ってきます。
更にnot回路をかませば出力は元に戻ります。
こんな回路を考えてみました。
f:id:zodi_G12:20181206161759j:plain
使ったFET
NchパワーMOSFET 2SK4017(Q) (60V5A): 半導体 秋月電子通商-電子部品・ネット通販
安価で速く小さくてお手頃、pチャンネルです。
できたやつf:id:zodi_G12:20181206162327j:plain
ブレボに刺して使えます。
本来ブレボは高周波向きませんが、まあめんどいので良いです。
パルス発生のオシレーター
f:id:zodi_G12:20181206162318j:plain
お馴染みのタイマーic555を使ってパルスを得ます。
ボリュームを変えると周波数やデューティ比を調節できます。

できましたよ

低周波。波打ってます。
f:id:zodi_G12:20181206162251j:plain
高周波
f:id:zodi_G12:20181206162256j:plain
カメラって凄くて、
高周波でも「さては高周波だなテメー」
と易々と看破してきます。故に波打つ訳です多分。
点滅を高速にすることで、同時点灯に見えるのと、
デューティ比制御で色彩コントロールもまあ成功です。

最後に

寒いですね。

RGBカラーセンサでRGBでLED分光表示してみた(ポータブル)。

まえがき

どうもお久しぶりのゾディアックです。この記事はアドベントカレンダー
adventar.org
の二日目の記事です。

RGBカラーセンサとは

RGBのそれぞれの波長に反応するセンサ。それぞれの波長に対して入力を受けた時に電流を流すようになる(多分そう)。使ったのはこれ
akizukidenshi.com

一応言っておきますと、部品を理解する上ではデータシート必読です。お願いします。

乾電池の1.5[V]を5[V]に昇圧する

すみません乾電池を1本使う前提なのですが、LEDはまず1.5[V]では光らないでしょう。なので5[V]に昇圧するわけなのですが、使った回路はアップコンバータのこれです。
f:id:zodi_G12:20181201235438j:plain

参考文献
trend-neta.com

この回路は1WならパワーLEDという電流をめっちゃ要するめっちゃ明るいLEDにも使えることは確認済みです。最大供給電流は500[mA]なので、まあイケるでしょうと思っていました。

5[V]電源でRGBカラーセンサとLEDの発光に分配

このRGBカラーセンサには電圧を印加します。5[V]印加して、特定の波長が入力された時に出力が発生します。その出力では足りないので、オペアンプ(LM324)で出力を増幅して、FETにかましてLEDを光らせます。トランジスタのスイッチング動作にて。

回路はこれf:id:zodi_G12:20181202000307p:plain

参考文献
www.footfoot.tokyo


直接発光する光源にカラーセンサを押し当ててもいいのですが、それでは味気ないので、この人は白色LEDの照り返しの返ってきた波長を読み取って、対象物の色が何色か判断するものを作っています。

実際に作ってみた

制作物として実際出来たもの

f:id:zodi_G12:20181202001119j:plainf:id:zodi_G12:20181202001134j:plain

照り返しさせる白色LEDはON-OFFが切り替えられます(LED上のスイッチで)。パワー供給も、電池以外で別途5[V]印加して使えて(右上のスイッチで電源切り替え)、電池とか使いたくない或いはもったいないなって時にも出来ます。左下スイッチは大元の電源スイッチです。青色が光っているのは、机上の電気(白色LED)の波長が青っぽいからでしょうかね。

机上のLED
akizukidenshi.com

実験です。この煙草、ガラムといいます。タールが33mgあるやつです。俺はいつもこれ吸ってます。美味しいですよ。パッケージ赤いですね。

f:id:zodi_G12:20181202001625j:plain

赤色のパッケージにかざすと

f:id:zodi_G12:20181202001707j:plain

赤色が光る。正解。

私の作ったもののメリット

ポータブルであり、いつでも何処でも、「この光に何色が含まれているかな」という調査が可能。

発展的に考えていること

暗号への応用で、RGBLEDとカラーセンサの対応で、精密なものにすればパターン的に連続なものであるから、相当強固な暗号が築けるのではないかという仮設を立てています。そうでなくてもLEDとセンサのペア数を増やせばどうだろう。

あとがき

酔っ払いながら記事書きましたごめんなさい。four roses(ウイスキー)おいしいですね。

コラッツの問題をHaskellで書いてみた

ドカべンと可憐ヌー

この記事は

IQが1 Advent Calendar 2017 - Adventarの6日目の記事です。

おちんちんなんかにまけないんだからねっ!///

先ず結論を言おう。
おちんちんに負けました...

おちんちんに負けないために毎月末に快楽天を買っています。もちろん紙媒体です。電子書籍は味気ないとマキシマの旦那も言っている。

コラッツの問題とは

これですコラッツの問題 - Wikipedia

簡単に説明すると任意(日本語的な意味で)の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で行列式を計算する

アドべンヌカレンヌー

この記事は

PMOB Advent Calendar 2016 - Adventarの21日目の記事です。

  • 前の記事[Not Found]
  • 次の記事[みせられないよ]

プログラムコード

まぁ前々回のブログでも書きましたけど、

今読んでる「関数プログラミング珠玉のアルゴリズムデザイン」って本の内容そのままです。

これです。

Amazon CAPTCHA

この行列式演算のアルゴリズムは、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で上位者問題を解く

アドセンスカレンダー

この記事は

PMOB Advent Calendar 2016 - Adventarの11日目の記事です。

  • 前の記事

後世に残すモノづくり - ざっきーの雑記ー

  • 次の記事[みせられません]

酒の神「バッカス

おはようございます。

しょうがないからBlack日課飲んでます。

こういう世の中なんですよ今の日本は。

資本主義と見せかけて社会主義っぽくもある気持ち悪さ。

そして根本的な教育の方針の欠陥。

大学とかこういう場に来て尚実感してこういう感想に至った次第です。

この国は終わりです。海外へ逃げる準備をした方がいいですよ皆さん。

色々な信念とか思想を人々はもっていますけれでも、

先入観とか言ったイドラは違います。これは良くないです。

「人間思ったほど客観視出来てはいない」それはそうですが、だから諦めるのか?という感じではあります。

冷静になって自分を切り離して客観視する努力は必要なのであります。

まぁせめてProkrustesbettのあやまちを犯さないようにしたい。

生きろ

最近生きながらにして死んでいる人が多い気がする。

ケルケゴールは「死に至る病」で、

「無自覚者も死に至る病を患う」といっています。

でもでも、無自覚者って、本人の感覚としては、

絶望を知らないんですから、とても幸せなんだと思いますけど。

いやでも、「人間は動物より勝っているからこそ、言いかえれば人間は自己であり精神であるからこそ、絶望することができるのである」
かもしれませんね。

人間の生きる骨は「愚鈍さ」と「慣れ」な気がしてきましたからね。

そもそも人間ってなんだろうって思うけれども、

「最低限の理性と、知的好奇心とか、精神を持っていて魂が輝いている生物」

こんな定義をしたら個人的にこの眼で見て人間だなと感じた人は少ない。

まぁこれは人間はこう有るべきみたいな、私の個人的な理想像でもあるので、

あんまり気にしないでくださいというか、些か強引すぎますかねぇ。

御託はいいから講釈垂れてよ

このフレーズは「げんがくさばいば」さんから拝借しました。

私の尊敬する人の一人です。

title的に考えますと今回は「Haskellで上位者問題を解く」ですね。

まぁ前々回のブログでも書きましたけど、

今読んでる「関数プログラミング珠玉のアルゴリズムデザイン」って本の内容そのままです。

これです。

Amazon CAPTCHA

今回は第二章です。

「上位者問題」ってご存知でしょうか。

説明いたしますと、配列の一つの要素に対して、その上位者とは、

その要素の右側に有り、その要素より大きい要素をいいます。

つまり、上位者は配列x[]で「 i \verb|<| jかつ x[i] \verb|<| x[j]のときのx[j]」ですかね。

例えば「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( n \log{n})らしいです。

となると当然mscも同じくそうなることがわかりますね。

終わりです。投げやりかもしれませんね。すみません、

ではでは。

そうだ俺が怠惰の罪だ

そういえば

この記事は

PMOB Advent Calendar 2016 - Adventarの8日目の記事です。

  • 前の記事

web.matsub.tech

  • 次の記事[🍆]

おはよう

おはよう。さっき起きたよ。

流石にヤバイ。単位大丈夫かしら。

それとね。僕はね、

C言語なんて書きたくない!!!」

「ポインタなんて知るか!!!しね!!!」

うーん。ポインタでごちゃごちゃやってるの読みにく過ぎる。

あれだ、でもちゃんとやるよ。

ただ、もうちょっと時間がいるな。

その前に、大学にちゃんと行かないとね。

それはそうと、ウィリアム・ギブスンの「ニューロマンサー」を、

今読んでいてはまってるんですけど、

サイバーパンク最高か。

お尻を出した子一等賞って感じである。

Haskellはいいぞ

Haskellの特殊な機能というわけではなくて、Haskellに有る機能、

便利な機能が集約されている。

つい最近、「一瞬でHaskellで円周率を一億桁計算する」みたいな、

そういう記事を見つけた。

一億桁を630秒くらいで計算してやるとかいうものであった。

これ↓

Haskellで円周率1億桁を計算する、あるいは円周率計算にHaskellの多倍長整数の改良を見る - 純粋関数空間


でもね、俺のPCでコンパイルして実行したら、390秒だった。

めっちゃ速かった。

恐らくだけど、ByteStringとか使ってbit列扱えるやつとか、

並列処理で速くなるっしょ!って

思ってたんだけど、

どうやらかなり複雑な実装されてるっぽい(わからなかった)

多倍長整数の演算がgmpによって実装されており、高速であるらしい。

並列処理もしてない。

並列化は意味なくて、やってもあんまり速くならないらしい。

そもそもの乗算、これは、FFTで実装されているらしいが、

これ自体を並列化しないと意味がないっぽい。

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だからなのだろうか。

おわり。

ではでは。