Thử thách trên sân băng


24

Mục tiêu của thử thách này là viết một chương trình hoặc chức năng trả về số lần đình công ít nhất cần thiết để hoàn thành một khóa học nhất định.

Đầu vào

  • Bố cục của khóa học có thể được thông qua theo bất kỳ cách phù hợp và định dạng bạn thích. (đọc từ bàn điều khiển, được truyền dưới dạng tham số đầu vào, đọc từ tệp hoặc bất kỳ chuỗi đa chuỗi, chuỗi chuỗi, mảng ký tự / byte hai chiều nào khác).
  • Vị trí bắt đầu của quả bóng và lỗ có thể được chuyển qua làm đầu vào, nó không phải được phân tích cú pháp từ đầu vào. Trong các trường hợp thử nghiệm, chúng được bao gồm trong khóa học để đảm bảo không có sự nhầm lẫn về vị trí thực tế.
  • Bạn có thể ánh xạ lại các ký tự đầu vào sang một thứ khác, miễn là chúng vẫn có thể được nhận dạng là các ký tự riêng biệt (ví dụ: các ký tự ASCII có thể in được).

Đầu ra

  • Chương trình phải trả về số điểm thấp nhất có thể (số lần tấn công ít nhất cần thiết để đạt được lỗ) cho bất kỳ khóa học nào được chuyển dưới dạng đầu vào theo định dạng hợp lý (chuỗi, số nguyên, số float hoặc haiku mô tả kết quả)
  • Nếu khóa học là không thể đánh bại, trả lại -1(hoặc bất kỳ giá trị sai lệch nào khác của sự lựa chọn của bạn sẽ không được trả lại cho một khóa học có thể đánh bại ).

Thí dụ:

Trong ví dụ này, các vị trí được ký hiệu là 0, X / Y, từ trái sang phải, từ trên xuống - nhưng bạn có thể sử dụng bất kỳ định dạng nào bạn thích vì kết quả hoàn toàn không phụ thuộc vào định dạng.

Đầu vào:

###########
#     ....# 
#      ...# 
#  ~    . # 
# ~~~   . # 
# ~~~~    # 
# ~~~~    # 
# ~~~~  o # 
# ~~~~    # 
#@~~~~    # 
###########

Ball (Start-Position): 1/9
Hole (End-Position):   8/7

Đầu ra:

8

Khóa học ví dụ

Quy tắc và lĩnh vực

Khóa học có thể bao gồm các lĩnh vực sau:

  • '@' Bóng - Bắt đầu khóa học
  • 'o' Lỗ - Mục tiêu của khóa học
  • '#' Tường - Bóng sẽ dừng lại khi va vào tường
  • '~' Nước - Phải tránh
  • '.' Cát - Bóng sẽ dừng trên cát ngay lập tức
  • ' ' Ice - Ball sẽ tiếp tục trượt cho đến khi nó chạm vào thứ gì đó

Các quy tắc và hạn chế cơ bản của trò chơi:

  • Quả bóng không thể di chuyển theo đường chéo, chỉ trái, phải, lên và xuống.
  • Quả bóng sẽ không dừng lại trước mặt nước, chỉ trước bức tường, trên cát và trong lỗ.
    • Bắn vào nước là không hợp lệ / không thể
    • Quả bóng sẽ ở trong lỗ, không bỏ qua nó như trên băng
  • Khóa học luôn luôn là hình chữ nhật.
  • Khóa học luôn được bao bọc bởi nước hoặc tường (không cần kiểm tra ranh giới).
  • Luôn luôn có chính xác một quả bóng và một lỗ.
  • Không phải tất cả các khóa học có thể đánh bại.
  • Có thể có nhiều đường dẫn đến cùng một điểm (thấp nhất).

Lỗ hổng và điều kiện chiến thắng

  • Sơ hở tiêu chuẩn bị cấm
  • Các chương trình phải chấm dứt
  • Bạn không thể tạo ra các quy tắc bổ sung (đánh bóng mạnh đến nỗi nó nhảy qua mặt nước, bật ra khỏi tường, nhảy qua các bãi cát, uốn quanh các góc, v.v.)
  • Đây là , vì vậy giải pháp có số lượng nhân vật ít nhất sẽ thắng.
  • Các giải pháp phải có khả năng xử lý tất cả các trường hợp kiểm tra được cung cấp, nếu điều này là không thể do hạn chế của ngôn ngữ được sử dụng, vui lòng ghi rõ trong câu trả lời của bạn.

