117 行
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Tcl
		
	
	
		
			実行ファイル
		
	
	
	
	
			
		
		
	
	
			117 行
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Tcl
		
	
	
		
			実行ファイル
		
	
	
	
	
| #!/usr/bin/env tclsh
 | |
| source ../prelude.tcl
 | |
| 
 | |
| proc read-input input {
 | |
|     global next
 | |
|     global type
 | |
|     global flip
 | |
|     global conj
 | |
|     while {[gets $input line] >= 0} {
 | |
|         # oops
 | |
|         set line [replace $line ">" > "&" &]
 | |
|         #puts $line
 | |
|         must_regexp {^([%&]?)([a-z]+) -> (.*)$} $line _ sigil name to
 | |
|         set next($name) [replace $to "," ""]
 | |
|         if {$sigil eq ""} {
 | |
|             set type($name) ""
 | |
|         } elseif {$sigil eq "%"} {
 | |
|             set type($name) "flip"
 | |
|             set flip($name) 0
 | |
|         } elseif {$sigil eq "&"} {
 | |
|             set type($name) "conj"
 | |
|             set conj($name) [dict create]
 | |
|         } else {
 | |
|             error "unknown sigil $sigil"
 | |
|         }
 | |
|     }
 | |
|     foreach n [array names type] {
 | |
|         foreach to $next($n) {
 | |
|             if {![info exists type($to)]} {
 | |
|                 set type($to) ""
 | |
|             }
 | |
|             if {$type($to) eq "conj"} {
 | |
|                 dict set conj($to) $n 0
 | |
|             }
 | |
|         }
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 | |
| proc pulse {init {debug 0}} {
 | |
|     global next
 | |
|     global type
 | |
|     global flip
 | |
|     global conj
 | |
|     global count
 | |
| 
 | |
|     set n $init
 | |
|     set pulses {}
 | |
| 
 | |
|     #puts [array get next]
 | |
| 
 | |
|     incr count(0) ;# button
 | |
|     foreach to $next($init) {
 | |
|         #incr count(0)
 | |
|         lappend pulses $init $to 0
 | |
|     }
 | |
| 
 | |
|     while {[llen $pulses]} {
 | |
|         if {$debug} {
 | |
|             puts "#[llen $pulses] : $pulses"
 | |
|         }
 | |
|         set copy $pulses
 | |
|         set pulses {}
 | |
|         foreach {from n value} $copy {
 | |
|             incr count($value)
 | |
|             switch $type($n) {
 | |
|                 flip {
 | |
|                     if {$value == 0} {
 | |
|                         set flip($n) [expr {!$flip($n)}]
 | |
|                         foreach to $next($n) {
 | |
|                             lappend pulses $n $to $flip($n)
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|                 conj {
 | |
|                     dict set conj($n) $from $value
 | |
|                     set all 1
 | |
|                     foreach v [dict values $conj($n)] {
 | |
|                         if {!$v} {
 | |
|                             set all 0
 | |
|                             break
 | |
|                         }
 | |
|                     }
 | |
|                     set send [expr {!$all}]
 | |
|                     foreach to $next($n) {
 | |
|                         lappend pulses $n $to $send
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
|     }
 | |
|     #puts $count(0)
 | |
|     #puts $count(1)
 | |
| }
 | |
| 
 | |
| proc solve input {
 | |
|     read-input $input
 | |
| 
 | |
|     global count
 | |
|     #puts [array get next]
 | |
|     #array set count {0 0 1 0}
 | |
|     set count(0) 0
 | |
|     set count(1) 0
 | |
| 
 | |
|     global solved
 | |
|     set solved 0
 | |
|     for {set i 1} {$i <= 1000} {incr i} {
 | |
|         pulse broadcaster
 | |
|     }
 | |
| 
 | |
|     puts "$count(0)"
 | |
|     puts $count(1)
 | |
|     puts [expr {$count(0) * $count(1)}]
 | |
| }
 | |
| 
 | |
| solve stdin
 |