Quick actions

cmd+k|ctrl+k

Navigation

Languages

Untitled

Snippet info

Language

Raku

Visibility

unlisted

Author

legacy-anonymous

Created

2018-12-13T15:04:31Z

Updated

2018-12-13T15:04:31Z

class Cart {
        has $.state is rw;
        has $.y is rw;
        has $.x is rw;
        has $.id;
        has $!turn = 0;

        method move-on (@map) {
                given $.state {
                        when '>' { $.x++ }
                        when '<' { $.x-- }
                        when 'v' { $.y++ }
                        when '^' { $.y-- }
                }

                $.state = do given $.state, @map[$.y; $.x] {
                        when '>', '/'  { '^' }
                        when '>', '\\' { 'v' }
                        when '>', '-'  { $.state }
                        when '>', '+'  { ('^', $.state, 'v')[$!turn++ % 3] }

                        when '<', '/'  { 'v' }
                        when '<', '\\' { '^' }
                        when '<', '-'  { $.state }
                        when '<', '+'  { ('v', $.state, '^')[$!turn++ % 3] }

                        when 'v', '/'  { '<' }
                        when 'v', '\\' { '>' }
                        when 'v', '|'  { $.state }
                        when 'v', '+'  { ('>', $.state, '<')[$!turn++ % 3] }

                        when '^', '/'  { '>' }
                        when '^', '\\' { '<' }
                        when '^', '|'  { $.state }
                        when '^', '+'  { ('<', $.state, '>')[$!turn++ % 3] }
                }
        }

        method yx { $.y, $.x }
}

my @map = $*IN.lines.map({ .comb.Array });
my %carts;

my $max-y = @map.elems;
my $max-x = max @map.map(*.elems);

for ^$max-x X ^$max-y -> ($x, $y) {
        my $track = @map[$y; $x];

        given $track {
                when '>' | '<' { @map[$y; $x] = '-' }
                when 'v' | '^' { @map[$y; $x] = '|' }
        }

        if $track ne @map[$y; $x] {
                my $id = %carts.elems;
                %carts{$id} = Cart.new(state => $track, :$x, :$y, :$id)
        }
}

repeat {
        for %carts.values.sort(*.yx) -> $cart {
                next if %carts{$cart.id}:!exists;

                $cart.move-on(@map);

                my %positions = %carts.values.classify(*.yx.Str);
                my @crashes   = %positions.values.grep(*.elems > 1);

                for @crashes -> @crashed-carts {
                        for @crashed-carts -> $crashed-cart {
                                say "crashed: {$crashed-cart.perl}";
                                %carts{$crashed-cart.id}:delete;
                        }
                }
        }
} while %carts.elems > 1;

say "survivor: {%carts{*}».perl}";
INFO