Giocare a golf su una mappa da golf

Aug 17 2020

Data una distanza in metri come numero intero \$60\le d \le 260\$, restituisce il numero di mazze che possono essere utilizzate in base al seguente grafico arbitrario, dove entrambi \$min\$e \$max\$ sono inclusi:

 club           | min | max
----------------+-----+-----
 Driver         | 200 | 260
 3-wood         | 180 | 235
 5-wood         | 170 | 210
 3-iron         | 160 | 200
 4-iron         | 150 | 185
 5-iron         | 140 | 170
 6-iron         | 130 | 160
 7-iron         | 120 | 150
 8-iron         | 110 | 140
 9-iron         |  95 | 130
 Pitching Wedge |  80 | 115
 Sand Wedge     |  60 |  90

Appunti

  • I nomi dei club sono forniti solo a scopo informativo.

  • Ovviamente la scelta del club dipende da molti altri parametri. Ad esempio, il Sand Wedge è progettato per fuggire da un bunker di sabbia. Ma ai fini di questa sfida, conta solo la distanza.

  • Questa è senza dubbio una sfida da golf di codice .

Esempio

Per \$d=130\$, possiamo scegliere 6 ferro , 7 ferro , 8 ferro o 9 ferro , quindi la risposta attesa è \$4\$.

Casi test

Input Output
60    1
79    1
80    2
93    1
105   2
110   3
116   2
129   3
130   4
200   4
201   3
235   2
260   1

O come elenchi:

Input : 60, 79, 80, 93, 105, 110, 116, 129, 130, 200, 201, 235, 260
Output: 1, 1, 2, 1, 2, 3, 2, 3, 4, 4, 3, 2, 1

Risposte

17 640KB Aug 17 2020 at 23:02

codice macchina x86-16, 47 42 byte

00000000: be14 01b3 01b1 0bad 3ad0 7205 3ad4 7701  ........:.r.:.w.
00000010: 43e2 f4c3 505a 5feb 6e73 78d2 8282 8c8c  C...PZ_.nsx.....
00000020: 9696 a0a0 aaaa b4b9 c8c8                 ..........

Inserzione:

BE 0114     MOV  SI, OFFSET CHART   ; SI point to distance chart 
B3 01       MOV  BL, 1              ; start counter at 1 
B1 0B       MOV  CL, 11             ; loop 11 clubs 
        SCORE_LOOP: 
AD          LODSW                   ; load AL = min, AH = max 
3A D0       CMP  DL, AL             ; is d less than min? 
72 05       JB   DONE               ; if so, continue 
3A D4       CMP  DL, AH             ; is d greater than max? 
77 01       JA   DONE               ; if so, continue 
43          INC  BX                 ; otherwise increment counter 
        DONE: 
E2 F4       LOOP SCORE_LOOP         ; loop through end of chart 
C3          RET                     ; return to caller
                 
CHART   DB  80,90,95,235,110,115,120,210,130,130,140,140
        DB  150,150,160,160,170,170,180,185,200,200

Funzione richiamabile, input din DX, output in BL.

Nessuna compressione (i dati sono solo 24 22 byte in binario comunque) solo un confronto tra tabelle.

Modifica: enormi oggetti di scena a @SE: smettila di licenziare i bravi ragazzi per riorganizzare l'elenco ed eliminare la necessità di compensare il dvalore, risparmiando 5 byte !

Il programma di test viene eseguito:

Versione alternativa, 50 byte

BB 0501     MOV  BX, 0501H          ; init counter to 1 in BL and  
BF 556D     MOV  DI, 0556DH         ; magic number to 0x5556D in BH:DI 
BE 011C     MOV  SI, OFFSET CHART   ; SI point to transition table 
B1 16       MOV  CL, 22             ; loop 22 transitions 
        SCORE_LOOP: 
AC          LODSB                   ; load AL = next transition 
3A C2       CMP  AL, DL             ; is d less than? 
77 0B       JA   EXIT               ; if not, end 
D0 EF       SHR  BH, 1              ; cascade bit shift high word into CF 
D1 DF       RCR  DI, 1              ; bit shift lsb into CF 
43          INC  BX                 ; increment counter 
72 02       JC   NEXT               ; if CF was a 1, continue to next 
4B          DEC  BX                 ; otherwise subtract 2 
4B          DEC  BX 
        NEXT: 
