Coureurs de course

18

Vous recevrez deux éléments d'entrée: une chaîne au format codé de longueur définissant la piste de course et une lettre majuscule représentant la voie à partir de laquelle. Par exemple, la chaîne "3a4A6b5B" se développe en "aaaAAAAbbbbbbBBBBB". Vous utilisez ensuite la chaîne développée pour créer une piste, en tant que telle:

 A) aaaAAAA
 B) bbbbbbBBBBB

Il s'agit d'une piste à deux voies. Les lettres minuscules représentent l'air. Vous ne pouvez pas courir sur l'air! Les lettres majuscules représentent la route sur laquelle vous pouvez courir. Votre objectif pour ce défi est, compte tenu d'une lettre majuscule, de montrer jusqu'où un coureur commençant sur cette voie pourrait courir. Les coureurs sont autorisés à changer de voie s'il y a un morceau de route juste au-dessus ou en dessous d'eux. Ils sont également autorisés à reculer! Sur cette piste particulière, la sortie est 0 pour toute entrée de lettre, car aucune des pistes n'a de route exécutable à la position 1.

Exemples:

Entrée: "4A5B4c3C", "A"

Ce code se développe en une piste qui ressemble à ceci:

A) AAAA
B) BBBBB
C) ccccCCC

La sortie de cet exemple est 7 , car un coureur commençant sur la voie A pourrait descendre vers la voie B, puis la voie C, et finir à la 7e position.

Entrée: "4A2B3D", "D"

Piste:

A) AAAA
B) BB
C)
D) DDD

La sortie est 3 , car un coureur commençant sur la voie D n'a aucun moyen de se rendre sur la voie B ou A

Entrée: "4A4a4A3b6B5C", "A"

Piste:

A) AAAAaaaaAAAA
B) bbbBBBBBB
C) CCCCC

La sortie est 12 , car le coureur sur A peut basculer sur B, puis revenir sur A à la fin. La distance maximale pour "C" est également de 12. Pour "B", elle est de 0.

Entrée: "12M4n10N11O", "M"

Piste:

M) MMMMMMMMMMMM
N) nnnnNNNNNNNNNN
O) OOOOOOOOOOO

Exemple simple avec des longueurs d'exécution à plusieurs chiffres. La sortie est 14 .

Entrée: "4A5B1b2B4c3C", "A"

Piste:

A) AAAA
B) BBBBBbBB
C) ccccCCC

La sortie est 8 , car le coureur en A peut descendre en B, puis en C, puis revenir en B. (Merci à FryAmTheEggman pour cet exemple.)

Entrée: "1a2A2a2B1c1C1d3D", "B"

Piste:

A)aAAaa
B)BB
C)cC
D)dDDD

La sortie est 4 . Le coureur doit vérifier les deux chemins, voir lequel va plus loin. (Merci à user81655 pour cet exemple.)

Entrée: "2A1b1B2C1D3E", "A"

Piste:

A) AA
B) bB
C) CC
D) D
E) EEE

La sortie est 3 . Vous devez courir en arrière pour atteindre la destination la plus éloignée. (Encore une fois, merci à user81655 pour cet exemple.)

Remarques:

  • Si une piste n'a pas de lettre à une certaine position, cela compte aussi comme de l'air. Ainsi, si l'entrée est "Q" et qu'aucune route n'a été placée sur la voie "Q", la sortie doit être 0 .
  • Il y a deux éléments d'entrée. Le premier est une chaîne codée de longueur. La seconde est une lettre majuscule (vous pouvez utiliser le type de données chaîne ou char pour cela.) Pour la lisibilité, il devrait y avoir un séparateur raisonnable entre ces entrées (espace, nouvelle ligne, tabulation, virgule, point-virgule).
  • La chaîne encodée de longueur d'exécution listera toujours les éléments dans l'ordre alphabétique
  • La longueur la plus longue d'une voie peut être de 1000. Par conséquent, la sortie la plus élevée possible est de 1000.

Générateur de piste:

En l'honneur de notre première réponse, voici un générateur de piste. Essayez de trouver quelque chose pour étouffer les réponses actuelles! (Remarque: ce n'est pas parce que le générateur n'affiche pas de message d'erreur que votre code de piste est nécessairement valide. Voir les exemples ci-dessus pour la forme appropriée.)

function reset() {
    var t = document.getElementById("track");
    t.innerHTML = "";
    for(var i = 0;i<26;i++) {
      var c = String.fromCharCode(i+65);
      t.innerHTML += "<div><span>"+c+") </span><span id='"+c+"'></span></div>";
      
    }
  }

