การแข่งขันกอล์ฟน้ำแข็ง


24

เป้าหมายของการท้าทายนี้คือการเขียนโปรแกรมหรือฟังก์ชั่นที่คืนค่าจำนวนนัดน้อยที่สุดที่จำเป็นในการจบหลักสูตร

อินพุต

  • เลย์เอาต์ของหลักสูตรสามารถส่งผ่านในรูปแบบและรูปแบบที่คุณต้องการ (อ่านจากคอนโซลผ่านเป็นพารามิเตอร์อินพุตอ่านจากไฟล์หรืออื่น ๆ หลายบรรทัดสตริงสตริงอาร์เรย์อักขระสองมิติ / อาร์เรย์ไบต์)
  • ตำแหน่งเริ่มต้นของลูกบอลและหลุมสามารถส่งผ่านเป็นอินพุตได้เช่นกันโดยไม่จำเป็นต้องแยกวิเคราะห์จากอินพุต ในกรณีทดสอบพวกเขาจะรวมอยู่ในหลักสูตรเพื่อให้แน่ใจว่าไม่มีความสับสนเกี่ยวกับตำแหน่งที่แท้จริง
  • คุณสามารถทำการแมปอักขระที่ป้อนเข้ากับสิ่งอื่นได้ตราบใดที่ยังจำได้ว่าเป็นอักขระที่แตกต่าง (เช่นอักขระ ASCII ที่พิมพ์ได้)

เอาท์พุต

  • โปรแกรมจะต้องส่งคืนคะแนนต่ำสุดที่เป็นไปได้ (จำนวนการนัดหยุดงานที่น้อยที่สุดที่จำเป็นในการเข้าถึงรู) สำหรับหลักสูตรใด ๆ ที่ผ่านเป็นอินพุตในรูปแบบที่เหมาะสม (สตริงจำนวนเต็มลอยหรือไฮกุอธิบายผลลัพธ์)
  • หากหลักสูตรเป็นไปไม่ได้ที่จะเอาชนะให้ส่งคืน-1(หรือมูลค่าที่ผิดพลาดอื่น ๆ ที่คุณเลือกซึ่งจะไม่ถูกส่งคืนสำหรับหลักสูตรที่เอาชนะได้)

ตัวอย่าง:

ในตัวอย่างนี้ตำแหน่งจะถูกระบุด้วย 0, X / Y, จากซ้ายไปขวา, จากบนลงล่าง - แต่คุณสามารถใช้รูปแบบใดก็ได้ที่คุณต้องการเนื่องจากผลลัพธ์นั้นเป็นรูปแบบที่ไม่ขึ้นอยู่กับความสมบูรณ์

การป้อนข้อมูล:

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

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

เอาท์พุท:

8

ตัวอย่างหลักสูตร

กฎและเขตข้อมูล

หลักสูตรประกอบด้วยฟิลด์ต่อไปนี้:

  • '@' บอล - จุดเริ่มต้นของหลักสูตร
  • 'o' Hole - เป้าหมายของหลักสูตร
  • '#' กำแพง - ลูกบอลจะหยุดเมื่อกระทบกำแพง
  • '~' น้ำ - ต้องหลีกเลี่ยง
  • '.' ทราย - ลูกบอลจะหยุดบนทรายทันที
  • ' ' Ice - Ball จะยังคงเลื่อนจนกว่าจะพบบางสิ่ง

กฎพื้นฐานและข้อ จำกัด ของเกม:

  • ลูกบอลไม่สามารถเคลื่อนที่ในแนวทแยงมุมได้ทั้งซ้ายขวาขึ้นและลง
  • ลูกบอลจะไม่หยุดที่ด้านหน้าของน้ำเฉพาะด้านหน้ากำแพงบนทรายและในหลุม
    • ภาพลงไปในน้ำไม่ถูกต้อง / เป็นไปไม่ได้
    • ลูกบอลจะอยู่ในหลุมไม่ข้ามมันเหมือนน้ำแข็ง
  • หลักสูตรเป็นรูปสี่เหลี่ยมผืนผ้าเสมอ
  • หลักสูตรนี้ล้อมรอบด้วยน้ำหรือผนังเสมอ (ไม่จำเป็นต้องตรวจสอบขอบเขต)
  • มีเสมอหนึ่งลูกและหนึ่งหลุม
  • ไม่ใช่ทุกหลักสูตรที่สามารถเอาชนะได้
  • อาจมีหลายเส้นทางที่ให้คะแนน (ต่ำสุด) เดียวกัน