E2 F0       LOOP SCORE_LOOP         ; keep looping 
        EXIT: 
C3          RET 
                 
CHART   DB 80,91,95,110,116,120,130,131,140,141,150,151,160,161,170,171,180,186,200,201,211,236

Questo è fortemente ispirato dalla risposta di Jonathan Allan . Questo utilizza una tabella di valori in dcui il numero di mazze transita o +1o -1, e un numero magico binario corrispondente di 0x5556ddove a 1indica un cambiamento positivo e 0indica un cambiamento negativo.

Sfortunatamente, questo non aiuta molto qui poiché la codifica della tabella originale è di 24 byte contro le 22 transizioni più il numero magico di 3 byte , quindi è davvero più grande. È stato divertente provarci!

12 ovs Aug 17 2020 at 22:05

Python 3 , 71 byte

lambda n:sum(a<=n/5<=b for a,b in zip(b'($" ',b'4/*(%" '))

Provalo online!

Le stringhe di byte contengono alcuni non stampabili, la loro forma con escape è b'($" \x1e\x1c\x1a\x18\x16\x13\x10\x0c'e b'4/*(%" \x1e\x1c\x1a\x17\x12'.


Python 3 , 71 byte

lambda n:sum(b>n-a*5>-1for a,b in zip(b'($" ',b'=8))$$$'))

Provalo online!


Python 3.8 , 90 86 byte

lambda x:-~sum([79<x<91,94<x<236,-1<(a:=x-110)<6,9<a<101,69<a<76,a/10in{2,3,4,5,6,9}])

Provalo online!

L'ultima condizione può anche essere scritta come a%10<1<a/10<7,a==90alla stessa lunghezza.

7 JonathanAllan Aug 17 2020 at 20:59

Gelatina , 25 byte

“Ḳœẹ“rɓ?’ḃ5×5“ZO‘;"Ä⁸>§I‘

Un programma completo che stampa il risultato (o un Link monadico che restituisce un elenco di un singolo elemento).

Provalo online! Oppure guarda la suite di test .

Come?

Per qualsiasi input valido, in \$[60,260]\$siamo in grado di utilizzare almeno un club. Per ogni yardage, in \$[61,260]\$, siamo in grado di utilizzare la stessa mazza, una in più o una in meno di quanto avremmo potuto fare per un metro in meno. Il codice seguente codifica le yard in cui aumenta il numero di mazze disponibili e quelle in cui il numero di mazze disponibili diminuisce e le utilizza per calcolare il risultato.

“Ḳœẹ“rɓ?’ḃ5×5“ZO‘;"Ä⁸>§I‘ - Main Link: integer, Y  e.g. 129
“Ḳœẹ“rɓ?’                 - list of (two) base-250 integers = [11132965,7226564]
         ḃ5               - convert to bijective base five -> [[5,3,2,2,2,2,3,3,2,5],[3,3,2,2,2,2,2,2,2,4]]
           ×5             - multiply by five -> [[25,15,10,10,10,10,15,15,10,25],[15,15,10,10,10,10,10,10,10,20]]
             “ZO‘         - list of code-page indices = [90,79]
                  "       - zip with:
                 ;        -   concatenation -> [[90,25,15,10,10,10,10,15,15,10,25],[79,15,15,10,10,10,10,10,10,10,20]]
                   Ä      - Cumulative values -> [[90,115,130,140,150,160,170,185,200,210,235],[79,94,109,119,129,139,149,159,169,179,199]]
                    ⁸>    - is Y greater than (those)? -> [[1,1,0,0,0,0,0,0,0,0,0],[1,1,1,1,0,0,0,0,0,0,0]]
                      §   - sums -> [2,4]
                       I  - deltas -> [2]
                        ‘ - increment -> [3]
                          - implicit print -> "3"
6 Jonah Aug 17 2020 at 20:56

J , 63 58 55 50 byte

1#.1=(59 90+/\@,|:5*2+4#.inv 2424834 3408207)I."1]

Provalo online!

-5 byte grazie a xash

Codifica gli elenchi come numeri in base 4, ricostruisce, quindi utilizza l'indice dell'intervallo I.per contare in quanti intervalli rientra l'input.

