Koşu Uzunluğu Yarışçıları


18

Size iki giriş parçası verilecektir: koşu parkurunu tanımlayan çalışma uzunluğu kodlu formatta bir dize ve başlayacak şeridi temsil eden büyük harf. Örneğin, "3a4A6b5B" dizesi "aaaAAAAbbbbbbBBBBB" ye genişler. Daha sonra, bir parça oluşturmak için genişletilmiş dizeyi aşağıdaki gibi kullanırsınız:

 A) aaaAAAA
 B) bbbbbbBBBBB

Bu iki şeritli bir parkur. Küçük harfler havayı temsil eder. Canlı yayın yapamazsınız! Büyük harfler koşabileceğiniz yolu temsil eder. Bu meydan okuma için hedefiniz, büyük bir harf verildiğinde, o şeritte başlayan bir yarışçının ne kadar uzağa gidebileceğidir. Yarışçıların hemen üstünde veya altında bir yol varsa şerit değiştirmesine izin verilir. Ayrıca geriye doğru koşmalarına izin verilir! Bu parçada çıkış herhangi bir harf girişi için 0'dır , çünkü parçaların hiçbiri 1. konumda çalıştırılabilir bir yola sahip değildir.

Örnekler:

Giriş: "4A5B4c3C", "A"

Bu kod şöyle görünen bir parçaya genişler:

A) AAAA
B) BBBBB
C) ccccCCC

Bu örnek için çıktı 7'dir , çünkü A şeridinde başlayan bir koşucu, B şeridine ve daha sonra C şeridine gidebilir ve 7. pozisyonda sonlanabilir.

Giriş: "4A2B3D", "D"

Izlemek:

A) AAAA
B) BB
C)
D) DDD

Çıkış 3'tür , çünkü D şeridinde başlayan bir koşucunun B veya A şeridine ulaşması mümkün değildir.

Giriş: "4A4a4A3b6B5C", "A"

Izlemek:

A) AAAAaaaaAAAA
B) bbbBBBBBB
C) CCCCC

Çıkış 12'dir , çünkü A'daki koşucu B'ye geçebilir ve sonunda A'ya geri dönebilir. "C" için maksimum mesafe de 12'dir. "B" için 0'dır.

Giriş: "12M4n10N11O", "M"

Izlemek:

M) MMMMMMMMMMMM
N) nnnnNNNNNNNNNN
O) OOOOOOOOOOO

Çok basamaklı çalışma uzunluklarına sahip basit bir örnek. Çıktı 14 .

Giriş: "4A5B1b2B4c3C", "A"

Izlemek:

A) AAAA
B) BBBBBbBB
C) ccccCCC

Çıkış 8'dir , çünkü A'daki koşucu B'ye, sonra C'ye inebilir, sonra B'ye geri dönebilir. (Bu örnek için FryAmTheEggman'a teşekkür ederiz.)

Giriş: "1a2A2a2B1c1C1d3D", "B"

Izlemek:

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

Çıktı 4'tür . Koşucu, her iki yolu da kontrol etmelidir, hangisi daha da ileri gider. (Bu örnek için user81655'e teşekkürler.)

Giriş: "2A1b1B2C1D3E", "A"

Izlemek:

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

