Codingame : Skynet Revolution : Solution PERL

Nouveau concours codingame auquel j’ai participé (d’ailleurs si vous avez d’autre lien de site réalisant des concours ça m’intéresse !)

Voici comment réaliser un 100% en Perl

Première question, assez simple :

#!/usr/bin/perl
select(STDOUT); $| = 1; # DO NOT REMOVE

# @author   : Scorfly
# @mail     : scorfly at gmail dot com

use Data::Dumper;

# My personal constant
use constant false => 0;
use constant true  => 1;

($r) = split(/ /, <STDIN>);
$r =~ s/\n//g;

($g) = split(/ /, <STDIN>);
$g =~ s/\n//g;

($l) = split(/ /, <STDIN>);
$l =~ s/\n//g;

$hasJumped = false;

while (1) {
    ($s) = split(/ /, <STDIN>);
    $s =~ s/\n//g;
    
    ($x) = split(/ /, <STDIN>);
    $x =~ s/\n//g;
    
    if ($hasJumped)
    {
        print "SLOW\n";
    }
    else
    {
        if ($s <= $g)
        {
            print "SPEED\n";
        }
        elsif ($s > $g+1 )
        {
            print "SLOW\n";
        }
        else
        {
            $tmp = $x+$s;
            if ($tmp > $r)
            {
                $hasJumped = true;
                print "JUMP\n";
            }
            else
            {
                print "WAIT\n";
            }
        }
    }
    
    # DEBUG
    print STDERR "$g - goufre \n";
    print STDERR "$r - size before goufre init \n";
    print STDERR "$l - size of plateform \n";
    print STDERR " \n";
    print STDERR "$s - speed \n";
    print STDERR "$x - pos \n";
    print STDERR "----------------";
    
}

Pour la seconde question j’ai du refaire le concours après car je n’ai pas réussi à obtenir le 100% lors de l’épreuve.

#!/usr/bin/perl
select(STDOUT); $| = 1; # DO NOT REMOVE

# @author   : Scorfly
# @mail     : scorfly at gmail dot com
# inspired by : http://www.codingame.com/cg/#!report:304298abe9483e149208d0eb19b780d62b7ae1
#   - Author : NewboO
#   - Infos : PHP 100%

use Data::Dumper;
use Switch 'Perl6';

my $m = <STDIN>; chomp $m;
my $v = <STDIN>; chomp $v;

my %roads;
for (my $i = 0 ; $i < 4; $i++)
{
    $roads->{$i} = <STDIN>; chomp $roads->{$i};
}

# Let's go to infinite
my @solution;

while(1)
{
    my $s = <STDIN>; chomp $s;
    my @motos;
    for(my $i=0; $i<$m; $i++)
    {
        my ($x, $y, $a) = split(/ /, <STDIN>); chomp $a;
        
        if($a)
        {
            push(@motos, [$x, $y]);
        }
    }
    
    @solution = getPath(\@motos, $s, $roads, $v);
    
    MyLogger(\@solution, "sol", 1);
    
    #$action = unshift(@solution);
    if (@solution)
    {
        print $solution[0];
    }
    else
    {
        print "SPEED";
    }
    print "\n";
}

##############
#   Sub part

# depending on speed, is there hole betweed our position and next round ?
#   - $s : speed
#   - $x : position on road
#   - $roads : road list
sub canDrive
{
    my ($s, $x, $roads) = @_;

    my @safe = qw(1 1 1 1);
    foreach $roadId (keys $roads)
    {
        my @cutedRoad = split("", $roads->{$roadId});
        for($i=$x; $i<=$x+$s; $i++)
        {
            if(defined($cutedRoad[$i]) && $cutedRoad[$i] eq "0")
            {
                $safe[$roadId] = 0;
                last;
            }
        }
    }
    return @safe;
}

# Check if we jump, who survive
#   - $s : speed
#   - $x : positon
#   - $roads : list of road
sub canJump
{
    my ($s, $x, $roads) = @_;

    my @safe;
    foreach my $roadId (keys $roads)
    {
        my @cutedRoad = split("", $roads->{$roadId});
        $safe[$roadId] = int (!defined($cutedRoad[$s+$x]) || $cutedRoad[$s+$x] eq '.');
    }
    return @safe;
}

