Rzutki spotykają Codegolfa

11

Myślę, że każdy zna rzutki, niektórzy ludzie nie rozumieją wyniki więc dla tych ludzi, tutaj jest link przydatne w tej sprawie.

Tablica

Tarcza do gry w rzutki można porównać do kawałka ciasta podzielonego na 20 części. Każdy kawałek jest podzielony na 4 sekcje.

  • mały pierścień zewnętrzny zwany podwójnym (punkty x2)
  • duży pierścień zwany singlem (punkty x1)
  • kolejny mały pierścień o nazwie potrójny (punkty x3)
  • kolejny duży pierścień zwany singlem (punkty x1)

Na środku planszy są jeszcze 2 pierścienie, zielony i czerwony (klasyczna tablica)

  • Czerwony pierścień, środek planszy zwany bullseye lub double bull i jest dobry na 50 punktów. Ten jest liczony jako podwójny i dlatego może się przy nim kasować.
  • Zielony pierścień, zwany bykiem, pojedynczym bykiem lub po prostu 25 i liczy się jako pojedynczy.

Wyzwanie

Znajdź wszystkie możliwości realizacji transakcji za pomocą 3 rzutek lub mniej.
Użytkownik może wprowadzić liczbę całkowitą i będziesz musiał sprawdzić, czy to możliwe, aby uzyskać wynik do 0 za pomocą 3 rzutek (lub mniej).

Przykłady

Przykład 1:

Input: 170  
Output: T20, T20, Bullseye

Przykład 2:

Input: 6  
Output: D3;  
        S3,S1,D1;  
        S2,D2;  
        S2,S2,D1;  
        D2,D1;  
        S4,D1;  
        D1,D1,D1;  
        S1,S1,D2;  
        T1,S1,D1;

Przykład 3:

Input: 169
Output: No possible checkout!

Zasady

  • Podstawowa zasada rzutki, musisz zakończyć podwójną (zewnętrzny pierścień planszy lub dziesiątkę)
  • Brak wykorzystania zasobów zewnętrznych.
  • Dozwolone jest twarde kodowanie możliwych transakcji, ale pamiętaj, że to kodegolf, nie spowoduje to, że Twój kod będzie krótki;)
  • Komórki do trafienia zostaną wyświetlone w formacie C + N, gdzie C = T dla potrójnego, D dla podwójnego i S dla pojedynczego.
    • bullseye można nazwać bullseye lub DB, DBull lub coś podobnego.

Możliwe kasy

Na początek najwyższa możliwa kasa to 170.
169 38,166,165,163,162,159 nie jest możliwe w 3 rzutkach.
Najniższa możliwa kasa to 2.

Dodatkowo

Nie jest to wymagane, dodaj możliwość pokazania wszystkich możliwych transakcji dla wszystkich wyników. Po prostu zastanawiam się, ile kombinacji jest możliwych: P

Zwycięzcą zostanie ten z najkrótszym kodem.

Szczęśliwego kodowania.

Teun Pronk
źródło
1
Pierwsza wymieniona reguła jest niepoprawna (i unieważnia pierwszy przykład), ponieważ możesz także ukończyć na byku. Pomocne byłoby wyjaśnienie, czy oczekujesz programu, funkcji, czy obu; i ile jest elastyczności w formacie wyjściowym.
Peter Taylor
1
@PeterTaylor Wyjaśnię to bardziej, ponieważ zielony pierścień i czerwony pierścień pośrodku nazywa się Single bull and bullseye lub double bull.
Teun Pronk
1
+1 za doskonałe pytanie. Jest to rodzaj rzeczywistego problemu, który komputery potrafią rozwiązać. Możesz rzucić 6 w S2 D1 D1, którego brakuje w twoim przykładowym wyjściu (powinno tam być, chyba że uważasz S2 S2 D1 i D1 D1 D1 za takie same, ale są wyraźnie wymienione jako różne.) Istnieje kilka drobne niejasności dotyczące formatu wyjściowego i liczenia wyników, które omówię w mojej odpowiedzi.
Level River St

Odpowiedzi:

2

Znaki C ++ 248/228 230/214

Rev 0:

int f(int s){char m[4]="SDT";int t=0;for(int b=2;b<77;b+=1+(b==62)*12)for(int a=2;a<77;a+=1+(a==62)*12){int c=s-a/3*(a%3+1)-b/3*(b%3+1);if(((c+38)/40==1)|(c==50)&&(c%2==0)&(a>=b)){printf("%c%d %c%d D%d\n",m[a%3],a/3,m[b%3],b/3,c/2);t++;}}return t;}