Çıktı 3 . En uzak hedefe ulaşmak için geriye doğru koşmalısınız. (Bir kez daha, bu örnek için user81655'e teşekkürler.)

Notlar:

  • Bir parkurun belirli bir konumda bir harfi yoksa, hava da sayılır. Bu nedenle, giriş "Q" ise ve "Q" şeridine hiçbir yol yerleştirilmemişse, çıkış 0 olmalıdır .
  • İki adet girdi vardır. Birincisi, çalışma uzunluğu kodlu bir dizedir. İkincisi büyük harftir (bunun için dize veya karakter veri türü kullanabilirsiniz.) Okunabilirlik için bu girişler arasında makul bir ayırıcı (boşluk, yeni satır, sekme, virgül, noktalı virgül) olmalıdır.
  • Çalışma uzunluğu kodlu dize öğeleri her zaman alfabetik sırayla listeler
  • Bir şeridin tüm uzunluğu en uzun 1000 olabilir. Bu nedenle, mümkün olan en büyük çıktı 1000'dir.

Parça Üreticisi:

İlk cevabımızın onuruna, bir parça üreticisi. Mevcut cevapları bulmak için bir şey bulmaya çalışın! (Not: Jeneratörün bir hata mesajı göstermemesi, parça kodunuzun mutlaka geçerli olduğu anlamına gelmez. Doğru form için yukarıdaki örneklere bakın.)

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
Anahtar kararları ve geriye doğru çalışırken, artık bir parçadan daha fazla bir labirent: P
user81655

Test senaryolarında olduğu gibi sadece tek bir rota var mı?
RichieAHB

@RichieAHB Birden fazla rota olabilir.
geokavel

Sadece eksik C'yi kullanmanın karmaşıklığının 4A2B3Dgiderilip giderilemeyeceğini mi merak ediyorsunuz ? Örneğin, ekleme 0c? Değilse, söz 1A1Zverildiği zaman , BY şeritlerinin var olduğu varsayılır (ancak boştur)?
Kenney

1
Ayrıca, geriye doğru koşmak büyük bir sorundur. 12M4n10N11OÖrneğin, çıkış 14, daha sonra yanlıştır: 25 bir uzunluk için C0 en uzun yol M0 başlar ve biter,
Kenney

Yanıtlar:


3

Perl, 231 219 203 192 189 bayt

için +1 içerir -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)

Daha az 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

Koşu

Mağaza Yukarıdaki kodu (diyelim bir dosyada 231.pl). Şeklinde girin (\d+\w)+ *\w. Örnek: parkur 4A5B4c3Cve şerit girişi A:

echo 4A5B4c3C A | perl -p 231.pl

Test odası

(golf oynamayan)

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);
  • güncelleme 219 dizi indeksleri yeniden çalıştırarak 12 bayt kaydedin.
  • güncelleme 203 Özyinelemeyi yeniden düzenleyerek 16 bayt kaydedin.
  • 192 sonrası@L=map{[/./g]}@L işlem sonrası ortadan kaldırarak 11 bayt kaydedin .
  • güncelleme 189 yerine ifkullanarak Postfixing 3 bayt kaydedin .mapfor

Bu bir Perl şeyse değil, ama bu HIZLI çalışır.
geokavel

6

JavaScript (ES6), 298 334 bayt

(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

açıklama

Temel olarak bu çözüm, yolu bir labirent gibi ele alır. Koşucunun ulaşması mümkün olan tüm karoların nerede olduğunu bulur ve bulduğu X indeksinin en büyük değerini döndürür.

Yaptığı ilk şey, giriş dizesini bir satır dizisine çözmek. Harfleri kullanmak yerine, büyük harfi a 1ve küçük harfini a 0. Ortaya çıkan harita şöyle görünecektir:

11100011
0011100
100111

Bundan sonra, başlangıç ​​yolunun ilk döşemesini a 2(sadece zaten varsa 1) yapar ve bitişik döşemeleri kontrol eden her döşemeden geçer 2. 1A'nın bitişik 2olması durumunda a olur 2. Eğer koşucu ilk satırda başlamışsa yukarıdaki harita bu olacaktır:

22200011
0022200
100222

A için en yüksek X dizini 2sonuç olur.

Bunun ilk sürümünü yaptığımda çok küçük bir gözetim yaptım ve işe yarayana kadar kesmek için bana 36 bayt mal oldu, bu yüzden muhtemelen bu konuda yapılabilecek birçok iyileştirme var. *iç çekmek*

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

Ölçek

Bonus: Çıktı, ayrıştırılmış haritayı içerir!

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>

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.