Zdobądź pojedynczą strzałkę


22

Wprowadzenie

Napisz program lub funkcję, która, biorąc pod uwagę współrzędne miejsca, w którym rzutka wyląduje na tarczy, zwraca wynik tej strzałki. Współrzędne strzałki są podawane jako dwie liczby całkowite, x,ymierzone od środka tarczy do gry z dokładnością do milimetra.

Jak zdobyć rzutkę

Rzutki to gra polegająca na rzucaniu rzutką w okrąg. Rzutki jest podzielony na 20 równych rozmiarów „klinów”. Zaczynając od góry i idąc zgodnie z ruchem wskazówek zegara, sekcje mają wartości 20,1,18,4,13,6,10,15,2,17,3,19,7,16,8,11,4,4,12 , 5. Jeśli twoja strzałka wyląduje w czarnych lub białych częściach któregoś z klinów, uzyskasz wartość wskazaną na zewnątrz tego klina.
oto zdjęcie tarczy do rzutek.


Jeśli jednak twoja strzałka wyląduje w zewnętrznym zielonym / czerwonym pierścieniu tarczy, zdobędziesz podwójną liczbę punktów wskazanych na zewnątrz klina, na który trafiłeś. Podobnie, uderzając w wewnętrzny zielony / czerwony pierścień (ten pomiędzy dwiema białymi / czarnymi sekcjami), zdobywasz trzykrotnie liczbę wskazaną na zewnętrznej stronie klina. Jeśli twoja strzałka trafi w najbardziej wewnętrzny krąg (czerwone oko byka), zamiast tego zdobędziesz 50 punktów i wreszcie, jeśli twoja strzałka trafi w drugie najbardziej wewnętrzne koło (zielony pierścień wokół tarczy), zdobędziesz 25 punktów.

Wymiary pierścieni, mierzone od środka tarczy do rzutek, są następujące:

obraz nie jest skalowany


Bullseye (50): [0mm-6mm)
25:            [6mm-16mm)
Inner Single:  [16mm-99mm)
Triple:        [99mm-107mm)
Outer Single:  [107mm-162mm)
Double:        [162mm-170mm)
Miss (0):       170mm+

Uwaga 1: Dostarczone zdjęcia służą wyłącznie celom ilustracyjnym i nie są skalowane.

Uwaga 2: Podane pomiary są przybliżone i mogą nie być dokładne do prawdziwej tarczy do rzutek.

Uwaga 3: Wszystkie podane pomiary są [inclusive-exclusive). Na potrzeby tego wyzwania nie będziemy się martwić, że strzałki uderzą w drut i odskoczą. Jeśli rzutka wyląduje „na drucie” z jedną z linii promieniowych, to od osoby odpowiadającej decyduje, czy przerwać wiązanie zgodnie z ruchem wskazówek zegara, czy przeciwnie do ruchu wskazówek zegara. Kierunek zerwania musi być zgodny i wskazany.

Uwaga 4: Tarcza jest zawieszona w standardowy sposób, a środek 20 sekcji znajduje się bezpośrednio nad tarczą, a 3 sekcja bezpośrednio pod tarczą.

Wkład

Dwie liczby całkowite reprezentujące x,ywspółrzędne miejsca lądowania strzałki, mierzone w milimetrach, w stosunku do środka tarczy.

Wydajność

Pojedyncza liczba całkowita dla liczby punktów, które zostałyby przyznane rzutce, która wylądowała na podanych współrzędnych.

Próba

0,0     -> 50
2,101   -> 60
-163,-1 -> 22
6,18    ->  1
-6,18   ->  5
45,-169 ->  0
22, 22  ->  4 (if tie-broken clock-wise)
            18(if tie-broken counter-clockwise)
-150,0  ->  11
-150,-1 ->  11

Punktacja

. Wygrywa najmniej bajtów w kodzie źródłowym.

Standardowe luki zabronione .


1
@Shaggy Nie widzę żadnego uzasadnionego powodu, aby to zrobić.
Jonathan Allan

5
@Shaggy Czy możesz wyjaśnić, dlaczego tak powinno być? Osobiście chciałbym, żeby moje rzutki zawsze trafiały w tarczę do rzutek, ale ze względu na wyzwanie, pomyślałem, że najlepiej trzymać się rzeczywistości zamiast fantazji.
mypetlion

