Add subs and grph
This commit is contained in:
parent
b340f05ef4
commit
49127ae4ef
7 changed files with 174 additions and 1 deletions
84
08_grph/grph.nim
Normal file
84
08_grph/grph.nim
Normal file
|
@ -0,0 +1,84 @@
|
|||
import os
|
||||
import std/streams
|
||||
# import re
|
||||
import nre
|
||||
import std/tables
|
||||
|
||||
const k = 3
|
||||
|
||||
# let fileName = paramStr(1)
|
||||
# var dna = readFile(fileName)
|
||||
|
||||
type
|
||||
Node* = tuple[name: string, dna: string]
|
||||
AdjacencyList = seq[tuple[v: Node, w: Node]]
|
||||
AffixTable* = Table[string, seq[Node]]
|
||||
|
||||
var adjList: ref AdjacencyList = seq[tuple[v: Node, w: Node]].new()
|
||||
|
||||
var nodesByPrefix: ref AffixTable = newTable[string, seq[Node]]()
|
||||
var nodesBySuffix: ref AffixTable = newTable[string, seq[Node]]()
|
||||
|
||||
let firstLinePattern = re">(\w+)(?:\s+.+)?"
|
||||
|
||||
proc parseNextNode*(stream: Stream): Node =
|
||||
if atEnd(stream):
|
||||
raise newException(ValueError, "Stream is at end")
|
||||
|
||||
let firstLine = readLine(stream)
|
||||
let match = firstLine.match(firstLinePattern)
|
||||
if match.isNone:
|
||||
raise newException(ValueError, "Invalid line: " & firstLine)
|
||||
|
||||
let name = match.get.captures[0]
|
||||
var dna = ""
|
||||
|
||||
while not atEnd(stream) and peekChar(stream) != '>':
|
||||
dna &= readLine(stream)
|
||||
|
||||
(name, dna)
|
||||
|
||||
proc addNodeToTables*(node: Node, prefixes, suffixes: ref AffixTable) =
|
||||
let prefix = node.dna[0..k-1]
|
||||
let suffix = node.dna[^k..^1]
|
||||
|
||||
if not prefixes.hasKey(prefix):
|
||||
prefixes[prefix] = newSeq[Node]()
|
||||
|
||||
prefixes[prefix].add(node)
|
||||
|
||||
if not suffixes.hasKey(suffix):
|
||||
suffixes[suffix] = newSeq[Node]()
|
||||
|
||||
suffixes[suffix].add(node)
|
||||
|
||||
proc updateAdjacencyList*(node: Node, prefixes, suffixes: ref AffixTable, adjList: ref AdjacencyList) =
|
||||
let prefix = node.dna[0..k-1]
|
||||
let suffix = node.dna[^k..^1]
|
||||
|
||||
if prefixes.hasKey(suffix):
|
||||
for n in items(prefixes[suffix]):
|
||||
if node.name != n.name:
|
||||
adjList[].add((node, n))
|
||||
|
||||
if suffixes.hasKey(prefix):
|
||||
for n in items(suffixes[prefix]):
|
||||
if node.name != n.name:
|
||||
adjList[].add((n, node))
|
||||
|
||||
proc processInputStream(stream: Stream) =
|
||||
while not atEnd(stream):
|
||||
let node = parseNextNode(stream)
|
||||
addNodeToTables(node, nodesByPrefix, nodesBySuffix)
|
||||
updateAdjacencyList(node, nodesByPrefix, nodesBySuffix, adjList)
|
||||
|
||||
|
||||
let fileName = paramStr(1)
|
||||
let fileStream = newFileStream(fileName)
|
||||
if not isNil(fileStream):
|
||||
processInputStream(fileStream)
|
||||
|
||||
for t in items(adjList[]):
|
||||
echo t.v.name & " " & $t.w.name
|
||||
|
||||
fileStream.close()
|
Loading…
Add table
Add a link
Reference in a new issue