#
# Check if some moto survive depending on the action
#
sub checkAction
{
    my ($motosH, $s, $action) = @_;
    my @motos = @$motosH;

    $x = $motos[0][0];
    if($action eq 'SPEED') { $s++; }
    elsif($action eq 'SLOW') { $s--; }
    
    if ($s == 0) { return (0, undef); }
    
    my @nMotos;
    given($action)
    {
        when (/(WAIT|SPEED|SLOW)/)
        {
            my @dSafe = canDrive($s, $x, $roads);
            foreach $moto (@motos)
            {
                if($dSafe[@$moto[1]])
                {
                    push(@nMotos, [@$moto[0]+$s, @$moto[1]]);
                }
            }
        }
        when ("DOWN")
        {
            my @dSafe = canDrive($s, $x, $roads);
            my @dOSafe = canDrive($s-1, $x, $roads);
            foreach my $moto (@motos)
            {
                if($dOSafe[@$moto[1]] && $dSafe[@$moto[1]+1] && @$moto[1]+1 < 4)
                {
                    push(@nMotos, [@$moto[0]+$s, @$moto[1]+1]);
                }
            }
        }
        when ("UP")
        {
            my @dSafe = canDrive($s, $x, $roads);
            my @dOSafe = canDrive($s-1, $x, $roads);

            foreach my $moto (@motos)
            {
                if($dOSafe[@$moto[1]] && $dSafe[@$moto[1]-1] && @$moto[1]-1 >= 0)
                {
                    push(@nMotos, [@$moto[0]+$s, @$moto[1]-1]);
                }
            }
        }
        when ("JUMP")
        {
            my @jSafe = canJump($s, $x, $roads);
            foreach my $moto (@motos)
            {
                if($jSafe[@$moto[1]])
                {
                    push(@nMotos, [@$moto[0]+$s, @$moto[1]]);
                }
            }
        }
    }
    
    if (@nMotos > 0)
    {
        return ($s, @nMotos);
    }
    else
    {
        return ($s, qw());
    }
}

#
# Check recursivly each action to finish the road
#
sub getPath
{
    my ($motosH, $s, $roads, $v, @current) = @_;
    my @motos = @$motosH;

    my @actionList = qw(SPEED UP DOWN WAIT JUMP SLOW);
    foreach my $action (@actionList)
    {
        my ($nS, @nMotos) = checkAction(\@motos, $s, $action);
        
        if(@nMotos >= $v)
        {
            push(@current, $action);
            my @cutedRoad = split("", $roads->{0});
            if($nMotos[0][0] >= @cutedRoad)
            {
                return @current;
            }
            else
            {
                @solution = getPath(\@nMotos, $nS, $roads, $v, @current);
                if (@solution)
                {
                    if ($solution[0] ne "")
                    {
                        return @solution;
                    }
                }
            }
            pop(@current);
        }
    }
}

# /**
#  * MyLogger  print data in STDERR to debug during developpement
#  *    - $value : value to print
#  *    - $comment : info about the value
#  *    - $debug (optionnal) : print $value in Data::Dumper
#  */
sub MyLogger {
    my ($value, $comment, $debug) = @_;
    
    if (!defined($debug)) {$debug = 0;}
    
    if($debug)
    {
        print STDERR "$comment : \n";
        print STDERR Dumper($value);
    }
    else
    {
        print STDERR "$comment : $value \n";
    }
}

Je me suis fait au passage une petite fonction pour le debug que je pense utiliser à chaque concours maintenant vu qu’il faut print les valeurs dans la STDERR pour débuguer son script.

1 commentaire

    Répondre95
  1. Photo d'avatar
    toto 01-05-2014 à 17:49

    Autres liens de sites réalisant des concours: http://codecondo.com/coding-challenges/ https://github.com/technoskald/coding-entertainment

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *