Đường đua dài


18

Bạn sẽ được cung cấp hai phần đầu vào: một chuỗi ở định dạng được mã hóa theo chiều dài chạy xác định đường chạy và chữ in hoa thể hiện làn đường để bắt đầu. Ví dụ: chuỗi "3a4A6b5B" mở rộng thành "aaaAAAAbbbbbbBBBBB". Sau đó, bạn sử dụng chuỗi mở rộng để tạo một bản nhạc, như sau:

 A) aaaAAAA
 B) bbbbbbBBBBB

Đây là một đường đua với hai làn đường. Chữ thường đại diện cho không khí. Bạn không thể chạy trên không! Chữ in hoa đại diện cho con đường bạn có thể chạy. Mục tiêu của bạn cho thử thách này là, được đặt một chữ in hoa, cho ra một tay đua bắt đầu đi trên làn đường đó có thể chạy bao xa. Các tay đua được phép chuyển làn nếu có một đoạn đường ngay phía trên hoặc bên dưới chúng. Họ cũng được phép chạy ngược! Trên bản nhạc cụ thể này, đầu ra là 0 cho bất kỳ đầu vào chữ cái nào, bởi vì cả hai bản nhạc đều không có đường chạy ở vị trí 1.

Ví dụ:

Đầu vào: "4A5B4c3C", "A"

Mã này mở rộng thành một bản nhạc trông như thế này:

A) AAAA
B) BBBBB
C) ccccCCC

Đầu ra cho ví dụ này là 7 , vì một người chạy bắt đầu trên làn A có thể di chuyển xuống làn B, rồi sang làn C và kết thúc ở vị trí thứ 7.

Đầu vào: "4A2B3D", "D"

Theo dõi:

A) AAAA
B) BB
C)
D) DDD

Đầu ra là 3 , vì một người chạy bắt đầu ở làn D không có cách nào để đến làn B hoặc A

Đầu vào: "4A4a4A3b6B5C", "A"

Theo dõi:

A) AAAAaaaaAAAA
B) bbbBBBBBB
C) CCCCC

Đầu ra là 12 , vì người chạy trên A có thể chuyển sang B, và sau đó quay lại A ở cuối. Khoảng cách tối đa cho "C" cũng là 12. Với "B", nó là 0.

Đầu vào: "12M4n10N11O", "M"

Theo dõi:

M) MMMMMMMMMMMM
N) nnnnNNNNNNNNNN
O) OOOOOOOOOOO

Ví dụ đơn giản với độ dài chạy nhiều chữ số. Đầu ra là 14 .

Đầu vào: "4A5B1b2B4c3C", "A"

Theo dõi:

A) AAAA
B) BBBBBbBB
C) ccccCCC

Đầu ra là 8 , vì người chạy tại A có thể xuống B, sau đó xuống C, sau đó quay lại B. (Cảm ơn FryAmTheEggman vì ví dụ này.)

Đầu vào: "1a2A2a2B1c1C1d3D", "B"

Theo dõi:

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

Đầu ra là 4 . Người chạy phải kiểm tra cả hai con đường để xem cái nào đi xa hơn. (Cảm ơn user81655 vì ví dụ này.)

Đầu vào: "2A1b1B2C1D3E", "A"

Theo dõi:

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

Đầu ra là 3 . Bạn phải chạy ngược để đến đích xa nhất. (Một lần nữa, nhờ user81655 cho ví dụ này.)

Ghi chú:

  • Nếu một bản nhạc không có chữ cái ở một vị trí nhất định, thì nó cũng được tính là không khí. Như vậy, nếu đầu vào là "Q" và không có đường nào được đặt trên làn "Q" thì đầu ra phải là 0 .
  • Có hai phần đầu vào. Đầu tiên là một chuỗi mã hóa có độ dài chạy. Thứ hai là chữ in hoa (bạn có thể sử dụng chuỗi hoặc kiểu dữ liệu char cho việc này.) Để dễ đọc, cần có một khoảng cách hợp lý giữa các đầu vào này (dấu cách, dòng mới, tab, dấu phẩy, dấu chấm phẩy).
  • Chuỗi được mã hóa theo chiều dài chạy sẽ luôn liệt kê các phần tử theo thứ tự bảng chữ cái
  • Chiều dài rất dài toàn bộ chiều dài của một làn có thể là 1000. Do đó, sản lượng lớn nhất có thể là 1000.