Các trường hợp thử nghiệm

Khóa học số 1 (2 lần đình công)

####
# @#
#o~#
####

Khóa 2 (không thể)

#####
#@  #
# o #
#   #
#####

Khóa 3 (3 lần đình công)

~~~
~@~
~.~
~ ~
~ ~
~ ~
~ ~
~.~
~o~
~~~

Khóa 4 (2 lần đình công)

#########
#~~~~~~~#
#~~~@~~~#
##  .  ##
#~ ~ ~ ~#
#~. o .~#
#~~~ ~~~#
#~~~~~~~#
#########

Khóa 5 (không thể)

~~~~~~~
~...  ~
~.@.~.~
~...  ~
~ ~ ~.~
~ . .o~
~~~~~~~

Thêm trường hợp kiểm tra:

https://pastebin.com/Azdyym00


1
Liên quan: Một , Hai .
admBorkBork

Nếu chúng ta sử dụng một mảng byte hai chiều làm đầu vào, chúng ta có được phép sử dụng ánh xạ tùy chỉnh cho các ký hiệu không?
Arnauld

@Arnauld Không chắc chắn sự đồng thuận thông thường liên quan đến vấn đề đó ở đây là gì, nhưng tôi sẽ nói nó ổn miễn là đầu vào vẫn có thể nhận ra được. Tôi đã cập nhật phần Đầu vào .
Manfred Radlwimmer

Nếu nhập trực tiếp đích đến, chúng ta có thể yêu cầu điểm đến là biểu tượng 'cát' không?
l4m2

@ l4m2 Chắc chắn, theo cách đó nó sẽ phù hợp với tất cả các quy tắc khác.
Manfred Radlwimmer

Câu trả lời:


6

JavaScript (ES6), 174 byte

Đưa đầu vào trong cong tách lạng bộ cú pháp ([x, y])(a), nơi xy là tọa độ 0-lập chỉ mục của vị trí bắt đầu và một [] là một ma trận các số nguyên, với 0= băng, 1= tường, 2= cát, 3= lỗ và 4= nước

Trả về 0nếu không có giải pháp.

p=>a=>(r=F=([x,y],n,R=a[y],c=R[x])=>R[c&(R[x]=4)|n>=r||[-1,0,1,2].map(d=>(g=_=>(k=a[v=Y,Y+=d%2][h=X,X+=~-d%2])||g())(X=x,Y=y)>3?0:k>2?r=-~n:F(k>1?[X,Y]:[h,v],-~n)),x]=c)(p)|r

Hãy thử trực tuyến!

Đã bình luận

p => a => (                       // given the starting position p[] and the matrix a[]
  r =                             // r = best result, initialized to a non-numeric value
  F = (                           // F = recursive function taking:
    [x, y],                       //   (x, y) = current position
    n,                            //   n = number of shots, initially undefined
    R = a[y],                     //   R = current row in the matrix
    c = R[x]                      //   c = value of the current cell
  ) =>                            //
    R[                            // this will update R[x] once the inner code is executed
      c & (R[x] = 4) |            //   set the current cell to 4 (water); abort if it was
      n >= r ||                   //   already set to 4 or n is greater than or equal to r
      [-1, 0, 1, 2].map(d =>      //   otherwise, for each direction d:
        (g = _ => (               //     g = recursive function performing the shot by
          k = a[                  //         saving a backup (h, v) of (X, Y)
            v = Y, Y += d % 2][   //         and updating (X, Y) until we reach a cell
            h = X, X += ~-d % 2]) //         whose value k is not 0 (ice)
          || g()                  //   
        )(X = x, Y = y)           //     initial call to g() with (X, Y) = (x, y)
        > 3 ?                     //     if k = 4 (water -> fail):
          0                       //       abort immediately
        :                         //     else:
          k > 2 ?                 //       if k = 3 (hole -> success):
            r = -~n               //         set r to n + 1
          :                       //       else:
            F(                    //         do a recursive call to F():
              k > 1 ?             //           if k = 2 (sand):
                [X, Y]            //             start the next shots from the last cell
              :                   //           else (wall):
                [h, v],           //             start from the last ice cell
              -~n                 //           increment the number of shots
            )                     //         end of recursive call
      ), x                        //   end of map(); x = actual index used to access R[]
    ] = c                         // restore the value of the current cell to c
)(p) | r                          // initial call to F() at the starting position; return r

5

Python 3 , 273 byte