1
Sugerowana testów: -150,-1a -150,0które powinny dadzą 11i może być przypadek kant w niektórych przykładach wykonania, jak to jest przejście między theta konwergencję -PI theta = + PI w układzie współrzędnych biegunowych. (Moja pierwsza odpowiedź nie powiodła się w sprawie drugiej).
Arnauld

1
Cholera, x = y = 0 totalnie mnie psuje !! Dobre wyzwanie.
BradC

1
Mam nadzieję, że nie masz nic przeciwko, edytowałem w lepszej wersji drugiego zdjęcia.
BradC

Odpowiedzi:


19

JavaScript (ES7), 137 bajtów

Przyjmuje współrzędne w składni curry (x)(y). Wykorzystuje remis przeciwny do ruchu wskazówek zegara.

x=>y=>(r=(x*x+y*y)**.5)<6?50:r<16?25:(r<99?1:r<107?3:r<162||r<170&&2)*parseInt('b8g7j3h2fa6d4i1k5c9eb'[Math.atan2(y,x)*3.1831+10.5|0],36)

Wypróbuj online!

W jaki sposób?

(x,y)(r,θ)

r=x2+y2
θ=arctan2(y,x)

r

θs

s=θ+π2π×20+12=θ×10π+10+12

340×34010/π

10π3.1831

11

11,8,16,7,19,3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11

11θπθ+π

Wyjście graficzne

Poniższy fragment kodu ES6 rysuje tarczę przy użyciu tej samej logiki, co w kodzie golfowym.


8

JavaScript (ES6) + SVG (HTML5), 53 + 523 51 + 519 507 = 576 570 558 bajtów

document.write`<svg width=345 height=345>`;i=b=Math.PI/10;s=Math.sin(a=-b/2);c=Math.cos(a);f=(r,f,n)=>document.write(`<path d=M172,172L${[172+r*s,172+r*c]}A${[r,r,0,0,1,172+r*t,172+r*d]}z fill=#${f} n=${n} />`);g=(q,r,m,n,i)=>f(q,i?474:`b32`,n*m)+f(r,i?`fff`:`000`,n);[3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11,8,16,7,19].map(n=>{t=s;d=c;s=Math.sin(a+=b);c=Math.cos(a);g(170,162,2,n,i=!i);g(107,99,3,n,i);});document.write`<circle cx=172 cy=172 r=16 fill=#474 n=25 /><circle cx=172 cy=172 r=6 fill=#b32 n=50`
<body onclick=alert(+event.target.getAttribute`n`)>

Wejście odbywa się poprzez kliknięcie myszą, wyjście przez alert. Edycja: Zapisano 12 bajtów, używając nieco więcej przybliżonych kolorów, jak sugeruje @Arnauld.


Myślę, że nikt nie będzie cię winił, jeśli użyjesz b33i 474za czerwony i zielony. :-)
Arnauld

@Arnauld Wystarczająco fair, chociaż b33jest bb3333tak b22(aka bb3322) bliższy oryginałowi be3628.
Neil

7

Zespół Intel 8086/8087, 180 144 142 138 bajtów

Wykorzystuje on koprocesor matematyczny 8087 dla całej arytmetyki triggera i zmiennoprzecinkowej. Wszystkie obliczenia są wykonywane sprzętowo z 80-bitową precyzją zmiennoprzecinkową.

df06 b101 d8c8 df06 af01 d8c8 dec1 d9fa df1e b301 8b16 b301
33c0 81fa aa00 7c03 eb53 9083 fa06 7d05 b032 eb49 9083 fa10
7d05 b019 eb3f 90df 06b7 01df 06b5 01d9 f3df 06b1 01dd d2d9
ebde f9de c9de c1df 1eb3 01a1 b301 bb9c 01d7 83fa 6b7d 0a83
fa63 7c05 b303 eb09 9081 faa2 007c 04b3 02f6 e30b 0810 0713
0311 020f 0a06 0d04 1201 1405 0c09 0e0b 0a00

Zapisany jako MASM MACRO (w zasadzie funkcja), przyjmuje X i Y jako współrzędne i zwraca obliczony wynik w AX. Remis jest zerwany zgodnie z ruchem wskazówek zegara.

MAX_BULL EQU 6
MAX_25   EQU 16
MIN_3X   EQU 99
MAX_3X   EQU 107
MIN_2X   EQU 162
MAX_2X   EQU 170

