--- /dev/null
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#define MAXLINE 1000
+#define MAXBAGS 1000
+
+struct bag {
+ char *color;
+ struct baglist *above;
+};
+
+struct baglist {
+ struct bag *bag,
+ struct baglist *next;
+};
+
+char *bagnames[MAXBAGS];
+
+int main()
+{
+ char buffer[MAXLINE];
+
+ while (fgets(buffer, MAXLINE, stdin)) {
+ char *p;
+ p = strstr(buffer, " bag");
+ *p = 0;
+ printf("bag: %s\n", buffer);
+ p = strstr(p+1, " contain ") + strlen(" contain");
+
+ while (p) {
+ if (*p == ' ')
+ p++;
+ if (*p == 'n') {
+ printf("\tno other\n");
+ break;
+ }
+ int num = atoi(p);
+ char *bag = p = strchr(p, ' ') + 1;
+ p = strstr(p, " bag");
+ *p = 0;
+ p += strlen(" bag");
+ printf("\t%d, %s.\n", num, bag);
+ p = strchr(p, ' ');
+ }
+ }
+}
use strict;
-my $rounds;
-($rounds, $_) = @ARGV;
-
-my @cups_nums = split //;
-my @cups_pos;
-my $i;
-for (@cups_nums) {
- $cups_pos[$_] = $i++;
-}
-
-my $max = 1_000_000;
-
-my ($prev, @cups, $one);
-for (@cups_nums, 10 .. $max) {
- my $cup = {
- num => $_,
- prev_num => $prev,
- next => undef,
- };
- push @cups, $cup;
- $one = $cup if $cup->{num} == 1;
+my ($rounds, $max, $cups) = @ARGV;
+
+my @next_cup = (1 .. $max);
+my $i = 0;
+my $prev = @next_cup - 1;
+my $cur;
+for my $cup (split //, $cups) {
+ $cup--; # count cup numbers from 0, not from 1
+ $next_cup[$prev] = $cup;
$prev = $cup;
+ $cur //= $cup; # The first one
}
-
-$prev = $cups[-1];
-for my $cup (@cups) {
- $cup->{prev_num} = $cups[$cups_pos[$cup->{num}-1]]
- if $cup->{num} > 1 && $cup->{num} <= 10;
- $cup->{prev_num} = $cups[-1]
- if $cup->{num} == 1;
- $prev->{next} = $cup;
- $prev = $cup;
-}
-
-# for my $cup (@cups) {
-# print $cup->{num}, ": >", $cup->{next}->{num}, " <", $cup->{prev_num}->{num}, "\n";
-# }
-
-my $cur = $cups[0];
+# $next_cup[6] = 2;
while ($rounds--) {
my @pickup;
- my $cup = $cur->{next};
- my $dest = $cur->{prev_num};
- my %num_seen;
+ my $cup = $next_cup[$cur];
+ my %num_seen = ($cur => 1);
# print "pickup: ";
for (1..3) {
push @pickup, $cup;
- $num_seen{ $cup->{num} } = 1;
- # print $cup->{num}, ' ';
- $cup = $cup->{next};
+ $num_seen{ $cup } = 1;
+ # print $cup + 1, ' ';
+ $cup = $next_cup[$cup];
}
- $dest = $dest->{prev_num} while $num_seen{$dest->{num}};
- # print " dest: ", $dest->{num}, "\n";
- $cur->{next} = $cup;
- my $end = $dest->{next};
- $dest->{next} = $pickup[0];
- $pickup[-1]->{next} = $end;
-
- $cur = $cur->{next};
- # $end = $cur;
+ my $dest = $cur;
+ while ($num_seen{$dest}) {
+ $dest--;
+ $dest = $max-1 if $dest < 0;
+ }
+ # print " dest: ", $dest + 1, "\n";
+ $next_cup[$cur] = $cup;
+ my $end = $next_cup[$dest];
+ $next_cup[$dest] = $pickup[0];
+ $next_cup[$pickup[-1]] = $end;
+
+ $cur = $next_cup[$cur];
+ $end = $cur;
# do {
- # print $end->{num}, ',';
- # $end = $end->{next};
- # } while ($end->{num} != $cur->{num});
+ # print $end+1, ',';
+ # $end = $next_cup[$end];
+ # } while ($end != $cur);
# print "\n";
print "round $rounds\n" if $rounds % 100_000 == 0;
}
-print "one -> ", $one->{next}->{num}, '*', $one->{next}->{next}->{num},
- "=", $one->{next}->{num} * $one->{next}->{next}->{num}, "\n";
+print "one -> ", $next_cup[0] + 1, '*', $next_cup[$next_cup[0]] + 1,
+ "=", ($next_cup[0]+1) * ($next_cup[$next_cup[0]]+1), "\n";