def p(g,c,d,k=0):
	while 1>k:c+=d;k=g.get(c,9)
	return-(k==2)or c-d*(k==3)
def f(g):
	c={q for q in g if g.get(q,9)>4};I=0;s=[c]
	while all(g.get(q,9)-4for q in c):
		c={k for k in{p(g,k,1j**q)for k in c for q in range(4)}if-~k}
		if c in s:return-1
		s+=[c];I+=1
	return I

Hãy thử trực tuyến!

-41 byte nhờ vào
các byte -1 byte nhờ Jonathan Frech


Không thể if k+1được if-~k?
Jonathan Frech


2

C #, 461 418 byte

Đây chỉ là một triển khai tham chiếu không cạnh tranh để (hy vọng) làm sống lại thách thức này:

Được chơi bởi Kevin Cruijssen

int P(string[]C){int w=C[0].Length,i=0,l=c.Length;var c=string.Join("",C);var h=new int[l];for(var n=new List<int>();i<l;n.Add(i++))h[i]=c[i]!='@'?int.MaxValue:0;for(i=1;;i++){var t=n;n=new List<int>();foreach(int x in t){foreach(int d in new[]{-1,1,-w,w}){for(int j=x+d;c[j]==' ';j+=d);if(c[j]=='#'&h[j-d]>s){h[j-d]=s;n.Add(j-d);}if(c[j]=='.'&h[j]>s){h[j]=s;n.Add(j);}if(c[j]=='o')return s;}}if(n.Count<1)return -1;}}

Bị đánh cắp

int IceGolf(string[] course)
{
    // Width of the course
    int w = course[0].Length;

    // Course as single string
    var c = string.Join("", course);

    // Array of hits per field
    var hits = new int[c.Length];

    // Fields to continue from
    var nextRound = new List<int>();

    // Initialize hits
    for (int i = 0; i < hits.Length; i++)
    {
        if (c[i] != '@')
            // All fields start with a high value
            hits[i] = Int32.MaxValue;
        else
        {
            // Puck field starts with 0
            hits[i] = 0;
            nextRound.Add(i);
        }
    }

    for (int s = 1; ; s++)
    {
        // clear the fields that will be used in the next iteration
        var thisRound = nextRound;
        nextRound = new List<int>();

        foreach (int i in thisRound)
        {
            // test all 4 directions
            foreach (int d in new[] { -1, 1, -w, w })
            {
                int j = i+d;

                // ICE - slide along
                while (c[j] == ' ')
                    j += d;

                // WALL - stop on previous field
                if (c[j] == '#' && hits[j-d] > s)
                {
                    hits[j-d] = s;
                    nextRound.Add(j-d);
                }

                // SAND - stop
                if (c[j] == '.' && hits[j] > s)
                {
                    hits[j] = s;
                    nextRound.Add(j);
                }

                // HOLE return strikes
                if (c[j] == 'o')
                    return s;
            }
        }

        // No possible path found
        if (nextRound.Count == 0)
            return -1;
    }
}

Dùng thử trực tuyến


1
Chơi gôn nhiều hơn một chút: int P(string[]C){int w=C[0].Length,i=0,l=c.Length;var c=string.Join("",C);var h=new int[l];for(var n=new List<int>();i<l;n.Add(i++))h[i]=c[i]!='@'?int.MaxValue:0;for(i=1;;i++){var t=n;n=new List<int>();foreach(int x in t){foreach(int d in new[]{-1,1,-w,w}){for(int j=x+d;c[j]==' ';j+=d);if(c[j]=='#'&h[j-d]>s){h[j-d]=s;n.Add(j-d);}if(c[j]=='.'&h[j]>s){h[j]=s;n.Add(j);}if(c[j]=='o')return s;}}if(n.Count<1)return -1;}}(418 byte). Ngoài ra, có lẽ bạn có thể thêm một liên kết TIO với mã kiểm tra?
Kevin Cruijssen

Cảm ơn các liên kết TIO. Mã tôi cung cấp ở trên không hoạt động, vì vậy tôi đã sửa nó và chơi thêm ba byte. Hãy thử trực tuyến 415 byte . (Bạn sẽ phải làm lại thêm trường hợp thử nghiệm khổng lồ của mình một lần nữa từ TIO hiện tại của bạn tôi không thể dán liên kết trong nhận xét này vì liên kết là quá lớn với trường hợp thử nghiệm ..; p.)
Kevin Cruijssen
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.