正方形セルの表を形成する1次元配列上で、指定セルに隣接する指定データの入っているセルブロックを検出するAppleScriptです。
テストデータは11×11のサイズで作ってみました。本Scriptを作ることが最終目的ではないので、実戦投入はしていませんが、それなりに動いているようです。11セルの対象データを検出するのに、0.002秒ぐらい(10回実行時の平均値)。
本プログラムではセルアドレス=58のセルと隣接する「9」のデータが入っているセルのアドレスをすべて求めています。基準セルの8方向のセルアドレスを計算したうえでデータにアクセスして、「9」が入っているセルを検出。それらをまとめてすべての検出セルの8方向のアドレスを検査し、それ以上検出セル数が増加しない状態までループ処理を続けています。
本プログラムは本番プログラムを作るための習作だったので、ものすごくオーソドックスな組み方をしています。本番のプログラムでは、この「無駄に長い」処理を大幅に簡略化して3分の1ぐらいの長さになりました。
AppleScript名:findBlock2.scptd |
— – Created by: Takaaki Naganoya – Created on: 2020/03/10 — – Copyright © 2020 Piyomaru Software, All Rights Reserved — use AppleScript version "2.4" — Yosemite (10.10) or later use framework "Foundation" use scripting additions property dataWidth : 11 property dataHeight : 11 property dataMax : 121 property testData : {"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "1", "9", "1", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "9", "9", "9", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "9", "9", "9", "9", "1", "1", "1", "1", "1", "1", ¬ "1", "9", "9", "9", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", ¬ "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"} set foundList to {58} set prevFound to 1 repeat set foundList to findAllDirection(foundList) of me set aLen to length of foundList if aLen = prevFound then return foundList else copy aLen to prevFound end if end repeat return foundList –> {58, 69, 68, 70, 80, 79, 81, 82, 91, 90, 92} on findAllDirection(foundList) repeat with sCanCell in foundList set nRes to findN(sCanCell) of me set sRes to findS(sCanCell) of me set eRes to findE(sCanCell) of me set wRes to findW(sCanCell) of me set nwRes to findNW(sCanCell) of me set neRes to findNE(sCanCell) of me set swRes to findSW(sCanCell) of me set seRes to findSE(sCanCell) of me if nRes is not equal to false then set newAddr to contents of (item 2 of nRes) if newAddr is not in foundList then set the end of foundList to newAddr else set nRes to false end if end if if sRes is not equal to false then set newAddr to contents of (item 2 of sRes) if newAddr is not in foundList then set the end of foundList to newAddr else set sRes to false end if end if if eRes is not equal to false then set newAddr to contents of (item 2 of eRes) if newAddr is not in foundList then set the end of foundList to newAddr else set eRes to false end if end if if wRes is not equal to false then set newAddr to contents of (item 2 of wRes) if newAddr is not in foundList then set the end of foundList to newAddr else set wRes to false end if end if if nwRes is not equal to false then set newAddr to contents of (item 2 of nwRes) if newAddr is not in foundList then set the end of foundList to newAddr else set nwRes to false end if end if if neRes is not equal to false then set newAddr to contents of (item 2 of neRes) if newAddr is not in foundList then set the end of foundList to newAddr else set neRes to false end if end if if swRes is not equal to false then set newAddr to contents of (item 2 of swRes) if newAddr is not in foundList then set the end of foundList to newAddr else set swRes to false end if end if if seRes is not equal to false then set newAddr to contents of (item 2 of seRes) if newAddr is not in foundList then set the end of foundList to newAddr else set seRes to false end if end if end repeat return foundList end findAllDirection ————————————— on findS(anAddress) copy anAddress to tmpAddr set tmpAddr to incLine(tmpAddr) of me if tmpAddr = false then return false set tmpCon to contents of item tmpAddr of testData if tmpCon = "1" then return false return {true, tmpAddr} end findS on findN(anAddress) copy anAddress to tmpAddr set tmpAddr to decLine(tmpAddr) of me if tmpAddr = false then return false set tmpCon to contents of item tmpAddr of testData if tmpCon = "1" then return false return {true, tmpAddr} end findN on findE(anAddress) copy anAddress to tmpAddr set tmpAddr to incCell(tmpAddr) of me if tmpAddr = false then return false set tmpCon to contents of item tmpAddr of testData if tmpCon = "1" then return false return {true, tmpAddr} end findE on findW(anAddress) copy anAddress to tmpAddr set tmpAddr to decCell(tmpAddr) of me if tmpAddr = false then return false set tmpCon to contents of item tmpAddr of testData if tmpCon = "1" then return false return {true, tmpAddr} end findW on findNW(anAddress) copy anAddress to tmpAddr set tmpAddr to decLine(tmpAddr) of me if tmpAddr = false then return false set tmpAddr to decCell(tmpAddr) of me if tmpAddr = false then return false set tmpCon to contents of item tmpAddr of testData if tmpCon = "1" then return false return {true, tmpAddr} end findNW on findNE(anAddress) copy anAddress to tmpAddr set tmpAddr to decLine(tmpAddr) of me if tmpAddr = false then return false set tmpAddr to incCell(tmpAddr) of me if tmpAddr = false then return false set tmpCon to contents of item tmpAddr of testData if tmpCon = "1" then return false return {true, tmpAddr} end findNE on findSW(anAddress) copy anAddress to tmpAddr set tmpAddr to incLine(tmpAddr) of me if tmpAddr = false then return false set tmpAddr to decCell(tmpAddr) of me if tmpAddr = false then return false set tmpCon to contents of item tmpAddr of testData if tmpCon = "1" then return false return {true, tmpAddr} end findSW on findSE(anAddress) copy anAddress to tmpAddr set tmpAddr to incLine(tmpAddr) of me if tmpAddr = false then return false set tmpAddr to incCell(tmpAddr) of me if tmpAddr = false then return false set tmpCon to contents of item tmpAddr of testData if tmpCon = "1" then return false return {true, tmpAddr} end findSE ————————————— on incLine(anAddress) if anAddress + dataWidth > dataMax then set anAddress to false else set anAddress to anAddress + dataWidth end if return anAddress end incLine on decLine(anAddress) if anAddress – dataWidth < 1 then set anAddress to false else set anAddress to anAddress – dataWidth end if return anAddress end decLine on incCell(anAddress) set tmpMax to anAddress div dataWidth if ((anAddress + 1) div dataWidth) is not equal to tmpMax then set anAddress to false else if anAddress + 1 < dataMax then set anAddress to anAddress + 1 else return false end if end if return anAddress end incCell on decCell(anAddress) set tmpMax to anAddress div dataWidth set tmp2Max to (anAddress – 1) div dataWidth if anAddress – 1 > 0 then if (tmp2Max is equal to tmpMax) then set anAddress to anAddress – 1 end if else set anAddress to false end if return anAddress end decCell |
More from my site
(Visited 62 times, 1 visits today)