function rand() {
  var track = "";
  for(var i = 0;i<26;i++) {
  var blocks = Math.floor(Math.random()*4);
  var start = Math.floor(Math.random()*2);
  for(var j = 0;j<blocks;j++) {
    var letter = String.fromCharCode(65+i+32*((start+j)%2));
    var length = Math.floor(Math.random()*4)+1;
    track += length+letter;
  }
  }
  document.getElementById("code").value = track;
}

  function gen() {
  var s = document.getElementById("code").value;
    var check = s.match(/(\d+[A-Za-z])+/);
    if(check == null || check[0]!=s) {
      alert("Invalid Track");
      return false;
    }
    reset();
  var n = s.match(/\d+/g);
    var o = s.match(/[A-Za-z]/g);
    for(var i = 0;i<n.length;i++) {
      var c = o[i].toUpperCase();
      document.getElementById(c).textContent += o[i].repeat(n[i]);
    }
    return true;
    }
<body onload="reset()">
Track: <input type="text" id="code" size="75%" /><input type="submit" onclick="gen()" /><input type="button" value="Random Track" onclick="rand()" /><code id="track"/>
  </body>

geokavel
la source
3
Avec les décisions de changement et la marche arrière, c'est plus un labyrinthe qu'une piste maintenant: P
user81655
N'y a-t-il jamais qu'une seule voie - comme dans les cas de test?
RichieAHB
@RichieAHB Il peut y avoir plusieurs itinéraires.
geokavel
Vous vous demandez simplement si la complication de la gestion du C manquant 4A2B3Dpourrait être supprimée? Par exemple, ajouter 0c? Si ce n'est pas le cas, est-il prévu au moment de dire 1A1Z, les voies BY sont supposées exister (mais sont vides)?
Kenney
1
En outre, la marche arrière est un énorme problème. L' 12M4n10N11Oexemple, sortie 14, est alors faux: le chemin le plus long commence à M0 et se termine à C0, pour une longueur de 25.
Kenney

Réponses:

3

Perl, 231 219 203 192 189 189 octets

comprend +1 pour -p

sub f{my($l,$p,$m)=@_;map{$m=$_>$m?$_:$m}f($l,$p+1)+1,f($l-1,$p),f($l+1,$p),f($l,$p-1)-1if$L[$l][$p]&&!$V{$l}{$p}++;$m}s/(\d+)(.)\s*/push@{$L[ord$2&~32]},(0|$2lt'a')x$1;()/ge;$_=0|f(ord,0)

Moins golfé:

sub f{                          # this is a recursive function, so we need locals.
    my($l,$p,$m)=@_;            # in: lane, position; local: max path length

    map{
      $m = $_ > $m ? $_ : $m    # update max
    }
    f( $l,   $p+1 )+1,          # same lane, forward
    f( $l-1, $p   ),            # left lane, same pos
    f( $l+1, $p   ),            # right lane, same pos
    f( $l,   $p-1 )-1           # same lane, backtrack
    if
        $L[$l][$p]              # check if there's road here
    && !$V{$l}{$p}++            # and we've not visited this point before.
    ;

    $m                          # return the max
}

s/(\d+)(.)\s*/                  # Parse RLE pattern, strip starting lane separator
  push@{ $L[ord$2&~32] }        # index @L using uppercase ascii-code, access as arrayref
  ,(0|$2lt'a')x$1               # unpack RLE as bitstring
  ;()                           # return empty list for replacement
/gex;                           # (x for ungolfing)
                                # $_ now contains trailing data: the start lane.

$_ =                            # assign output for -p
   0|                           # make sure we print 0 instead of undef/nothing
   f(ord,0)                     # begin calculation at start of current lane

Fonctionnement

Stockez le code ci-dessus dans un fichier (par exemple 231.pl). Entrée sous forme de (\d+\w)+ *\w. Exemple: saisie d'une piste 4A5B4c3Cet d'une voie A:

echo 4A5B4c3C A | perl -p 231.pl

Suite de tests

(non golfé)

printf "==== Testing %s\n", $file = shift // '231.pl';

sub t{
    my($input,$expect) = @_;
#   $input =~ s/\s//g;
    printf "TEST %-20s -> %-3s: ", $input, $expect;

    $output = `echo $input | perl -p $file`;

    printf "%-3s  %s\n", $output,
    $output == $expect
    ? " PASS"
    : " FAIL: $output != $expect";

}

t("4A5B4c3C A", 7);
t("4A5B4c3C C", 0);
t("4A2B3D D", 3);
t("4A4a4A3b6B5C A", 12);
t("4A4a4A3b6B5C B",  0);
t("4A4a4A3b6B5C C", 12);
t("12M4n10N11O M", 14 );
t("4A5B1b2B4c3C A", 8);
t("1a2A2a2B1c1C1d3D B", 4 );
t("2A1b1B2C1D3E A", 3 );
t("10A9b1B8c2C9D1E11F A", 11);
  • update 219 save 12 bytes en retravaillant les indices de tableau.
  • update 203 Économisez 16 octets en refactorisant la récursivité.
  • mise à jour 192 enregistrer 11 octets en éliminant le @L=map{[/./g]}@Lpost - traitement.
  • mise à jour 189 enregistrer 3 octets en post-fixant en ifutilisant mapau lieu de for.
Kenney
la source
Je ne sais pas si c'est une chose Perl, mais cela fonctionne RAPIDEMENT.
geokavel
6

JavaScript (ES6), 298 334 octets