; cartesian coordinates to radius
; ST = sqrt( X^2 + Y^2 )
; input: X,Y (mem16,mem16)
; output: Radius (mem16)
FCRAD   MACRO X, Y, R
    FILD  Y         ; ST[] = Y
    FMUL  ST,ST     ; ST = y^2 
    FILD  X         ; ST[] = X
    FMUL  ST,ST     ; ST = x^2
    FADD            ; ST = ST + ST1
    FSQRT           ; ST = SQRT(ST)
    FISTP R         ; R = ROUND(ST)
        ENDM

; cartesian coordinates to sector #
; input: X,Y (mem16,mem16)
; output: Sector (mem16)
FCSEC   MACRO X, Y, S
    FILD  Y         ; ST[] = Y
    FILD  X         ; ST[] = X
    FPATAN          ; ST = atan2(Y,X)
    FILD  CTEN      ; ST[] = 10
    FST   ST(2)     ; ST(2) = 10
    FLDPI           ; ST[] = pi
    FDIV            ; ST = 10 / pi
    FMUL            ; ST = A * ST
    FADD            ; ST = ST + 10
    FISTP S         ; S = ROUND(ST)
        ENDM

; score the dart throw
; input: X / Y coordinates (mem16)
; output: Score (AX)
SCORE   MACRO X, Y
        LOCAL IS_BULL, IS_25, IS_3X, IS_2X, MUL_SCORE, DONE
    FCRAD X, Y, FDW         ; FDW = radius(X,Y)
    MOV  DX, FDW            ; DX = FDW = radius
    XOR  AX, AX             ; score is initially 0
    CMP  DX, MAX_2X         ; >= 170 (miss)
    JL   IS_BULL            ; if not, check for bullseye
    JMP  DONE
IS_BULL:
    CMP  DX, MAX_BULL       ; < 6 (inner bullseye)
    JGE  IS_25              ; if not, check for 25
    MOV  AL, 50             ; score is 50
    JMP  DONE
IS_25:
    CMP  DX, MAX_25         ; < 16 (outer bullseye)
    JGE  IS_3X              ; if not, check for triple
    MOV  AL, 25             ; score is 25
    JMP  DONE
IS_3X:
    FCSEC X, Y, FDW         ; FDW = sector(X,Y)
    MOV  AX, FDW            ; load sector # into AX
    MOV  BX, OFFSET SCR     ; load base score table
    XLAT                    ; put base score into AL
    CMP  DX, MAX_3X         ; < 107 (triple upper bounds)
    JGE  IS_2X              ; if not, check for double
    CMP  DX, MIN_3X         ; >= 99 (triple lower bounds)
    JL   IS_2X              ; if not, check for double
    MOV  BL, 3              ; this is triple score
    JMP  MUL_SCORE          ; go forth and multiply
IS_2X:
    CMP  DX, MIN_2X         ; >= 162 (double lower bounds) (> 170 already checked)
    JL   DONE               ; if not, single score
    MOV  BL, 2              ; this is double score
MUL_SCORE:
    MUL  BL                 ; multiply score either 2x or 3x
DONE:
    ENDM

; DATA (place in appropriate segment)
SCR     DB  11,8,16,7,19,3,17,2,15,10,6  ; score table
        DB  13,4,18,1,20,5,12,9,14,11
CTEN    DW  10      ; constant 10 to load into FPU
FDW     DW  ?       ; temp DW variable for CPU/FPU data transfer

Przykładowy program testowy dla PC DOS. Pobierz go tutaj DARTTEST.COM .

INCLUDE DART.ASM            ; the above file
INCLUDE INDEC.ASM           ; generic I/O routines - input int
INCLUDE OUTDEC.ASM          ; generic I/O routines - output int

    FINIT                   ; reset 8087

    MOV  AH, 2              ; display "X" prompt
    MOV  DL, 'X'
    INT  21H
    CALL INDEC              ; read decimal for X into AX
    MOV  X, AX

    MOV  AH, 2              ; display "Y" prompt
    MOV  DL, 'Y'
    INT  21H
    CALL INDEC              ; read decimal for Y into AX
    MOV  Y, AX

    SCORE X, Y              ; AX = SCORE( X, Y )

    CALL OUTDEC             ; display score

X   DW  ?
Y   DW  ?

Wydajność

Przykładowe użycie powyższego programu testowego . Wymagany jest rzeczywisty komputer IBM z 8087, DOSBox lub ulubionym emulatorem.

