Just in time processing on a character stream
Given a stream of characters, presumably (simulated) from a keyboard, that contain the separators "formfeed", "linefeed", "tab" and "space" characters. Print out the ith character of the ith tab-field of the ith line of the ith page to reveal a secret password.
Stop processing immediately upon encountering a "!" found uniquely in this i,i,i,i position (least the system self destruct). The "!" may be found/permitted else where however, in which case it should be ignored.
Ideally this can be generalise as follows:
- The separators (formfeed, linefeed, tab, space) provided from a user supplied array and can include additional/alternative separators, e.g. (formfeed, linefeed, ".", "," ," ",...).
- These selection criterial is generalised ith,ith,ith,ith to a boolean function of f(page,line,field,word,...) or f(ith,jth,kth,lth,mth,etc...)
Provide a reasonably interesting message to be decoded, e.g. Silence-Dogood. Your choice.
This task was inspired by the movie "National Treasure" with refers to a "book cipher".
Tcl
<lang tcl>package require Tcl 8.6
oo::class create JustInTimeStreamExtract {
variable map counter counters last constructor {{pageSeparator "\f"} {lineSeparator "\n"} {fieldSeparator "\t"}} {
dict set map $pageSeparator NextPage dict set map $lineSeparator NextLine dict set map $fieldSeparator NextField set counter 1 array set counters {page 0 line 0 field 0 char 0} set last ""
}
method emit {char} {
puts -nonewline $char set last $char
} method finished {} {
if {$last ne "\n"} { puts "" }
}
method stream {{channel stdin} {length 1}} {
try { while 1 { set str [read $channel $length] if {[eof $channel]} break foreach c [split $str ""] { if {[dict exists $map $c]} { my [dict get $map $c] } else { my NextChar $c } } } } trap STOP {} { # Do nothing } my finished
}
method NextPage {} {
incr counters(page) array set counters {line 0 field 0 char 0}
} method NextLine {} {
incr counters(line) array set counters {field 0 char 0}
} method NextField {} {
incr counters(field) set counters(char) 0
} method NextChar {char} {
incr counters(char) if {[my PrintThisOne?]} { if {$char eq "!"} { throw STOP "stop character found" } incr counter my emit $char array set counters {page 0 line 0 field 0 char 0} }
}
method PrintThisOne? {} {
tcl::mathop::== $counter $counters(page) $counters(line) $counters(field) $counters(char)
}
}</lang> Demonstration of use: <lang tcl>[JustInTimeStreamExtract new] stream [open "sample.txt"]</lang>