Máy phát điện theo dõi:

Để vinh danh câu trả lời đầu tiên của chúng tôi, đây là một trình tạo theo dõi. Hãy cố gắng đưa ra một cái gì đó để bỏ qua các câu trả lời hiện tại! (Lưu ý: Chỉ vì trình tạo không hiển thị thông báo lỗi không có nghĩa là mã theo dõi của bạn nhất thiết phải hợp lệ. Xem các ví dụ ở trên để có hình thức phù hợp.)

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
Với các quyết định chuyển đổi và chạy ngược lại, nó giống như một mê cung hơn bây giờ: P
user81655 19/12/15

Có bao giờ chỉ có một tuyến đường - như trong các trường hợp thử nghiệm?
RichieAHB

@RichieAHB Có thể có nhiều hơn một tuyến đường.
geokavel

Chỉ cần tự hỏi nếu có thể các biến chứng của việc xử lý C mất tích 4A2B3Dcó thể được loại bỏ? Chẳng hạn, thêm 0c? Nếu không, dự kiến ​​khi nói 1A1Zđã được đưa ra, làn đường BY được giả sử tồn tại (nhưng trống)?
Kenney

1
Ngoài ra, chạy ngược là một vấn đề rất lớn. Các 12M4n10N11Oví dụ, đầu ra 14, sau đó giả: dài nhất bắt đầu con đường tại M0 và kết thúc tại C0, cho chiều dài 25.
Kenney

Câu trả lời:


3

Perl, 231 219 203 192 189 byte

bao gồm +1 cho -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)

Ít chơi gôn hơn:

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

Đang chạy

Lưu trữ mã ở trên trong một tập tin (nói 231.pl). Đầu vào ở dạng (\d+\w)+ *\w. Ví dụ: nhập đường 4A5B4c3Cvà làn đường A:

echo 4A5B4c3C A | perl -p 231.pl

TestSuite

(không chơi gôn)

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);
  • cập nhật 219 lưu 12 byte bằng cách làm lại các chỉ mục mảng.
  • cập nhật 203 Lưu 16 byte bằng cách tái cấu trúc đệ quy.
  • cập nhật 192 lưu 11 byte bằng cách loại bỏ hậu @L=map{[/./g]}@Lxử lý.
  • cập nhật 189 lưu 3 byte bằng cách viết hậu tố ifbằng cách sử dụng mapthay vì for.

Tôi không nếu đây là một điều Perl, nhưng điều này chạy NHANH CHÓNG.
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

Giải trình

Về cơ bản giải pháp này coi đường đua là một mê cung. Nó tìm thấy nơi tất cả các ô có thể đạt được của người chạy và trả về giá trị lớn nhất của chỉ số X mà nó tìm thấy.

Điều đầu tiên nó làm là giải mã chuỗi đầu vào thành một mảng các dòng. Thay vì sử dụng các chữ cái, nó biến 1một chữ in hoa thành một chữ cái viết thường thành a 0. Bản đồ kết quả sẽ trông giống như thế này:

11100011
0011100
100111

Sau đó, nó tạo ra ô đầu tiên của rãnh bắt đầu a 2(chỉ khi nó đã có 1) và các vòng lặp qua mỗi ô kiểm tra các ô liền kề cho a 2. Nếu a 1có liền kề 2thì nó trở thành a 2. Bản đồ trên sẽ trở thành thế này nếu người chạy bắt đầu ở dòng đầu tiên:

22200011
0022200
100222

Chỉ số X cao nhất cho một 2kết quả.

Tôi đã thực hiện một giám sát rất nhỏ khi tôi thực hiện phiên bản ban đầu này và tôi đã tốn 36 byte để hack nó cho đến khi nó hoạt động, vì vậy có lẽ có rất nhiều cải tiến có thể được thực hiện cho việc này. *thở dài*

Ung dung

(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

Kiểm tra

Phần thưởng: Đầu ra bao gồm bản đồ được phân tích cú pháp!

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>

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.