[AppleScript]

キミならどう書く 2.0 - ROUND 1 - 100までの整数から素数を列挙せよ@AppleScript / 2006-06-21 (水)

キミならどう書く 2.0 - ROUND 1 -— Lightweight Language Ringより。やっぱり俺が書くならAppleScriptだろうてことで書いてみた。基本はエラトステネスの篩なんだが、AppleScriptでリストを扱うとき、追加するのは簡単だけど取り除くのが面倒くさい上に遅くなるし、100じゃなくもっと多いときは死ぬほど遅くなる(主に最初のリストを作る時点で)ので、『素数リストと探索リスト』ではなく『素数リストと除外リスト』を作り、素数リストの最大値の二乗が探索リストの最大値を超えたら、(素数リストの一番最後の数+1)〜100から除外リストにある数字を除外して終了。なんつーか素朴だなぁw

property maxi : 100 --これを変えるとどこまで探すか変わる

on run
    set nmax to maxi --nmaxには探索リストの最大値を入れておく。探索リストを作る訳じゃないけど。
    set {pList, nList} to {{}, {}} --pListは素数リスト、nListは除外リスト(=非素数リスト)。
    repeat with i from 2 to maxi --一応2から最大値まで回す。
        log i
        if i is not in nList then --iが除外リストに入っていなければ作業。
            set end of pList to i --素数リストの最後にiを追加
            repeat with j from 2 to nmax div i --iの倍数(i*2からi*(nmax div i))を除外リストに追加する
                if (j * (item -1 of pList)) is not in nList then --除外リストに追加されるのは除外リストにない場合だけ
                    set end of nList to j * (item -1 of pList) ---除外リストの最後に追加
                end if
            end repeat
            repeat while (nmax is in nList) --探索リストの最大値が除外リストに入った場合
                set nmax to nmax - 1 --1ずつ減らしてみる
            end repeat
        end if
        if ((item -1 of pList) ^ 2) > nmax then exit repeat --(素数リストの最後)^2が探索リストの最大値より大きくなったら終わり
    end repeat
    repeat with i from (item -1 of pList) + 1 to maxi --plistには見つかった素数が入っているが、最後(最大)のものの次から除外リストに入っていないか確認
        if i is not in nList then set end of pList to i --除外リストに入っていない場合、素数リストに追加
    end repeat
    set CurrentDelimiter to AppleScript's text item delimiters --テキストアイテム区切りを保存
    set AppleScript's text item delimiters to " " --テキストアイテム区切りをスペースに
    set pList to pList as string --plistを文字列に変換
    set AppleScript's text item delimiters to CurrentDelimiter --テキストアイテム区切りをもとに戻す
    return pList --スペースで区切られた素数リストが出来ました
end run

探索リストを作ると遅くてかなわんのですよ。まぁ元々激しく遅い訳ですが、桁違いに遅くなる。

[ ツッコミの受付は終了しています ]
1: midore (06-06-27 13:17)
ぐるりさん、こんにちは。
私も考えてみました。自分のとこからトラックバックうてないんでコメントしちゃってます。
2: ぐるり (06-06-27 19:44)
seedは{}でも大丈夫ですよ。
個人的にはseedがglobal変数になってるのがちょっと……ということで書き直してみた。
on run
set pList to {}
repeat with targetnum from 2 to 100
set flag to true
repeat with i in pList
if (targetnum mod i) = 0 then
set flag to false
exit repeat
end if
end repeat
if flag then set end of pList to targetnum
end repeat
return pList
end run
3: midore (06-06-27 22:32)
をー、ありがとございます。