(t,s)=>[a=[],t.match(/\d+(.)(\d+\1)*/gi).map(l=>a[c=l.match`[A-Z]`+"",n=c.charCodeAt(),c==s?i=n:n]=l[r="replace"](/\d+./g,p=>(p.slice(-1)<"a"?"1":"0").repeat(parseInt(p))),i=o=-1),...a.join``,a[i]?a[i]=a[i][r](/^1/,2):0].map(_=>a.map((l,y)=>a[y]=l[r](/1/g,(c,x)=>((a[y-1]||s)[x]|(a[y+1]||s)[x]|l[x-1]|l[x+1])>1?(x>o?o=x:0,2):c)))&&o+1

Explication

Fondamentalement, cette solution traite la piste comme un labyrinthe. Il trouve où se trouvent toutes les tuiles possibles pour le coureur et renvoie la plus grande valeur de l'index X qu'il a trouvé.

La première chose qu'il fait est de décoder la chaîne d'entrée en un tableau de lignes. Au lieu d'utiliser des lettres, il transforme une lettre majuscule en a 1et une lettre minuscule en a 0. La carte résultante ressemblera à ceci:

11100011
0011100
100111

Après cela, il crée la première tuile de la piste de départ a 2(seulement si c'est déjà le cas 1) et boucle à travers chaque tuile en vérifiant les tuiles adjacentes pour a 2. Si a 1a un adjacent, 2il devient a 2. La carte ci-dessus deviendra ceci si le coureur a commencé sur la première ligne:

22200011
0022200
100222

L'indice X le plus élevé pour a 2devient le résultat.

J'ai fait une erreur très mineure lorsque j'ai fait la version initiale de cela et cela m'a coûté 36 octets pour le pirater jusqu'à ce qu'il fonctionne, donc il y a probablement beaucoup d'améliorations qui pourraient être apportées à cela. *soupir*

Non golfé

(t,s)=>
  [

    // Decode run-length encoded string into an array of track lanes
    a=[],                           // a = array of track line strings, 0 = air, 1 = tiles
    t.match(/\d+(.)(\d+\1)*/gi)     // regex magic that separates pairs by their letter
    .map(l=>                        // for each line of pairs
      a[                            // add the tiles to the array
        c=l.match`[A-Z]`+"",        // c = pair character
        n=c.charCodeAt(),           // n = index of line
        c==s?i=n:n                  // if this line is the starting line, set i
      ]=l[r="replace"](/\d+./g,p=>  // match each pair, p = pair
        (p.slice(-1)<"a"
          ?"1":"0").repeat(         // repeat 0 for air or 1 for ground
            parseInt(p)             // cast of match would return NaN because of the
          )                         //     letter at the end but parseInt works fine
      ),
        i=                          // i = index of starting line, initialise as invalid
          o=-1                      // o = output (max value of x)
    ),

  // Find all positions that are possible for the runner to get to
    ...a.join``,                   // add every letter of the track lines to an array
    a[i]?a[i]=a[i][r](/^1/,2):0    // set the starting tile to 2 if it is already 1
  ].map(_=>                        // loop for the amount of tiles, this is usually way
                                   //     more than necessary but allows for hard to reach
                                   //     tiles to be parsed
    a.map((l,y)=>                  // for each line l at index y
      a[y]=l[r](/1/g,(c,x)=>       // for each character c at index x

        // Replace a 1 with 2 if there is a 2 to above, below, left or right of it
        ((a[y-1]||s)[x]|(a[y+1]||s)[x]|l[x-1]|l[x+1])>1?
          (x>o?o=x:0,2):c          // set o to max value of x for a 2 tile
      )
    )
  )
  &&o+1                            // return o + 1

Tester

Bonus: la sortie inclut la carte analysée!

var solution = (t,s)=>[a=[],t.match(/\d+(.)(\d+\1)*/gi).map(l=>a[c=l.match`[A-Z]`+"",n=c.charCodeAt(),c==s?i=n:n]=l[r="replace"](/\d+./g,p=>(p.slice(-1)<"a"?"1":"0").repeat(parseInt(p))),i=o=-1),...a.join``,a[i]?a[i]=a[i][r](/^1/,2):0].map(_=>a.map((l,y)=>a[y]=l[r](/1/g,(c,x)=>((a[y-1]||s)[x]|(a[y+1]||s)[x]|l[x-1]|l[x+1])>1?(x>o?o=x:0,2):c)))&&o+1
function generateMap() { var start = 0; a.some((l, i) => l ? start = i : 0); var end = 0; a.map((l, i) => l && i <= 90 ? end = i : 0); for(var output = "", i = start; i < end + 1; i++) output += String.fromCharCode(i) + ") " + (a[i] || "") + "\n"; return output; }
Track = <input type="text" id="track" value="2A1b1B2C1D3E" /><br />
Starting Letter = <input type="text" id="start" value="A" /><br />
<button onclick="result.textContent=solution(track.value,start.value)+'\n\n'+generateMap()">Go</button>
<pre id="result"></pre>

user81655
la source