Skip to content

Commit 2520475

Browse files
committed
feat(2020-21/angch): Working code of untrimmed failed code
1 parent 4419a2c commit 2520475

1 file changed

Lines changed: 315 additions & 0 deletions

File tree

2020-21/angch/main.go

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"log"
7+
"os"
8+
"sort"
9+
"strings"
10+
"time"
11+
12+
"github.com/gnboorse/centipede"
13+
)
14+
15+
type Rule struct {
16+
Ingredient []string
17+
Allergen []string
18+
}
19+
20+
func intersect(a, b []string) []string {
21+
log.Println("intersect", a, b)
22+
a_ := make(map[string]bool)
23+
c := make([]string, 0)
24+
for _, v := range a {
25+
a_[v] = true
26+
}
27+
for _, v := range b {
28+
if a_[v] {
29+
c = append(c, v)
30+
}
31+
}
32+
sort.Strings(c)
33+
return c
34+
}
35+
36+
func inslice(a string, b []string) bool {
37+
for _, v := range b {
38+
if a == v {
39+
return true
40+
}
41+
}
42+
return false
43+
}
44+
45+
func do(fileName string) (ret1 int, ret2 int) {
46+
file, err := os.Open(fileName)
47+
if err != nil {
48+
log.Fatal(err)
49+
}
50+
defer file.Close()
51+
scanner := bufio.NewScanner(file)
52+
53+
possibleAllergen := make(map[string]map[string]bool)
54+
allergenInIngredient := make(map[string]map[string]bool)
55+
appearances := make(map[string]int)
56+
rules := make([]Rule, 0)
57+
58+
allergen := make([]string, 0)
59+
ingredient := make([]string, 0)
60+
allergenId := make(map[string]int)
61+
ingredientId := make(map[string]int)
62+
63+
for scanner.Scan() {
64+
l := scanner.Text()
65+
_ = l
66+
67+
if l == "" {
68+
break
69+
}
70+
rule := strings.Split(l, "(")
71+
contains := strings.Split(rule[1], ",")
72+
for k, v := range contains {
73+
contains[k] = strings.TrimPrefix(v, "contains ")
74+
contains[k] = strings.TrimSuffix(contains[k], ")")
75+
contains[k] = strings.TrimSpace(contains[k])
76+
}
77+
78+
ingredients := strings.Split(strings.TrimSpace(rule[0]), " ")
79+
80+
log.Println(ingredients, contains)
81+
82+
for _, v := range ingredients {
83+
e, ok := possibleAllergen[v]
84+
if !ok {
85+
possibleAllergen[v] = make(map[string]bool)
86+
e = possibleAllergen[v]
87+
88+
if _, ok = ingredientId[v]; !ok {
89+
ingredientId[v] = len(ingredient)
90+
ingredient = append(ingredient, v)
91+
}
92+
}
93+
94+
for _, v2 := range contains {
95+
e[v2] = true
96+
97+
f, ok := allergenInIngredient[v2]
98+
if !ok {
99+
allergenInIngredient[v2] = make(map[string]bool)
100+
f = allergenInIngredient[v2]
101+
}
102+
f[v] = true
103+
104+
if _, ok = allergenId[v2]; !ok {
105+
allergenId[v2] = len(allergen)
106+
allergen = append(allergen, v2)
107+
}
108+
}
109+
110+
// log.Println("incr", v)
111+
appearances[v]++
112+
}
113+
myrule := Rule{
114+
Ingredient: ingredients,
115+
Allergen: contains,
116+
}
117+
rules = append(rules, myrule)
118+
}
119+
// log.Println("possibleAllergen", possibleAllergen)
120+
// log.Println("allergenInIngredient", allergenInIngredient)
121+
// log.Println(rules)
122+
// log.Println("appearances", appearances)
123+
124+
{
125+
allergen := make(map[string][]string)
126+
counts := make(map[string]int)
127+
for k, v := range rules {
128+
log.Println(k, v)
129+
for _, all := range v.Allergen {
130+
if _, ok := allergen[all]; !ok {
131+
allergen[all] = make([]string, len(v.Ingredient))
132+
copy(allergen[all], v.Ingredient)
133+
} else {
134+
allergen[all] = intersect(allergen[all], v.Ingredient)
135+
}
136+
}
137+
for _, v := range v.Ingredient {
138+
counts[v]++
139+
}
140+
}
141+
142+
ret1 = 0
143+
a:
144+
for k, v := range counts {
145+
for _, v2 := range allergen {
146+
if inslice(k, v2) {
147+
continue a
148+
}
149+
}
150+
ret1 += v
151+
}
152+
log.Println("out", allergen, ret1)
153+
confirmed := make(map[string]string)
154+
b:
155+
for k, v := range allergen {
156+
if len(v) == 1 {
157+
confirmed[k] = v[0]
158+
delete(allergen, k)
159+
160+
for k2, v2 := range allergen {
161+
for k3, v3 := range v2 {
162+
if v3 == v[0] {
163+
// log.Println("xfound", v3, k3)
164+
allergen[k2] = append(v2[:k3], v2[k3+1:]...)
165+
break
166+
}
167+
}
168+
}
169+
// log.Println("removed", v[0], "become", allergen)
170+
goto b
171+
}
172+
}
173+
174+
keys := make([]string, 0)
175+
for k, _ := range confirmed {
176+
keys = append(keys, k)
177+
}
178+
sort.Strings(keys)
179+
outdanger := make([]string, 0)
180+
for _, v := range keys {
181+
outdanger = append(outdanger, confirmed[v])
182+
}
183+
log.Println("out2", confirmed, strings.Join(outdanger, ","))
184+
}
185+
186+
if false {
187+
doesnotContain := make(map[string]map[string]bool)
188+
for rulen, rule := range rules {
189+
al := make(map[string]bool)
190+
notal := make([]string, 0)
191+
for _, al2 := range rule.Allergen {
192+
al[al2] = true
193+
}
194+
for al2 := range allergenInIngredient {
195+
if !al[al2] {
196+
notal = append(notal, al2)
197+
}
198+
}
199+
200+
for _, ingredient := range rule.Ingredient {
201+
log.Println("Rule #", rulen+1, ingredient, "does not contain", notal)
202+
203+
c, ok := doesnotContain[ingredient]
204+
if !ok {
205+
doesnotContain[ingredient] = make(map[string]bool)
206+
c = doesnotContain[ingredient]
207+
}
208+
for _, al2 := range notal {
209+
c[al2] = true
210+
}
211+
}
212+
}
213+
log.Println(doesnotContain)
214+
}
215+
log.Println("allergenid", allergenId)
216+
217+
if false {
218+
// Ah fuggit.
219+
vars := make(centipede.Variables, 0)
220+
for i := 0; i < len(ingredient); i++ {
221+
varName := centipede.VariableName(ingredient[i])
222+
cvar := centipede.NewVariable(varName, centipede.IntRange(1, len(allergen)+1))
223+
vars = append(vars, cvar)
224+
}
225+
226+
constraints := make([]centipede.Constraint, 0)
227+
allergenIds := make([][]int, 0)
228+
for ruleN, rule := range rules {
229+
varnames := make([]centipede.VariableName, 0)
230+
vv := make(map[string]bool)
231+
for _, id := range rule.Ingredient {
232+
varnames = append(varnames, centipede.VariableName(id))
233+
vv[id] = true
234+
}
235+
236+
allergenIds = append(allergenIds, make([]int, 0))
237+
for _, id := range rule.Allergen {
238+
allergenIds[ruleN] = append(allergenIds[ruleN], allergenId[id])
239+
}
240+
241+
ConstraintFunction := foo(ruleN, allergenIds, vv)
242+
log.Println("rule c added", ruleN, allergenIds, varnames)
243+
244+
constraints = append(constraints, centipede.Constraint{Vars: varnames, ConstraintFunction: ConstraintFunction})
245+
}
246+
log.Println(vars, constraints)
247+
//constraints = append(constraints, centipede.Constraint{Vars: varnames, ConstraintFunction: ConstraintFunction})
248+
249+
solver := centipede.NewBackTrackingCSPSolver(vars, constraints)
250+
begin := time.Now()
251+
success := solver.Solve() // run the solution
252+
elapsed := time.Since(begin)
253+
if success {
254+
for _, variable := range solver.State.Vars {
255+
fmt.Printf("Variable %v = %v\n", variable.Name, variable.Value)
256+
}
257+
} else {
258+
log.Println("not found")
259+
}
260+
log.Println(elapsed)
261+
262+
// centipede.NewVariable("A", centipede.IntRange(1, 10)),
263+
// centipede.NewVariable("B", centipede.IntRange(1, 10)),
264+
// centipede.NewVariable("C", centipede.IntRange(1, 10)),
265+
// centipede.NewVariable("D", centipede.IntRange(1, 10)),
266+
// centipede.NewVariable("E", centipede.IntRangeStep(0, 20, 2)), // even numbers < 20
267+
// }
268+
}
269+
// count := 0
270+
// for k, v := range doesnotContain {
271+
// if len(v) == len(allergenInIngredient) {
272+
// log.Println(k, "is ok", appearances[k])
273+
// count += appearances[k]
274+
// }
275+
// }
276+
// ret1 = count
277+
278+
return ret1, ret2
279+
}
280+
281+
func foo(n int, allergenIds [][]int, vv map[string]bool) func(variables *centipede.Variables) bool {
282+
return func(variables *centipede.Variables) bool {
283+
found := 0
284+
nn := make([]string, 0)
285+
for _, v := range *variables {
286+
nn = append(nn, string(v.Name))
287+
}
288+
log.Println("Rule ", n, nn)
289+
290+
for _, id := range allergenIds[n] {
291+
for _, v := range *variables {
292+
if !vv[string(v.Name)] {
293+
continue
294+
}
295+
if !v.Empty {
296+
log.Println("xx rule", n, v.Name, v.Value, id+1)
297+
i, ok := v.Value.(int)
298+
if ok && i == id+1 {
299+
found++
300+
// log.Println("found")
301+
break
302+
}
303+
}
304+
}
305+
}
306+
log.Println("found", found, len(allergenIds[n]), found == len(allergenIds[n]))
307+
// return found > 0
308+
return found == len(allergenIds[n])
309+
}
310+
}
311+
312+
func main() {
313+
// log.Println(do("test.txt"))
314+
log.Println(do("input.txt"))
315+
}

0 commit comments

Comments
 (0)