Rev 1. Zapisano niektóre znaki, deklarując wszystkie zmienne na raz i eliminując niepotrzebne nawiasy. Okazuje się, że w C ++ cała logika i bitowa i / lub mają niższy priorytet niż porównania.

int f(int s){char m[4]="SDT";int a,b,c,t=0;for(b=2;b<77;b+=1+(b==62)*12)for(a=2;a<77;a+=1+(a==62)*12){c=s-a/3*(a%3+1)-b/3*(b%3+1);if(c>1&c<41|c==50&&c%2==0&a>=b){printf("%c%d %c%d D%d\n",m[a%3],a/3,m[b%3],b/3,c/2);t++;}}return t;}

Zrobiłem funkcję, a nie program, jak inni. Zwraca całkowitą liczbę znalezionych możliwości. Można go zmniejszyć z 230 do 214 znaków, eliminując funkcję sumowania.

Wyjściowa próbka, wynik 6:

wprowadź opis zdjęcia tutaj

Liczę różne pierwsze i drugie strzałki jako tę samą kombinację, jak zrobiła PO (przykład:

T1 S1 D1 = S1 T1 D1), chociaż kosztuje to dodatkowe 7 znaków. Zawsze najpierw wypisuję wyższy wynik (ignorując podwojenie i potrzaskiwanie), ponieważ uważam, że jest to bardziej odpowiednie dla gracza (który może zmienić swoją strategię, jeśli spudłuje z pierwszą rzutką.) Z tego samego powodu wymieniam rzutki w kolejności zgodnie z druga strzałka. Uważam, że trzecia strzałka jest całkowicie odmienna od pozostałych dwóch, dlatego uważam D1 D2 i D2 D1 za różne przypadki, podczas gdy PO ma je wymienione jako takie same.

Dzięki temu systemowi liczenia otrzymuję 42336 całkowitych możliwości , takich samych jak mmumboss. Licząc różne pierwsze i drugie strzałki jako różne kombinacje, liczba ta wzrasta do 83349.

Nie użyłem pętli for z zestawami, jak zrobili to inni (jestem całkiem nowy w C ++ i nawet nie wiem, czy to możliwe). Zamiast tego nadużywam warunku przyrostu pętli, aby skakać z 20 do 25 Używam zmiennej z pojedynczej pętli, aby zakodować wszystkie możliwe wyniki dla pojedynczej strzałki, takie jak: S1 D1 T1 S2 D2 T2 itd. Z modułem i podziałem do dekodowania. Pozwala to zaoszczędzić na szczegółowości deklarowania większej liczby pętli, chociaż komplikuje to wyrażenia.

Wynikiem tego jest to, że nieużywana strzałka jest wyświetlana jako T0, ale myślę, że jasne jest, co to znaczy, zwłaszcza że (biorąc pod uwagę różne pierwszą i drugą strzałkę jako tę samą kombinację) byłem w stanie zgrupować je wszystkie na początku mojej produkcji.

Wersja bez golfa tutaj. Kilka innych funkcji polega na selektywnym korzystaniu z operatorów & i && z | w taki sposób, aby nadać porządek pierwszeństwa bez nawiasów.

int f(int s)
{
  char m[4] = "SDT";
  int a,b,c,t=0;
    for (b = 2; b < 77; b += 1 + (b == 62) * 12)
      for (a = 2; a < 77; a += 1 + (a == 62) * 12){
        c = s - a / 3 * (a % 3 + 1) - b / 3 * (b % 3 + 1);
        if (c>1 & c<41 | c == 50 && c % 2 == 0 & a >= b){
          printf("%c%d %c%d D%d\n", m[a % 3], a / 3, m[b % 3], b / 3, c / 2);
          t++;
        }
     }
   return t;
}
Level River St
źródło
204 bajty
ceilingcat
4

MATLAB ( 299 249 241 znaków)

To moja pierwsza poważna gra w golfa. Moja pierwsza próba (136 znaków) daje poprawny wynik, ale nie z poprawnym formatowaniem. Daje wszystkie możliwości, patrząc na liczbę punktów dla każdej strzałki. Oznacza to, że pojedyncze 20 i podwójne 10 mają osobne wpisy, jednak oba są wyświetlane jako 20. Oczywiście ostatnia rzutka jest zawsze podwójna.

function f(x);u=[1:20 25].';y=[u;2*u; 3*u(1:end-1)];v=combvec([combnk(y,2);[y y];[zeros(62,1) y];[0 0]].',y(22:42).').';v(sum(v,2)==x,:)

W drugiej próbie poprawiono formatowanie, co oczywiście zwiększyło liczbę znaków:

