Corridori Run-Length


18

Ti verranno dati due pezzi di input: una stringa in formato codificato di lunghezza che definisce la pista da corsa e una lettera maiuscola che rappresenta la corsia da cui iniziare. Ad esempio, la stringa "3a4A6b5B" si espande in "aaaAAAAbbbbbbBBBBB". Quindi utilizzare la stringa espansa per creare una traccia, come tale:

 A) aaaAAAA
 B) bbbbbbBBBBB

Questa è una pista con due corsie. Le lettere minuscole rappresentano l'aria. Non puoi correre in onda! Le lettere maiuscole rappresentano la strada su cui puoi correre. Il tuo obiettivo per questa sfida è, dato una lettera maiuscola, produrre fino a che distanza potrebbe correre un corridore che inizia su quella corsia. I corridori sono autorizzati a cambiare corsia se c'è un pezzo di strada direttamente sopra o sotto di essi. Possono anche correre all'indietro! Su questa traccia particolare l'output è 0 per qualsiasi input di lettere, poiché nessuna delle tracce ha una strada percorribile in posizione 1.

Esempi:

Ingresso: "4A5B4c3C", "A"

Questo codice si espande in una traccia simile alla seguente:

A) AAAA
B) BBBBB
C) ccccCCC

L'output per questo esempio è 7 , perché un corridore che inizia sulla corsia A potrebbe spostarsi verso il basso sulla corsia B, quindi sulla corsia C e finire alla 7a posizione.

Ingresso: "4A2B3D", "D"

Traccia:

A) AAAA
B) BB
C)
D) DDD

L'output è 3 , perché un corridore che inizia sulla corsia D non ha modo di raggiungere la corsia B o A

Ingresso: "4A4a4A3b6B5C", "A"

Traccia:

A) AAAAaaaaAAAA
B) bbbBBBBBB
C) CCCCC

L'output è 12 , perché il corridore su A può passare a B, e quindi tornare ad A alla fine. Anche la distanza massima per "C" è 12. Per "B" è 0.

Ingresso: "12M4n10N11O", "M"

Traccia:

M) MMMMMMMMMMMM
N) nnnnNNNNNNNNNN
O) OOOOOOOOOOO

Esempio semplice con lunghezze di esecuzione a più cifre. L'output è 14 .

Ingresso: "4A5B1b2B4c3C", "A"

Traccia:

A) AAAA
B) BBBBBbBB
C) ccccCCC

L'output è 8 , perché il corridore in A può scendere in B, quindi in C, quindi tornare in B. (Grazie a FryAmTheEggman per questo esempio.)

Ingresso: "1a2A2a2B1c1C1d3D", "B"

Traccia:

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

L'output è 4 . Il corridore deve controllare entrambi i percorsi, due vedono che va oltre. (Grazie a user81655 per questo esempio.)

Ingresso: "2A1b1B2C1D3E", "A"

Traccia:

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

L'output è 3 . Devi correre all'indietro per raggiungere la destinazione più lontana. (Ancora una volta, grazie a user81655 per questo esempio.)

Appunti:

  • Se una traccia non ha una lettera in una determinata posizione, anche questa conta come aria. Pertanto, se l'ingresso è "Q" e nessuna strada è stata posizionata sulla corsia "Q", l'uscita dovrebbe essere 0 .
  • Ci sono due pezzi di input. La prima è una stringa codificata di lunghezza. La seconda è una lettera maiuscola (per questo puoi usare il tipo di dati stringa o carattere). Per leggibilità, dovrebbe esserci un ragionevole separatore tra questi input (spazio, nuova riga, tabulazione, virgola, punto e virgola).
  • La stringa codificata per la lunghezza elencherà sempre gli elementi in ordine alfabetico
  • Il più lungo può essere l'intera lunghezza di una corsia è 1000. Pertanto, la massima produzione possibile è 1000.

Generatore di tracce:

In onore della nostra prima risposta, ecco un generatore di tracce. Prova a trovare qualcosa per sconcertare le risposte attuali! (Nota: solo perché il generatore non mostra un messaggio di errore non significa che il codice della traccia sia necessariamente valido. Vedi gli esempi sopra per la forma corretta.)

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>


3
Con le decisioni sul cambio e la marcia indietro è più un labirinto che una traccia ora: P
user81655

Esiste sempre un'unica strada, come nei casi di test?
RichieAHB il

@RichieAHB Potrebbe esserci più di un percorso.
geokavel,

Ti stai solo chiedendo se forse la complicazione della gestione della C mancante 4A2B3Dpotrebbe essere rimossa? Ad esempio, aggiungendo 0c? In caso contrario, è previsto quando si dice che le 1A1Zcorsie BY si presume esistano (ma sono vuote)?
Kenney,

1
Inoltre, la corsa all'indietro è un grosso problema. L' 12M4n10N11Oesempio, output 14, è quindi falso: il percorso più lungo inizia in M0 e termina in C0, per una lunghezza di 25.
Kenney,

Risposte:


3

Perl, 231 219 203 192 189 byte

include +1 per -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)

Meno 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

In esecuzione

Memorizza il codice sopra in un file (diciamo 231.pl). Inserire sotto forma di (\d+\w)+ *\w. Esempio: immissione di traccia 4A5B4c3Ce corsia A:

echo 4A5B4c3C A | perl -p 231.pl

TestSuite

(non golfato)

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);
  • l'aggiornamento 219 salva 12 byte rielaborando gli indici di array.
  • aggiornamento 203 Salva 16 byte rifattorizzando la ricorsione.
  • l'aggiornamento 192 salva 11 byte eliminando il @L=map{[/./g]}@Lpostprocessing.
  • aggiornamento 189 salva 3 byte postfisso ifusando mapinvece di for.

Non se questa è una cosa Perl, ma funziona VELOCEMENTE.
geokavel,

6

JavaScript (ES6), 298 334 byte

(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

Spiegazione

Fondamentalmente questa soluzione tratta la pista come un labirinto. Trova dove sono tutte le tessere possibili per il corridore e restituisce il massimo valore dell'indice X trovato.

La prima cosa che fa è decodificare la stringa di input in una matrice di linee. Invece di usare le lettere, trasforma una lettera maiuscola in una 1e una lettera minuscola in una 0. La mappa risultante sarà simile a questa:

11100011
0011100
100111

Dopodiché rende la prima tessera della traccia iniziale a 2(solo se è già 1) e scorre attraverso ogni tessera controllando le tessere adiacenti per a 2. Se a 1ha un adiacente 2diventa a 2. La mappa sopra diventerà questa se il corridore ha iniziato sulla prima riga:

22200011
0022200
100222

L'indice X più alto per a 2diventa il risultato.

Ho fatto una supervisione molto minore quando ho fatto la versione iniziale di questo e mi è costato 36 byte di hackerarlo fino a quando non ha funzionato, quindi probabilmente ci sono molti miglioramenti che potrebbero essere fatti a questo. *sospiro*

Ungolfed

(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

Test

Bonus: l'output include la mappa analizzata!

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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.