A>DARTTEST.COM
X: 0
Y: 0
50
A>DARTTEST.COM
X: 2
Y: 101
60
A>DARTTEST.COM
X: -163
Y: -1
22
A>DARTTEST.COM
X: 6
Y: 18
1
A>DARTTEST.COM
X: -6
Y: 18
5
A>DARTTEST.COM
X: 45
Y: -169
0
A>DARTTEST.COM
X: 22
Y: 22
4
A>DARTTEST.COM
X: -150
Y: 0
11
A>DARTTEST.COM
X: -150
Y: 0
11
A>DARTTEST.COM
X: -150
Y: -1
11
A>DARTTEST.COM
X: -7
Y: -6
25
A>DARTTEST.COM
X: -90
Y: 138
24

* Edycje:

  • -36 bajtów poprzez usunięcie instrukcji obcinania zaokrąglenia i stałej 10.5. Tie teraz zerwane zgodnie z ruchem wskazówek zegara.
  • -2 bajty przez usunięcie niepotrzebnego FRNDINT
  • -4 bajty, FMUL używa tego samego źródła / celu

6

Galaretka , 56 bajtów

æA/Æ°_9:18ị“!@umÞẓẓS’Œ?¤
ḅıA<“©Ñckɱȥ‘TṂị“2ı¢¤¢£¡‘¹×>3$?Ç

Monadyczny link akceptujący parę jako listę, [x,y]która daje wynik.
Wykorzystuje rozbijanie remisów zgodnie z ruchem wskazówek zegara.

Wypróbuj online! Lub zobacz zestaw testowy

Uwaga: wersja dynamiczna ma również 56 bajtów

W jaki sposób?

æA/Æ°_9:18ị“!@umÞẓẓS’Œ?¤ - Link 1, segment score: pair [x, y]
  /                      - reduce by:
æA                       -   arc tangent
   Æ°                    - convert from radians to degrees
     _9                  - subtract 9 (align 0 with boundary between 1 & 20)
       :18               - integer divide by 18 (yields a segment index from 0 to 19)
                       ¤ - nilad followed by link(s) as a nilad:
           “!@umÞẓẓS’    -   base 250 number = 2091180117530057584
                     Œ?  -   shortest permutation of natural numbers [1..N] which
                         -   would reside at that index in a list of all permutations of
                         -   those same numbers ordered lexicographically.
                         -   = [18,4,13,6,10,15,2,17,3,19,7,16,8,11,14,9,12,5,20,1]
          ị              - index into (yields the score associated with the segment)

ḅıA<“©Ñckɱȥ‘TṂị“2ı¢¤¢£¡‘¹×>3$?Ç - Main Link: segment score: pair [x, y]
 ı                              - √(-1)
ḅ                               - convert from base = x+iy
  A                             - absolute value = √(x²+y²)
    “©Ñckɱȥ‘                    - code-page index list = [6,16,99,107,162,170]
                                - (i.e. the radial boundaries)
            T                   - list of truthy indexes
             Ṃ                  - minimal value (0 if empty)
               “2ı¢¤¢£¡‘        - code-page index list = [50,25,1,3,1,2,0]
              ị                 - index into
                                - (i.e. get an override score (>3) OR a multiplier (<=3))
                              Ç - call last Link (1) as a monad (get the segment score)
                             ?  - if...
                            $   - ...condition: last two links as a monad:
                          >     -      (override OR multiplier) greater than?
                           3    -      three
                        ¹       - ...then: identity (keep override as is)
                         ×      - ...else: multiply (by multiplier)

4

TI-Basic (TI-84 Plus CE), 147 146 bajtów