5 DominicvanEssen Aug 17 2020 at 23:53

R , 77 76 72 byte

Modifica: -4 byte grazie a Robin Ryder

sum((d=scan()/10-9)>=c(11,9:2,.5,-1,d)&d<=c(d,14.5,12,11,9.5,8:4,2.5,0))

Provalo online!

Soluzione abbastanza ingenua, ma beneficia della vettorizzazione automatica di R e del suo :operatore di sequenza.

5 DanielH. Aug 17 2020 at 20:44

Python 3 , 180 155 153 97 88 byte

lambda n:sum(a<=chr(n)<b for a,b in zip('<P_nx‚Œ– ª´È','[tƒ—¡«ºÉÓìą'))

Provalo online!

5 streetster Aug 17 2020 at 20:29

K (oK) , 85 82 byte

Soluzione:

{+/z=x|y&z}.(-3 -1 .5 2 3 4 5 6 7 8 9 11;0 2.5 4 5 6 7 8 9.5 11 12 14.5 17),-9+.1*

Provalo online!

Spiegazione:

Decisamente ingenuo; molto probabile che questo sia un approccio sbagliato. Anche se bel golf da ngn per semplificare la logica di confronto! .

{+/z=x|y&z}.(-3 -1 .5 2 3 4 5 6 7 8 9 11;0 2.5 4 5 6 7 8 9.5 11 12 14.5 17),-9+.1* / the solution
                                                                               .1* / multiply input by 0.1
                                                                            -9+    / subtract 9 from input
                                                                          ,        / append to
            (-3 -1 .5 2 3 4 5 6 7 8 9 11;0 2.5 4 5 6 7 8 9.5 11 12 14.5 17)        / club stats
{         }.                                                                       / call lambda with multiple args
       y&z                                                                         / min of input and min distance
     x|                                                                            / max compared to max distance
   z=                                                                              / is input the same?
 +/                                                                                / sum up

Extra:

  • -3 byte grazie angn
3 ManishKundu Aug 17 2020 at 20:45

Python 3 , 105 byte

lambda n,a=[1],b=[2],c=[3],d=[4]:(a*20+b*11+a*4+b*15+c*6+b*4+c+(c*9+d)*6+d*5+c*14+d+c*10+b*25+a*25)[n-60]

Provalo online!

Spiegazione: una semplice forza bruta per memorizzare l'elenco delle risposte e stampare l'indice richiesto.

3 Neil Aug 18 2020 at 02:16

Carboncino , 44 byte

NθIΣE¹²⁻›θ⁺⁵⁹×⁵Σ…”)⊞⊟‹G↔”ι›θ⁺⁹⁰×⁵Σ…”)⊟+.D↥”ι

Provalo online! Il collegamento è alla versione dettagliata del codice. Port of @ JonathanAllen's answer. Spiegazione:

Nθ

Input d.

IΣE¹²⁻

Mappare i 12 club e stampare la somma dei risultati espressi sulla stringa di prendere le differenze tra ...

›θ⁺⁵⁹×⁵Σ…”)⊞⊟‹G↔”ι

... dconfrontato con 59sommato a 5volte la somma digitale del prefisso della stringa compressa 43322222224, e ...

›θ⁺⁹⁰×⁵Σ…”)⊟+.D↥”ι

... dconfrontato con 90sommato a 5volte la somma digitale del prefisso della stringa compressa 53222233235.

Risposta precedente di 48 byte:

NθIΣEI⪪”)¶∧!✂η}⌊⍘⪫⪫⊕#<e⌊W[qY9¤…”²∧›θ⁻×⁵ι﹪κ²⊖⊗﹪κ²

Provalo online! Il collegamento è alla versione dettagliata del codice. Spiegazione: Le distanze di inizio e fine delle 12 clavette sono divise da una stringa compressa di numeri interi da 12 a 52 che vengono moltiplicati per 5. dviene confrontata con tutti loro, segnando 1per distanze maggiori o uguali in posizioni dispari e -1per distanze maggiori in pari posizioni e viene stampato il totale finale.

3 flornquake Aug 19 2020 at 07:08

Python 3 , 62 60 byte

