Code
--[[
Structure Sections by Crashguard303
Finds sections of cohesive secondary structures in a puzzle.
Improved table-handling.
Creates a flag-table marking found letters of the secondary structure
and a 3-dimensional section table with dimensions:
structure letter,
section number (with this letter),
start & end segment (with this section number and letter).
Example:
structure_section.H[2].first: first segment of 2nd helix section (if existing)
structure_section.H[2].last: last segment of 2nd helix section (if existing)
See script text for details.
]]--
function find_structure_sections()
-- Phase 1:
-- by using table found, store in each line of this table:
-- another secondary structure letter (.s) (must be different to last in line),
-- first (.first)
-- and last (.last) segment with structure (.s)
local found={} -- initialize table
found=found_new(found,structure.GetSecondaryStructure(1),1)
-- the very first segment is also a new letter
-- expand found-list by 1, at new found-list position: write new letter and current segment number as first-segment-information
local i
for i=2,structure.GetCount() do -- by variable i, cycle through all segments of the puzzle
local s=structure.GetSecondaryStructure(i) -- and fetch secondary structure letter at segment i
if s~=found[#found].s -- if actual letter is unequal to actual one in our found-list
then found[#found].last=i-1
-- actual section has ended one segment before,
-- so at current found-list position: write previous segment number as last-segment-information
found=found_new(found,s,i)
-- expand found-list by 1, at new found-list position: write new letter and current segment number as first-segment-information
end -- if
end -- i
found[#found].last=structure.GetCount()
-- the very last segment closes the found-list with a last-segment-information
-- at current found-list position: write last segment number as last-segment-information
-- uncomment this to show found table contents
-- for i=1,#found do
-- print(found[i].s,found[i].first,found[i].last)
-- end -- i
-- print()
-- Phase 2:
-- by using table structure_section, fetch information from table found
-- store structure sections sorted by letter and position
local structure_created_flag={} -- initialize flag table, so we can see if we have already created a table for this letter
local structure_section={} -- initialize basic table for letters
local i
for i=1,#found do -- by variable i, cycle trough all lines in our found-list which have letters, first and last segment information
s=found[i].s -- fetch s = letter at current found-list line
if structure_created_flag[s]==nil -- if s is not flagged as created
then structure_section[#structure_section+1]=s -- expand basic table and append s as found letter
structure_section[s]={} -- in s, create a subtable for all sections which have s
structure_created_flag[s]=true -- flag s as created
end -- if
structure_section[s][#structure_section[s]+1]={} -- expand subtable at s
structure_section[s][#structure_section[s]].first=found[i].first -- at new position, write first
structure_section[s][#structure_section[s]].last=found[i].last -- and last segment position of section
-- uncomment this to watch table conversion process
-- print(s,#structure_section[s],structure_section[s][#structure_section[s]].first,structure_section[s][#structure_section[s]].last)
end -- i
return structure_created_flag,structure_section
-- return flag table marking found letters with true and
-- return section table created in phase 2
-- old table found is obsolete and won't be returned
end -- function
function found_new(found,s,i)
-- expand found-list table
local found=found -- copy current found-table (I'm not sure if it necessary, but to me it's the safe way)
found[#found+1]={} -- expand found-list by 1
found[#found].s=s -- at new found-list position: write new letter
found[#found].first=i -- and current segment number as first-segment-information
return found -- return expanded table, which is now 1 line more
end -- function
structure_found_flag,structure_section=find_structure_sections()
-- fetch structure found flag table marking found letters with true and section table
print("Found structures:")
local i
for i=1,#structure_section do -- by variable i, cycle through all letters which have been found
local s=structure_section[i] -- fetch letter s at position i
print()
print(s..": "..#structure_section[s].." times") -- show how many sections with s are there
for j = 1,#structure_section[s] do -- by variable j, cycle through all sections with letter s
print(structure_section[s][j].first.." to "..structure_section[s][j].last)
-- show first and last segment of each section j with letter s
end -- j
end -- i
--[[Table usage (examples):
structure_found_flag: true if a structure (given by letter) was found
nil if it was not found
structure_found_flag["E"] or
structure_found_flag.E: true if sheets were found
structure_found_flag["H"] or
structure_found_flag.H: true if helices were found
structure_found_flag["L"] or
structure_found_flag.L: true if loops were found
#structure_section: number of DIFFERENT structures which have been found.
if there are just loops, it will be 1,
if there are loops and sheets, it will be 2
if there are loops, sheets and helices, it will be 3 etc.
structure_section[1]: letter of first structure which has been found
structure_section[2]: letter of second structure which has been found
structure_section[n]: letter of nth structure which has been found (n shouldn't be bigger than #structure_section)
For example, if there were loops found at first and then helices,
structure_section[1] will be "L",
structure_section[2] will be "H",
#structure_section["E"] or
#structure_section.E: number of sheet sections found (if existing)
#structure_section["H"] or
#structure_section.H: number of helix sections found (if existing)
#structure_section["L"] or
#structure_section.L: number of loop sections found (if existing)
structure_section["E"][1]["first"] or
structure_section.E[1].first: first segment of 1st sheet section (if existing)
structure_section.E[1].last: last segment of 1st sheet section (if existing)
structure_section.H[2].first: first segment of 2nd helix section (if existing)
structure_section.H[2].last: last segment of 2nd helix section (if existing)
structure_section.L[3].first: first segment of 3rd loop section (if existing)
structure_section.L[3].last: last segment of 3rd loop section (if existing)
]]--