Бігові гонки


18

Вам будуть надані два фрагменти введення: рядок у кодованому форматом довжині довжини, що визначає бігову доріжку, і велика літера, що представляє смугу, з якої слід починати. Наприклад, рядок "3a4A6b5B" розширюється на "aaaAAAAbbbbbbbBBBBB". Потім ви використовуєте розширений рядок для створення доріжки як такої:

 A) aaaAAAA
 B) bbbbbbBBBBB

Це доріжка з двома смугами. Малі літери представляють повітря. Не можна бігати в ефір! Великі літери являють собою дорогу, по якій можна пробігати. Ваша мета цього виклику полягає в тому, щоб з великої літери вивести, наскільки далеко може пробігти гонщик, що починається на цій смузі. Гонщикам дозволено перемикати смуги руху, якщо над ними або під ними знаходиться ділянка дороги. Їм також дозволяється бігати назад! На цій конкретній доріжці вихід дорівнює 0 для будь-якого введення літери, оскільки жодна з доріжок не має дороги, яку можна виконати в положенні 1.

Приклади:

Вхід: "4A5B4c3C", "A"

Цей код розширюється на композицію, яка виглядає приблизно так:

A) AAAA
B) BBBBB
C) ccccCCC

Вихід для цього прикладу дорівнює 7 , тому що бігун, що починається на смузі A, може рухатися вниз до смуги B, а потім смуги C і опинятися на 7-й позиції.

Вхід: "4A2B3D", "D"

Доріжка:

A) AAAA
B) BB
C)
D) DDD

Вихід 3 , тому що бігун, що починається на смузі D, не має можливості дістатися до смуги B або A

Вхід: "4A4a4A3b6B5C", "A"

Доріжка:

A) AAAAaaaaAAAA
B) bbbBBBBBB
C) CCCCC

Вихід 12 , тому що бігун на A може перейти на B, а потім повернутися до A в кінці. Максимальна відстань для "C" також є 12. Для "B" це 0.

Вхід: "12M4n10N11O", "M"

Доріжка:

M) MMMMMMMMMMMM
N) nnnnNNNNNNNNNN
O) OOOOOOOOOOO

Простий приклад з багатозначною довжиною пробігу. Вихід 14 .

Вхід: "4A5B1b2B4c3C", "A"

Доріжка:

A) AAAA
B) BBBBBbBB
C) ccccCCC

Вихід 8 , тому що бігун на A може спуститися до B, потім до C, потім повернутися до B. (Дякую FryAmTheEggman за цей приклад.)

Вхід: "1a2A2a2B1c1C1d3D", "B"

Доріжка:

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

Вихід 4 . Бігун повинен перевірити обидві стежки, дві бачити, що йде далі. (Завдяки користувачеві81655 за цей приклад.)

Вхід: "2A1b1B2C1D3E", "A"

Доріжка:

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

Вихід 3 . Вам потрібно бігти назад, щоб дістатися до самого віддаленого пункту призначення. (Ще раз дякую користувачеві81655 за цей приклад.)

Примітки:

  • Якщо доріжка не має літери в певному положенні, це також вважається повітряним. Таким чином, якщо вхід "Q", а дорога не розміщена на смузі "Q", вихід повинен бути 0 .
  • Є два фрагменти введення. Перший - це кодований рядок довжиною прогону. Друга - велика літера (для цього можна використовувати тип даних рядка чи знаку.) Для читабельності між цими входами повинен бути розумний роздільник (пробіл, новий рядок, вкладка, кома, крапка з двокрапкою).
  • Кодований рядок довжиною виконання буде завжди перераховувати елементи в алфавітному порядку
  • Найдовша довжина смуги може становити 1000. Отже, максимально можливий вихід 1000.

Генератор треків:

На честь нашої першої відповіді, ось генератор треків. Спробуйте придумати щось, щоб спотикати поточні відповіді! (Примітка. Тільки тому, що генератор не показує повідомлення про помилку, не означає, що код треку обов'язково дійсний. Див. Вище приклади для належної форми.)

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
Із рішеннями про перемикання та заднім ходом зараз це більше лабіринт, ніж трек: P
user81655

Чи існує колись один маршрут - як у тестових випадках?
RichieAHB

@RichieAHB Маршрут може бути більше, ніж один.
geokavel

Цікаво, чи можливо ускладнення поводження з відсутнім С в 4A2B3D бути усунено ? Наприклад, додавання 0c? Якщо ні, чи очікується, коли скажуть 1A1Z, що смуги BY передбачається існувати (але порожні)?
Кенні

1
Крім того, біг назад - це величезна проблема. The12M4n10N11OПриклад, висновок 14, тоді невірно: найдовший шлях починається в точці М0 і закінчується на C0, при довжині 25
Kenney

Відповіді:


3

Perl, 231 219 203 192 189 байт

включає +1 для -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)

Менше гольфу:

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

Біг

Зберігайте код вище у файлі (скажімо 231.pl). Введення у вигляді (\d+\w)+ *\w. Приклад: введення доріжки 4A5B4c3Cта смуги A:

echo 4A5B4c3C A | perl -p 231.pl

TestSuite

(не для гольфу)

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);
  • оновлення 219 зберегти 12 байт шляхом переробки індексів масиву.
  • оновлення 203 Збережіть 16 байт шляхом рефакторингу рекурсії.
  • оновлення 192 збереження 11 байтів, усунення @L=map{[/./g]}@Lпісляобробки.
  • оновлення 189 зберегти 3 байти шляхом постфіксації, ifвикористовуючи mapзамість for.

Я не знаю, якщо це справа Perl, але це працює ШВИДКО.
geokavel

6

JavaScript (ES6), 298 334 байт

(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

Пояснення

В основному це рішення трактує доріжку як лабіринт. Він знаходить, де знаходяться всі плитки, до яких можна досягти бігуна, і повертає найбільше значення знайденого індексу X.

Перше, що він робить - це декодування вхідного рядка в масив рядків. Замість використання букв він перетворює великі літери на 1а, а малі літери - на а 0. Отримана карта буде виглядати приблизно так:

11100011
0011100
100111

Після цього вона робить першу плитку стартової доріжки a 2(лише якщо вона вже є 1) і проходить через кожну плитку, перевіряючи сусідні плитки на a 2. Якщо a 1має суміжний, 2він стає a 2. Наведена вище карта стане такою, якщо бігун стартував на першому рядку:

22200011
0022200
100222

Найвищий X індекс для a 2стає результатом.

Я зробив дуже незначний нагляд, коли зробив початкову версію цього, і коштувало мені 36 байт, щоб зламати його, поки воно не спрацювало, тому, мабуть, багато вдосконалень, які можна було б зробити для цього. * зітхнути *

Безумовно

(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

Тест

Бонус: Вихід включає проаналізовану карту!

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>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.