49 lines
1.5 KiB
Text
49 lines
1.5 KiB
Text
link strings # for csort and deletec
|
|
|
|
procedure main(arglist)
|
|
ECsolve(S1 := getStates()) # original state names puzzle
|
|
ECsolve(S2 := getStates2()) # modified fictious names puzzle
|
|
GNsolve(S1)
|
|
GNsolve(S2)
|
|
end
|
|
|
|
procedure ECsolve(S) # Solve challenge using equivalence classes
|
|
local T,x,y,z,i,t,s,l,m
|
|
st := &time # mark runtime
|
|
/S := getStates() # default
|
|
every insert(states := set(),deletec(map(!S),' \t')) # ignore case & space
|
|
|
|
# Build a table containing sets of state name pairs
|
|
# keyed off of canonical form of the pair
|
|
# Use csort(s) rather than cset(s) to preserve the numbers of each letter
|
|
# Since we care not of X&Y .vs. Y&X keep only X&Y
|
|
|
|
T := table()
|
|
every (x := !states ) & ( y := !states ) do
|
|
if z := csort(x || (x << y)) then {
|
|
/T[z] := []
|
|
put(T[z],set(x,y))
|
|
}
|
|
|
|
# For each unique key (canonical pair) find intersection of all pairs
|
|
# Output is <current key matched> <key> <pairs>
|
|
|
|
i := m := 0 # keys (i) and pairs (m) matched
|
|
every z := key(T) do {
|
|
s := &null
|
|
every l := !T[z] do {
|
|
/s := l
|
|
s **:= l
|
|
}
|
|
if *s = 0 then {
|
|
i +:= 1
|
|
m +:= *T[z]
|
|
every x := !T[z] do {
|
|
#writes(i," ",z) # uncomment for equiv class and match count
|
|
every writes(!x," ")
|
|
write()
|
|
}
|
|
}
|
|
}
|
|
write("... runtime ",(&time - st)/1000.,"\n",m," matches found.")
|
|
end
|