Prompt X,Y
abs(X+iY→R
int(E-12+11.5+10π-1R▸Pθ(X,Y→θ
{11,8,16,7,19,3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11
25((R<6)+(R<16))+Ans(θ)(R≥16 and R<170)(1+(R≥162)+2(R≥99 and R<107

Monituje o X i Y na osobnych liniach.

Łamanie remisów przeciwnie do ruchu wskazówek zegara.

TI-Basic to tokenizowany język ; wszystkie użyte tutaj tokeny są jednobajtowe.

Wyjaśnienie:

Prompt X,Y
# 5 bytes, Prompt for X and Y
abs(X+iY→R
# 8 bytes, store distance from origin in R
int(E-12+11.5+10π-1R▸Pθ(X,Y→θ
# 22 bytes, store index in list of point values by polar angle in θ
{11,8,16,7,19,3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11
# 55 bytes, list of point values
25((R<6)+(R<16))+Ans(θ)(R≥16 and R<170)(1+(R≥162)+2(R≥99 and R<107
# 57 56 bytes, calculate the score

Wykorzystuje fakt, że porównania boolowskie TI-Basic zwracają 0 lub 1, dodając je i mnożąc przez wartości punktowe.


3

T-SQL, 392 374 366 bajtów

UPDATE t SET x=1WHERE x=0
SELECT TOP 1IIF(r<16,f,b*f)
FROM(SELECT r=SQRT(x*x+y*y),w=FLOOR(10*ATN2(y,x)/PI()+.5)FROM t)p,
(VALUES(10,11),(9,14),(8,9),(7,12),(6,5),(5,20),(4,1),(3,18),(2,4),(1,13),(0,6),
   (-1,10),(-2,15),(-3,2),(-4,17),(-5,3),(-6,19),(-7,7),(-8,16),(-9,8),(-10,11))s(a,b),
(VALUES(6,50),(16,25),(99,1),(107,3),(162,1),(170,2),(999,0))d(e,f)
WHERE a=w AND r<e

Podziały linii służą do czytelności. Początkowy UPDATEdba o x=y=0problemie, który w przeciwnym razie byłoby wyrzucić błąd z ATN2(), ale nie zmienia wynik.

Dane wejściowe są pobierane za pomocą istniejącej tabeli t , zgodnie z naszymi wytycznymi IO . Ze względu na użycie TOP 1ta tabela powinna zawierać tylko jeden wiersz.

Zasadniczo dołączam do 3 tabel:

  • Tabela p : X i y z tabeli wejściowej t są konwertowane na biegunowe r, a wartość „klina” w reprezentuje liczbę od -11 do dodatniej 11, dla klina punktacji, w który wpadła lotka. „Tie breaker” jest przeciwny do ruchu wskazówek zegara. (Próbowałem ROUND(), który był nieco krótszy, ale dawał niespójny remis.)
  • Tabele s : To jest tabela przeglądowa do konwersji wartości „klina” a na wynik b .
  • Tabela d : To jest tabela przeglądowa, która zwraca obliczenie wyniku na podstawie odległości od centrum. e jest odległością i łączy się z r , i zwraca tylko jeden wiersz na podstawie TOP 1. Wartość f jest albo stałym wynikiem (dla tarczy), albo mnożnikiem dla wyniku klinowego.

EDYCJA : Porzuciłem ORDER BY, wydaje się, że działa bez niego poprawnie, przynajmniej na SQL 2017. Upuściłem też AND y=0na warunek aktualizacji; Testowałem dla wszystkich ywartości całkowitych , zmieniając się, x=0aby x=1nigdy nie zmieniać wyniku.

EDYCJA 2 : Usunąłem kolumnę gz tabeli d , zastąpiłem ją IIF()instrukcją, która zwraca fbezpośrednio (jak na oko) lub f*bzapisała 8 bajtów. Usunięto również spację po TOP 1.


2

Haskell , 198 bajtów

p=pure
a#b=(!!(sum[1|k<-a,k<=b]))
a!b=([6,16,99,107,162,170]#(sqrt$a*a+b*b))[p 50,p 25,id,(*3),id,(*2),p 0]$([pi/20,3*pi/20..6]#(pi+atan2 b a))[11,8,16,7,19,3,17,2,15,10,6,13,4,18,1,20,5,12,9,14,11]

Krawat pęka przeciwnie do ruchu wskazówek zegara. (#)jest funkcją wyszukiwania. Kąt biegunowy służy do indeksowania z listy liczb, zaczynając od atan2punktu odcięcia od 11. Odległość służy do indeksowania z listy funkcji, [const 50, const 25, id, (*3), id, (*2), const 0]a na koniec funkcja ta jest stosowana do liczby, którą poprzednio otrzymaliśmy.

Wypróbuj online!


1

Perl 5 -MMath::Trig':pi' -MMath::Trig':radial' -apl , 166 bajtów

($d,$a)=cartesian_to_cylindrical@F;$_=(1+($d>161||$d<6)+($d<107&&$d>98)*2)*($d<170)*($d<16?25:("6 134 181 205 129 14118 167 193 172 1510"=~/../g)[($a/pi*10+41/2)%20])

Wypróbuj online!

Zajmuje przestrzeń dwóch współrzędnych oddzieloną na STDIN. Łamanie krawatów odbywa się w lewo.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.