--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+
+my %allergens;
+my %ingredients;
+my %in_count;
+
+while (<>) {
+ chomp;
+ my ($ingr, $al) = /\A([^\(]+) \(contains (.*)\)\z/;
+ my %ingr = map { $_ => 1 } split /\s+/, $ingr;
+ my @al = split /, /, $al;
+ for my $al (@al) {
+ if (defined $allergens{$al}) {
+ for my $in1 (keys %{ $allergens{$al} }) {
+ if (! $ingr{$in1}) {
+ delete $allergens{$al}->{$in1};
+ }
+ }
+ } else {
+ $allergens{$al} = { %ingr };
+ }
+ }
+ for my $in (keys %ingr) {
+ $ingredients{$in} = {};
+ $in_count{$in}++;
+ }
+}
+
+for my $al (keys %allergens) {
+ for my $in (keys %{ $allergens{$al} }) {
+ print "$in can be $al.\n";
+ $ingredients{$in}->{$al} = 1;
+ }
+}
+
+my $sum = 0;
+for my $in (keys %ingredients) {
+ if (keys %{ $ingredients{$in} } == 0) {
+ # print "$in can't contain allergen\n";
+ $sum += $in_count{$in};
+ }
+}
+
+print "Sum=$sum\n";
--- /dev/null
+#!/usr/bin/perl -w
+
+use strict;
+
+my %allergens;
+my %is_al;
+
+while (<>) {
+ chomp;
+ my ($ingr, $al) = /\A([^\(]+) \(contains (.*)\)\z/;
+ my %ingr = map { $_ => 1 } split /\s+/, $ingr;
+ my @al = split /, /, $al;
+ for my $al (@al) {
+ if (defined $allergens{$al}) {
+ for my $in1 (keys %{ $allergens{$al} }) {
+ if (! $ingr{$in1}) {
+ delete $allergens{$al}->{$in1};
+ }
+ }
+ } else {
+ $allergens{$al} = { %ingr };
+ }
+ }
+}
+
+AGAIN:
+for my $al (keys %allergens) {
+ if (keys %{ $allergens{$al} } == 1) {
+ my $in1;
+ for my $in (keys %{ $allergens{$al} }) {
+ $is_al{$in} = $al;
+ $in1 = $in;
+ }
+ delete $allergens{$al};
+ for my $al1 (keys %allergens) {
+ delete $allergens{$al1}->{$in1};
+ }
+ goto AGAIN;
+ }
+}
+
+print join(',', sort { $is_al{$a} cmp $is_al{$b} } keys %is_al), "\n";