function f(x);h=.1;u=h+[1:20,25].';y=[u;2*u;3*u(1:20)];v=combvec([combnk(y,2);[y,y];h*ones(62,1),y];[h,h]].',y(22:42).').';t='SDT';r=@fix;strrep(arrayfun(@(x)[t(int8((x-r(x))/h)),num2str(h*r(x)/(x-r(x)))],v(sum(r(v),2)==x,:),'un',0),'S0','')

Poprawiono z 299 do 249 znaków, jednocześnie poprawiając formatowanie wyjściowe. W tej ulepszonej wersji dane wyjściowe dla przykładowych przypadków to:

f (170):

'T20'    'T20'    'D25'

f (6):

'S1'    'S3'    'D1'
'S1'    'T1'    'D1'
'S2'    'D1'    'D1'
'S2'    'S2'    'D1'
'D1'    'D1'    'D1'
''      'S4'    'D1'
''      'D2'    'D1'
'S1'    'S1'    'D2'
''      'S2'    'D2'
''      'D1'    'D2'
''      ''      'D3'

f (169):

Empty cell array: 0-by-3

Dodatkowy:

Według moich umiejętności obliczeniowych istnieje 42336 możliwości zakończenia gry w rzutki.

mmumboss
źródło
Wynik powinien pokazywać, która komórka ma trafić, więc w pierwszej 60 60 50powinno być T20 T20 Bullseye. Wyjaśnię to bardziej w pytaniu. Fajnie się dzieje, prawie tam :)
Teun Pronk
1
Tak, sam już to zauważyłem. To pierwsza niedokończona próba. ;)
mmumboss
oops przepraszam lol, byłem ciekawy kodu i wynik nie przeczytałem historii powyżej xD
Teun Pronk
Tak powinno być lepiej. Jedyne, co mogę wymyślić, to to, że byk jest nadal wyświetlany jako 25. Ale mam nadzieję, że to jest w porządku, ponieważ w przeciwnym razie nie ma innej możliwości, jak napisać to na stałe, co po prostu nie jest zabawne.
mmumboss
Pojedynczy byk jako 25 jest rzeczywiście do przyjęcia, to jedyny sposób, w jaki możesz rzucić 25 za pomocą 1 rzutki
Teun Pronk
2

Rubin (260 znaków)

„Ten ostatni powinien być podwójny” to brakujący element - nie mogłem zrozumieć, dlaczego 168 nie powinno mieć wyników ...:

c=->n,d=3{d=d-1;r=[];n==0?[r]:(d>=0&&n>0?(o='0SDT';((1..20).map{|p|(1..3).map{|h|c.(n-p*h,d).map{|m|r<<["#{o[h]}#{p}"]+m}}};c.(n-50,d).map{|m|r<<['DB']+m};c.(n-25,d).map{|m|r<<[?B]+m})):1;r.select{|*i,j|j[?D]}.tap{|x|d!=2?1:puts(x.map{|i|"#{i.join(?,)};"})})}

c. (170)

T20,T20,DB;

c. (6)

S1,S1,D2;
S1,T1,D1;
S1,S3,D1;
D1,D1,D1;
D1,S2,D1;
D1,D2;
T1,S1,D1;
S2,D1,D1;
S2,S2,D1;
S2,D2;
D2,D1;
S3,S1,D1;
D3;
S4,D1;
Uri Agassi
źródło
1

Python 2.7 (270 znaków)

Nie jestem pewien, czy python zezwoli na jedną linijkę, ale on ma trzy.

def f(n):
 a={'%s%s'%('0SDT'[i],n):n*i for n in range(1,21)+[25] for i in [1,2,3] if n*i<75};a['']=0
 for r in [' '.join(h[:3]) for h in [(x,y,z,a[x]+a[y]+a[z]) for x in a for y in a for z in {k:a[k] for k in a if 'D' in k}] if h[3]==n and len(h[0])<=len(h[1])]:print r

Lub 278+ znaków z odpowiednim komunikatem „No Checkout” (np. 290 tutaj):

def f(n):
 a={'%s%s'%('0SDT'[i],n):n*i for n in range(1,21)+[25] for i in [1,2,3] if n*i<75};a['']=0;
 for r in [' '.join(h[:3]) for h in [(x,y,z,a[x]+a[y]+a[z]) for x in a for y in a for z in {k:a[k] for k in a if 'D' in k}] if h[3]==n and len(h[0])<=len(h[1])] or ['No Checkout']:print r

No to ruszamy:

f (170)

T20 T20 D25

f (6)

S3 S1 D1
S2 S2 D1
S2 D1 D1
S1 S3 D1
S1 S1 D2
S1 T1 D1
 S2 D2
 S4 D1
  D3
 D2 D1
 D1 D2
T1 S1 D1
D1 S2 D1
D1 D1 D1