lambda d:sum(b//25<=b%25+23-d/5<=7for b in b'BUNSWYQ+-}')+1

Provalo online!

C'è un carattere invisibile (su Stack Exchange) \x18alla fine della stringa.

2 Arnauld Aug 18 2020 at 21:10

Penso che sia possibile ottenere rapporti di compressione più aggressivi nella maggior parte dei non esolang.

Come piccolo incentivo, ecco i miei punteggi in Python e Node.

Rivelerò entrambi gli snippet di codice di seguito non appena una risposta più breve o altrettanto lunga verrà pubblicata (o aggiornata) in una delle lingue o alle 14:00 UTC di venerdì 21 agosto 2020 nell'improbabile eventualità che tale risposta non venga pubblicata entro tale data.

EDIT (2020-08-19): Congratulazioni a @flornquake per essere stato il primo a pubblicare una risposta Python inferiore a 70 byte, usando un'idea simile alla mia ma spingendola oltre per un totale di 62 byte!


Python 3.8 (pre-rilascio) , 70 byte

lambda d,n=12:sum((n:=n+x//8-4)<=d/5<=n+x%8+6for x in b' A980001225F')

Provalo online!


JavaScript (Node.js) , 74 byte

d=>Buffer(' A980001225F').map(x=>t-=d/5<(n+=x-32>>3)|d/5>n+x%8+6,n=t=12)|t

Provalo online!

2 DomHastings Aug 19 2020 at 18:55

Perl 5 , 70 byte

Il primo byte nella stringa viene aggiunto in \x##notazione per un facile test, ma è un byte letterale.

$_=grep"@F">=($k+=(ord>>4)*5)&"@F"<=$k+(15&ord)*5,"\xc6G76&&&'((+L"=~/./g

Memorizza i dettagli per ogni club (diviso per 5) come un byte in cui i primi quattro bit sono la differenza dall'inizio dell'intervallo precedente e l'inizio di questo, ei secondi quattro bit sono la differenza tra l'inizio di questo intervallo e fine.

start  end =>     / 5   =>   binary    #
--------------------------------------------
 60     90 => 12      6 => 11000110    # counter starts at 0
 80    115 => 4       7 => 00100100    # counter is 12 from before so we only need an extra 4
 95    130 => 3       7 => 00110111 
110    140 => 3       6 => 00110110

Provalo online!

1 rtpax Aug 17 2020 at 23:18

C (gcc) , 83 75 byte

(non tutti i caratteri vengono visualizzati correttamente durante lo scambio di stack, ma sono corretti in TIO)

*i;c;f(d){c=0;for(i=L"ÈĄ´ëªÒ È–¹Œª‚ x–nŒ_‚Ps<Z";*i;c+=d/ *i++&*i++/d);d=c;}

Provalo online!

1 Noname Aug 18 2020 at 08:04

Io , 89 byte

method(a," \"$("asList select(i,v,v at(0)<=a/5and a/5<=" \"%(*/4"at(i))size)

Provalo online!

1 Mukundan314 Aug 18 2020 at 10:55

Pyth , 36 byte

s/RC-QTrV"2FUdnx‚Œ– ª¾""Qjyƒ—¡°¿Éâû

Provalo online!

Spiegazione

              "...   # String literal with end of ranges minus 10 as characters
         "..."       # String literal with start of ranges minus 10 as characters
       rV            # Generate the ranges
 /R                  # Count occurrences of 
   C-QT              # input minus 10 converted to a characters (based on ascii value)
                     # in each of the ranges
s                    # sum
1 Matsyir Aug 18 2020 at 01:04

JavaScript (V8) , 142 132 117 113 byte

-10 byte: applicato -9 agli intervalli e input dopo la divisione anziché dividere solo per 10 (ispirato da altre risposte, ho capito perché ne valeva la pena dopo aver osservato il mio intervallo / 10 numeri)

-15 byte grazie ai miglioramenti di Arnauld

-5 byte grazie agli ulteriori miglioramenti di Shaggy

d=>[11,17,9,14.5,8,12,7,11,6,9.5,...'58473625',.5,4,-1,2.5,-3,t=0].map((e,i,r)=>t+=++i%2&d>=e&d<=r[i],d=d/10-9)|t

Provalo online!

Soluzione piuttosto ingenua ma non mi sentivo a mio agio nel tentare metodi più complessi usati in altre risposte (per non parlare del fatto che non sono sicuro che siano possibili / con cui valga la pena giocare a golf in JS!). Accetterò volentieri consigli / miglioramenti, però.

Non minimizzato e spiegato (leggermente obsoleto ma spiega comunque il processo complessivo):

f = (distance) => {
    // divide input by 10 and subtract 9 since the hardcoded ranges are shorter when those operations are done.
    distance = distance / 10 - 9

    // hardcoded ranges divided by 10 then subtracted 9 to save bytes (probably can be done better).
    // Will be used in pairs, only processing even indexes and using i & i+1
    //ranges = [20,26,18,23.5,17,21,16,20,15,18.5,14,17,13,16,12,15,11,14,9.5,13,8,11.5,6,9] // /10
    //ranges = [14,20,12,17.5,11,15,10,14,9,12.5,8,11,7,10,6,9,5,8,3.5,7,2,5.5,0,3] // /10 -6
    ranges = [11,17,9,14.5,8,12,7,11,6,9.5,5,8,4,7,3,6,2,5,0.5,4,-1,2.5,-3,0] // /10 -9 (winner! inspired by other answers)

    // .map used as .reduce
    ranges.map((e, i)=> { // e: current element, i: current index
        totalValidClubs += ( // increment total 'valid' counter if within range
            i%2 == 1 ? 0 : // skip odd indexes, will use i & i+1 on even indexes only
            distance>=e && distance<=ranges[i+1] ? 1 : 0) // if even index and distance is between ranges[i] & [i+1] (inclusive), increment by 1.
    }, totalValidClubs=0); // initialize valid club counter as 0
    return totalValidClubs;
}
1 SomoKRoceS Aug 18 2020 at 05:05

05AB1E , 38 36 byte

38 byte

"ÈĄ´ëªÒ È–¹Œª‚ x–nŒ_‚Ps<Z"Ç2ôε.SOÄ2‹}O

Non riesco a comprimere :( Il meglio a cui avrei potuto pensare è convertire ogni numero in un carattere ASCII.

Spiegazione:

"ÈĄ´ëªÒ È–¹Œª‚ x–nŒ_‚Ps<Z"Ç2ôε.SOÄ2‹}O
"ÈĄ´ëªÒ È–¹Œª‚ x–nŒ_‚Ps<Z"                Ranges of clubs as ASCII chars
                            Ç               Convert to values
                             2ô             Split into chunks of two
                               ε       }    Map on pairs
                                .S          -1 if lower than input, 1 if greater, 0 it equal
                                  O         Sum the result of the pair
                                   Ä        Absolute value
                                    2‹      Is it lower than 2? (The only cases the absolute value is 2 are when the input is out of range)
                                        O   Now we have list of 0 and 1 for each range. Sum it up :)