>seedがglobal変数...
これ正直、全く意識してなかったです(;^_^ 

flagをたててるんですね。なるほどぉーです。
4: midore (06-06-27 22:46)
う?
>seedがglobal変数になってる 
とのことだったんですが、

AppleScriptではグローバル宣言しないとグローバルにならないんじゃなかったけ?
だからローカル変数ですよね?>seed
違いましたっけ?
5: ぐるり (06-06-28 03:17)
あれ、昔は暗黙のrunハンドラの中で使ってる変数はglobalになってたはず……と思ってたら微妙に違うみたい。すみませんでした。
http://homepage1.nifty.com/ton_b/tips/MISC/Inplicit.html
6: midore (06-06-28 22:31)
いぇ、今回、ぐるりさんの華麗なスクリプトをみさせてもらえてべんきょになり楽しかったです。

>http://homepage1.nifty.com/ton_b/tips/MISC/Inplicit.html
あれ、こんなすばらしいページがあったんですね。

「キミならどう書く 2.0 - ROUND 1 - 100までの整数から素数を列挙せよ@AppleScript」のリンク用URL


[AppleScript]

AppleScriptで最大公約数 - いまさら既約分数クイズ / 2006-02-21 (火)

結城浩さんと言えばプログラマーで数学でクリスチャンな方で、結構な有名人ですが、実は彼の数学ガールが密かにお気に入りだ。いや、実は最近知ったんだけど。

たぶん一番人気であろう、ミルカさんシリーズもいいのだが、Where is the truth?シリーズも捨て難いものが。その中に、2003年末〜2004年初頭にかけて既約分数クイズというものがあった。問題自体は非常にシンプル。

問題:正の整数Nが与えられているとき、 以下の条件を満たす既約分数p/qを「すべて」求めるアルゴリズムを示してください。条件は:

  • p, qは整数(pは0以上で、qは1以上N以下).
  • gcd(p, q) = 1 (pとqの最大公約数は1).
  • 0 <= p/q <= 1.

これだけ。まぁ詳しくは原文を読んで頂くとして、AppleScript版の回答を作成してみたので、ここに書いておく。

on run
    my frac(9)
end run


on frac(n)
    set ans to {}
    repeat with q from 1 to n
        repeat with p from 0 to q
            if my gcd(p, q) = 1 then --(1)
                set end of ans to (p & "/" & q) as string
            end if
        end repeat
    end repeat
    return ans
end frac

on gcd(p, q)
    repeat until q = 0
        set {p, q} to {q, p mod q} --(2)
    end repeat
    return p
end gcd

ポイントはgcdハンドラの(2)。AppleScriptで最大公約数って?とか悩んだんだが、ユークリッドの互除法という方法を知り、AppleScriptで書いてみたのがこれ。WikipediaにはPythonでの例が掲載されていたが、入力された2数のmodを入れておく変数がp,qの他に必要だった。一方我らがAppleScriptにはリストがあるおかげですっきりと書く事が出来た。実質2行。fracハンドラでも、分子になるpの値を最大qまでと制限する事で計算量を減らすのは常套手段だね。qを1からnまで、pを0からqまでとする事で、0 <= p/q <= 1の検証はしなくて済んでいるし。実際はp,qの大小・qが0でない事の保証などをしなければならないのだろうが、今回は面倒なので見送り。そして他の人がやっている小さい順に並べるのも省略(ソートはAppleScriptには向かない気がするし。出来るけど)。

なお、runハンドラを

on run
    repeat with i from 1 to 9
        log my frac(i)
    end repeat
end run

とすれば、N=1〜9の時の答えがイベントログに残されるようになる。ソートはめんどくさいので、やらない。

[ ツッコミの受付は終了しています ]
1: ぐるり (06-02-21 04:52)
--一応N=1〜9の時の結果。
{"0/1","1/1"}
{"0/1","1/1","1/2"}
{"0/1","1/1","1/2","1/3","2/3"}
{"0/1","1/1","1/2","1/3","2/3","1/4","3/4"}
{"0/1","1/1","1/2","1/3","2/3","1/4","3/4","1/5","2/5","3/5","4/5"}
{"0/1","1/1","1/2","1/3","2/3","1/4","3/4","1/5","2/5","3/5","4/5","1/6","5/6"}
{"0/1","1/1","1/2","1/3","2/3","1/4","3/4","1/5","2/5","3/5","4/5","1/6","5/6","1/7","2/7","3/7","4/7","5/7","6/7"}
{"0/1", "1/1", "1/2", "1/3", "2/3", "1/4", "3/4", "1/5", "2/5", "3/5", "4/5", "1/6", "5/6", "1/7", "2/7", "3/7", "4/7", "5/7", "6/7", "1/8", "3/8", "5/8", "7/8"}
{"0/1", "1/1", "1/2", "1/3", "2/3", "1/4", "3/4", "1/5", "2/5", "3/5", "4/5", "1/6", "5/6", "1/7", "2/7", "3/7", "4/7", "5/7", "6/7", "1/8", "3/8", "5/8", "7/8", "1/9", "2/9", "4/9", "5/9", "7/9", "8/9"}

「AppleScriptで最大公約数 - いまさら既約分数クイズ」のリンク用URL


[AppleScript]

過去のAppleScriptたち / 2005-06-18 (土)

過去にこのサイトで公開していた奴でまだ公開に耐える奴を置いておく。

メール変換:先日アップルのディスカッションボードからリンク張られてたんで。

場所書類作りと使うのに必要なDialog Director 0.7。Classic Mac OS専用。

雑多なスクリプトもあったんだけど、X用に書き直してあるのをちょっと整理してちょっとずつ公開してみようと思ったり思わなかったり……

[ ツッコミの受付は終了しています ]
1: ぐるり (05-06-29 13:53)
ディスカッションボードから取りに来た人、すみません。リンク切れてました。
直しましたので、どぞ。

「過去のAppleScriptたち」のリンク用URL


[AppleScript]

ChooseCaptureApp(Tiger?対応版) / 2005-05-14 (土)

iPhotoとイメージキャプチャを選択できるAppleScript。それだけです^^;;;;;;,

  • デジカメを繋いだときに起動するアプリケーション(イメージキャプチャの環境設定で選べます)にこのAppletを指定すると、デジカメを繋いだときにiPhotoかイメージキャプチャのどちらを起動するか(あるいは何もしないか)を選択出来ます。
  • 日本語、出ます。
  • 英語も、出ます。
  • やる気があればさらに対応言語は増やせます。
  • システム環境設定(System Preferences.app)のdisplayed nameを見て言語を判定しています。

久しぶりに更新した。つーかrNoteにしてAppleScript関係のコンテンツをどうしようかと思いつつ見直していたらTigerでは起動できないことが発覚。一回でも起動してれば大丈夫だったようだけど、初めての人は駄目みたい。Script Editorからでは動かないんだもんな。いつの間にかsystem attribute "LANG"が空になってるんだもんな。そら動かんわ。ということで、誰のマックにも入っているであろう、システム環境設定のdisplayed nameを見て日本語か英語か判断するように変更してみました。

ChooseCaptureAppダウンロード(20KBくらい)


[AppleScript]

ChooseCaptureApp(初公開版) / 2002-03-24 (日)

iPhotoとイメージキャプチャを選択できるAppleScript。それだけです^^;;;;;;,

  • デジカメを繋いだときに起動するアプリケーションにこのAppletを指定すると、デジカメを繋いだときにiPhotoかイメージキャプチャのどちらを起動するか(あるいは何もしないか)を選択出来ます。
  • 日本語、出ます。一応化けません。少なくともぐるりのとこでは化けてません。
  • 英語も、出ます。もちろん化けません(当たり前)。
  • 一応Finderの言語を見て日本語と英語を判断しています。
  • 派手にベータ版なので、バグレポよろしくです^^;;;;;

初めて一般公開するX用AppleScriptです。デジカメを繋いだとき、最初はイメージキャプチャを使っていましたが、iPhotoが公開されてからはiPhotoを指定していました。しかし、iPhotoだと一括でしか写真をダウンロード出来ないんですね(私のCoolPix3100DC280Zoomだけ?)。私のように横着な人間はデジカメの中に前のデータを入れっぱなしにして次の写真を取ったりしてしまうので、一部をダウンロードする機能は欲しい。でもiPhotoも使いたい、とわがまま炸裂です(笑)。で、いちいち/Applications/を開くのも億劫なので、デジカメを繋いだときにどっちか選べればいいじゃん♪と軽い気持ちで作ったのがこれです。軽い気持ちで使って下さい。起動するとchoose from listのダイアログが出て、iPhotoを起動、イメージキャプチャを起動、何もしないの三択をするだけのものです。一応二か国語対応したつもりですが、英語システムに切り替えるのも面倒なので試していません。だれか英語システムでFinderに対してsystem attribute "LANG"した結果を教えて下さい。今は"en_US"だと思い込んで:)書いています。三択なのにdisplay dialogで済ませていないのは、選択肢が増えたときに組み込むのが面倒だからです。