ช่องโหว่และเงื่อนไขการชนะ

  • ช่องโหว่มาตรฐานเป็นสิ่งต้องห้าม
  • โปรแกรมจะต้องยุติ
  • คุณไม่สามารถสร้างกฎเพิ่มเติมได้ (การกระแทกลูกบอลจนกระโดดข้ามน้ำเด้งออกมาจากกำแพงกระโดดข้ามทุ่งทรายโค้งรอบมุม ฯลฯ )
  • นี่คือดังนั้นการแก้ปัญหาที่มีจำนวนอักขระน้อยที่สุดจะเป็นผู้ชนะ
  • การแก้ปัญหาจะต้องสามารถจัดการกับกรณีทดสอบที่ให้มาทั้งหมดหากเป็นไปไม่ได้เนื่องจากข้อ จำกัด ของภาษาที่ใช้โปรดระบุว่าในคำตอบของคุณ

กรณีทดสอบ

หลักสูตร # 1 (2 ครั้ง)

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

หลักสูตร # 2 (เป็นไปไม่ได้)

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

หลักสูตร # 3 (3 ครั้ง)

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

หลักสูตร # 4 (2 ครั้ง)

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

หลักสูตร # 5 (เป็นไปไม่ได้)

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

กรณีทดสอบเพิ่มเติม:

https://pastebin.com/Azdyym00


1
ที่เกี่ยวข้อง: หนึ่ง , สอง
AdmBorkBork

หากเราใช้อาร์เรย์แบบสองมิติเป็นอินพุตเราอนุญาตให้ใช้การแมปแบบกำหนดเองสำหรับสัญลักษณ์ได้หรือไม่
Arnauld

@Annauld ไม่แน่ใจว่าฉันทามติปกติเกี่ยวกับที่นี่ แต่ฉันบอกว่ามันตกลงตราบใดที่การป้อนข้อมูลยังคงเป็นที่รู้จัก ฉันได้อัปเดตส่วนอินพุตแล้ว
Manfred Radlwimmer

หากป้อนปลายทางโดยตรงเราสามารถกำหนดให้สถานที่ปลายทางเป็นสัญลักษณ์ 'ทราย' ได้หรือไม่?
l4m2

@ l4m2 แน่นอนว่าวิธีนั้นจะสอดคล้องกับกฎอื่น ๆ ทั้งหมด
Manfred Radlwimmer

คำตอบ:


6

JavaScript (ES6), 174 ไบต์

รับอินพุตในไวยากรณ์curling currying ([x, y])(a)โดยที่xและyเป็นพิกัด 0 ดัชนีของตำแหน่งเริ่มต้นและ[]คือเมทริกซ์ของจำนวนเต็มโดยมี0= ice, 1= wall, 2= sand, 3= hole และ4= water

ส่งคืน0ถ้าไม่มีวิธีแก้ไข

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

ลองออนไลน์!

แสดงความคิดเห็น

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 ไบต์

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

ลองออนไลน์!

ขอบคุณ -41 ไบต์ถึง ovs
-1 ไบต์ขอบคุณ Jonathan Frech


อาจif k+1ไม่เป็นif-~k?
Jonathan Frech


2

C #, 461 418 ไบต์

นี่เป็นเพียงการดำเนินการอ้างอิงที่ไม่แข่งขันเพื่อ (หวังว่า) จะฟื้นความท้าทายนี้

เล่นกอล์ฟโดย 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;}}

Ungolfed

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;
    }
}

ลองออนไลน์


1
เล่นกอล์ฟมากขึ้น: 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 ไบต์) นอกจากนี้คุณสามารถเพิ่มลิงค์ TIOด้วยรหัสทดสอบได้หรือไม่?
Kevin Cruijssen

ขอบคุณสำหรับลิงค์ TIO รหัสที่ฉันให้ไว้ข้างต้นใช้งานไม่ได้ดังนั้นฉันแก้ไขแล้วและเพิ่มจำนวนไบต์อีกสามไบต์ ลองมันออนไลน์415 ไบต์ (คุณจะต้องเพิ่มกรณีทดสอบขนาดใหญ่ของคุณอีกครั้งจาก TIO ปัจจุบันของคุณฉันไม่สามารถวางลิงก์ในความคิดเห็นนี้ได้เนื่องจากลิงก์มีขนาดใหญ่เกินไปกับกรณีทดสอบนั้น .. ; p)
Kevin Cruijssen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.