Buz Golf Mücadelesi


24

Bu zorluğun amacı, verilen bir kursu tamamlamak için gereken en az grev miktarını döndüren bir program veya işlev yazmaktır .

Giriş

  • Kursun düzeni tercih ettiğiniz herhangi bir şekilde ve biçimde geçirilebilir. (konsoldan okunur, bir giriş parametresi olarak iletilir, bir dosyadan veya diğer herhangi bir, çok satırlı dize, dize dizisi, iki boyutlu karakter / bayt dizisinden okunur).
  • Topun ve deliğin başlangıç ​​konumu da girdi olarak geçilebilir, girişten ayrıştırılması gerekmez. Test durumlarına, asıl konum hakkında karışıklık olmadığından emin olmak için kursa dahil edilirler.
  • Girdi karakterlerini, farklı karakterler olarak tanınabildikleri sürece başka bir şeye yeniden eşleyebilirsiniz (örn. Yazdırılabilir ASCII karakterleri).

Çıktı

  • Program, mantıklı bir formatta girdi olarak geçen herhangi bir kurs için mümkün olan en düşük puanı (deliğe ulaşmak için gereken en az grev miktarını) geri döndürmelidir (dize, tamsayı, kayan nokta veya sonucu açıklayan bir haiku)
  • Kursun yenilmesi mümkün değilse, geri dönün -1(veya seçtiğiniz bir dövülebilir kursa geri dönüşü yapılmayan herhangi bir sahte değeri).

Örnek:

Bu örnekte, konumlar 0 tabanlı, X / Y, soldan sağa, yukarıdan aşağıya doğru yazılmıştır - ancak sonuç yine de biçimden bağımsız olduğundan istediğiniz herhangi bir biçimi kullanabilirsiniz.

Giriş:

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

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

Çıktı:

8

Örnek kurs

Kurallar ve alanlar

Tabii aşağıdaki alanlardan oluşabilir:

  • '@' Top - Kursun başlangıcı
  • 'o' Delik - Kursun amacı
  • '#' Duvar - Bir duvara çarptığında top durur
  • '~' Su - Kaçınılması Gerekenler
  • '.' Kum - Top hemen kumun üzerinde duracak
  • ' ' Buz - Top bir şeye değene kadar kaymaya devam edecek

Oyunun temel kuralları ve kısıtlamaları:

  • Top çapraz olarak hareket edemez, yalnızca sola, sağa, yukarı ve aşağı hareket eder.
  • Top suyun önünde, sadece duvarların önünde, kumda ve delikte durmayacaktır.
    • Suya yapılan çekimler geçersiz / imkansız
    • Top delikte kalacak, buzun üzerinde olduğu gibi atlanmayacak
  • Kurs her zaman dikdörtgendir.
  • Kurs her zaman su veya duvarlarla sınırlandırılmıştır (sınır kontrolüne gerek yoktur).
  • Her zaman tam olarak bir top ve bir delik vardır.
  • Tüm kursları geçmek mümkün değildir.
  • Aynı (en düşük) puanla sonuçlanan birden fazla yol olabilir.

Loopholes ve Kazanma Durumu

  • Standart boşluklar yasaktır
  • Programlar sonlandırılmalıdır
  • Ek kurallar koyamazsınız (topa çok sert vurmak su üzerine atlar, duvardan atlar, kumlu alanların üzerinden atlar, köşelerin kıvrımları vs.)
  • Bu , bu yüzden en az sayıda karakter içeren çözüm kazanır.
  • Çözümler, verilen tüm test durumlarını idare edebilmelidir, kullanılmış dilin kısıtlamaları nedeniyle bu mümkün değilse lütfen cevabınızı belirtin.

Test durumları

Kurs # 1 (2 grev)

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

Ders # 2 (mümkün değil)

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

Kurs # 3 (3 grev)

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

Kurs # 4 (2 grev)

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

Kurs 5 (mümkün değil)

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

Daha fazla Test durumu:

https://pastebin.com/Azdyym00


1
İlgili: Bir , İki .
AdmBorkBork

Girdi olarak iki boyutlu bir bayt dizisi kullanırsak, semboller için özel bir eşleme kullanmamıza izin verilir mi?
Arnauld,

@Bu konuda genel bir fikir birliğinin ne olduğundan emin değilim, ancak giriş hala tanınabilir olduğu sürece bunun doğru olduğunu söyleyebilirim. Giriş bölümünü güncelledim .
Manfred Radlwimmer

Hedefi doğrudan girerseniz, varış yerinin 'kum' sembolü olmasını isteyebilir miyiz?
l4m2

@ l4m2 Elbette, bu şekilde diğer tüm kurallarla tutarlı kalacaktı.
Manfred Radlwimmer

Yanıtlar:


6

JavaScript (ES6), 174 bayt

Kıvrık körükleme sözdiziminde girdi alır; ([x, y])(a)burada x ve y , başlangıç ​​konumunun 0 indeksli koordinatlarıdır ve [] , 0= ice, 1= wall, 2= sand, 3= hole ve 4= water olan bir tam sayı matrisidir.

İade 0çözüm olmadığını.

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

Çevrimiçi deneyin!

Yorumlananlar

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 bayt

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

Çevrimiçi deneyin!


Jonathan Frech sayesinde -41 bayt ovs -1 bayt


Could if k+1olamaz if-~k?
Jonathan Frech


2

C #, 461 418 bayt

Bu, sadece (ancak umarım) bu zorluğun canlandırılması için rekabetçi olmayan bir referans uygulamasıdır:

Kevin Cruijssen tarafından Golf

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

Çevrimiçi deneyin


1
Biraz daha golf oynadım: 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 bytes). Ayrıca, test koduyla birlikte bir TIO bağlantısı ekleyebilir misiniz ?
Kevin Cruijssen

TIO bağlantısı için teşekkürler. Yukarıda verdiğim kod işe yaramadı, ben de düzelttim ve üç bayt daha golf oynadım. Çevrimiçi olarak 415 bayt deneyin . (Büyük test durumunuzu tekrar mevcut TIO'nuzdan tekrar eklemeniz gerekecek. Bu
yorumdaki
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.