#!/usr/bin/env tclsh9.0 namespace import ::tcl::mathop::+ namespace import ::tcl::mathop::- # Don't need to store the grid. Just a list of antenna locations, and # the size of the map (so we know if an antinode is out of bounds). # ant will be a dictionary mapping antenna labels to coordinate tuples. proc input {} { global rows cols ant set ant [dict create] set rows 0 while {[gets stdin line] >= 0} { if {$line eq ""} continue set cols [string length $line] set c 0 foreach char [split $line ""] { if {$char ne "."} { dict lappend ant $char [list $rows $c] } incr c } incr rows } } proc count {} { global rows cols ant # A location may have multiple antinodes, so we have to track them. set anti [dict create] # Iterate over antenna labels. dict for {label list} $ant { if {[llength $list] < 2} continue # Iterate over antenna pairs. for {set i 0} {$i < [llength $list] - 1} {incr i} { for {set j [+ $i 1]} {$j < [llength $list]} {incr j} { lassign [lindex $list $i] ir ic lassign [lindex $list $j] jr jc set dr [- $jr $ir] set dc [- $jc $ic] # Call our antinodes a and b, so coords ar, ac, br, bc. set ar [- $ir $dr] set br [+ $jr $dr] set ac [- $ic $dc] set bc [+ $jc $dc] # Track the ones that aren't out of bounds. if {$ar >= 0 && $ar < $rows && $ac >= 0 && $ac < $cols} { dict set anti [list $ar $ac] 1 } if {$br >= 0 && $br < $rows && $bc >= 0 && $bc < $cols} { dict set anti [list $br $bc] 1 } } } } puts [dict size $anti] } input count # Grid notes: # ...... ....... # ..xx.. ..x.... # ...... ....x.. # ....... # ..... # ..x.. ....... # ..... .....x. # ..x.. ....x.. # ..... ....... # Delta row (dr) is always non-negative because of how # we scanned the grid. # Delta col (dc) can be negative in the bottom right case, but it turns # out this doesn't matter. ac is ic + 1 which is ic - dc, so it's # calculated the same way as the other three cases.