Provalo online!

36 byte (grazie a @ovs)

"ÈĄ´ëªÒ È¹ª xn_Ps<Z"Ç2ôε-P(d}O

Utilizzando la -P(dmappa interna, che sottrarrà la coppia con l'input, la produrrà (i valori fuori intervallo saranno positivi), quindi applicare negativecon (e verificare se il valore non è negativo utilizzando d.

Provalo online!

1 SE-stopfiringthegoodguys Aug 21 2020 at 03:10

> <> , 51 byte

"Çɳº©«Ÿ¡•—‹ƒwÓmt^ìO["1&{:})${:}(*&+&55*0l3)?.&n;

(contiene 7 non stampabili)

Provalo online!

Poiché c'è almeno 1 mazza per ogni input, è possibile riorganizzare gli intervalli per eliminare un intervallo, il che ha l'ulteriore vantaggio di rimuovere la parte "260" che è appena al di fuori dell'intervallo di un byte.

1 CarterSande Aug 24 2020 at 15:46

Desmos , 106 byte:

f(d)=total(\left\{join([18...11],[9.5,8,6,20])*10<=d<=[47,42,40,37,34,32,30,28,26,23,18,52]*5:1,0\right\})

Visualizza il grafico online

Elimina f(d)=e sottrai 5 byte se ti piace usare un cursore come input.

MBaas Aug 20 2020 at 17:31

APL, 52 45 50 byte:

{+⌿1=(↓12 2⍴⎕ucs'Èą´ìªÓ Éº«¡xn_Pt<[')∘.⍸⍵}

Provalo online!