f (169)

No Checkout

Rzeczy, z których nie jestem zadowolony:

for x in a for y in a for z in

To ponad 10% całości. Czy istnieje bardziej kompaktowy sposób bez narzędzi itert itp?

and len(h[0])<=len(h[1])

Służy to do zapobiegania duplikatom w przypadku wykończenia dwoma rzutkami (np. [”,„ S1 ”,„ D1 ”] i [„ S1 ”,„ ”,„ D1 ”]). Uważam, że kolejność ma znaczenie (hej - ostatnia strzałka musi być podwójna, więc jasne jest, że kolejność ma znaczenie), ale rzut nie jest specjalnym przypadkiem.

psion5mx
źródło
1

05AB1E , 43 bajty

20L25ª3Lâ¨Ðʒθ<}Uã«XâXìε˜2ô}ʒPOQ}εε`…TSDsèì

Dość powolny. Wyjście jako lista list lub pusta lista, jeśli nie jest możliwe zakończenie. Moje byki to S25i D25; jeśli nie jest to dozwolone, mogę to zmienić.

Wypróbuj online lub zweryfikuj kilka przypadków testowych jednocześnie .

Wyjaśnienie:

Istnieje kilka kroków:

1) Utwórz listę wszystkich możliwych pojedynczych, podwójnych i potrójnych rzutek:

20L         # Create a list in the range [1,20]
   25ª      # Append 25 to this list
      3L    # Create a list in the range [1,3]
        â   # Create all possible pairs of these two lists
         ¨  # Remove the last pair (which is the Triple Bull)
            # Now we have a list of all possible darts:
            #  [[1,1],[1,2],[1,3],[2,1],...,[20,3],[25,1],[25,2]]

2) Zdobądź wszystkie możliwe finiszery (kończące się podwójnym) maksymalnie 3 rzutkami:

Ð           # Triplicate this list
 ʒ  }       # Filter the top copy by:
  θ         #  Where the last value
   <        #  Decremented by 1 is truthy (==1), so all doubles
     U      # Pop this filtered list of doubles, and store it in variable `X`
 ã          # Create all possible pairs of the list of darts with itself
  «         # Merge it with the list of darts
            # We now have a list containing all possible variations for 1 or 2 darts
 Xâ         # Then create all possible pairs of these with the doubles from variable `X`
   Xì       # And prepend the doubles themselves as well
            # Now we have all possible variations of 1 double; 1 dart + 1 double;
            # or 2 darts + 1 double
     ε   }  # Map each to:
      ˜     #  Deep-flatten the list
       2ô   #  And split it into parts of size 2
            #  (this is to convert for example a 2 darts + 1 double from
            #   [[[20,3],[5,1]],[1,2]] to [[20,3],[5,1],[1,2]])
            # Now we have a list of all possible finishers of up to 3 darts

3) Zachowaj tylko te, dla których całkowity wynik jest równy całkowitej liczbie wejściowej:

ʒ   }       # Filter this list by:
 P          #  Get the product of each inner-most lists
            #   i.e. [[20,3],[5,1],[1,2]] → [60,5,2]
  O         #  Take the sum of those
            #   i.e. [60,5,2] → 67
   Q        #  Check if this value is equal to the (implicit) input-integer
            # Now we only have the finishers left with a total value equal to the input

4) Konwertuj dane na ładnie wydrukowaną listę wyników (tzn. [[20,3],[5,1],[1,2]]Stanie się ["T20","S5","D2"]):

ε           # Map each of the remaining finishers of up to 3 darts to:
 ε          #  Map each inner list to:
  `         #   Push both values separately to the stack ([20,3] → 20 and 3)
   TSD     #   Push string "TSD"
       s    #   Swap to get the integer for single/double/triple at the top of the stack
        è   #   Use it to index into the string
            #   NOTE: 05AB1E has 0-based indexing with automatic wraparound,
            #   so the triple 3 will wrap around to index 0 for character "T"
         ì  #   Prepend this character in front of the dart-value
            # (after which the result is output implicitly as result)
Kevin Cruijssen
źródło
0

Kotlin , 254 bajty

Uwaga: algorytm oparty jest na odpowiedzi C ++ na poziomie River St.

{s:Int->val m="SDT"
var c=0
val r=(2..62).toList()+listOf(75,76)
for(t in r)for(o in r){val l=s-o/3*(o%3+1)-t/3*(t%3+1)
if((l>1&&l<41||l==50)&&l%2==0&&o>=t){println("${m[o%3]}${o/3},${m[t%3]}${t/3},D${l/2}")
c++}}
if(c<1)println("No possible checkout!")}

Wypróbuj online!

JohnWells
źródło