Giocare a golf su una mappa da golf
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
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 d
in 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 d
valore, 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 d
cui il numero di mazze transita o +1
o -1
, e un numero magico binario corrispondente di 0x5556d
dove a 1
indica un cambiamento positivo e 0
indica 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!
Python 3 , 71 byte
lambda n:sum(a<=n/5<=b for a,b in zip(b'($" ',b'4/*(%" '))
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))$$$'))
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}])
L'ultima condizione può anche essere scritta come a%10<1<a/10<7,a==90
alla stessa lunghezza.
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"
J , 63 58 55 50 byte
1#.1=(59 90+/\@,|:5*2+4#.inv 2424834 3408207)I."1]
-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.
Python 3 , 180 155 153 97 88 byte
lambda n:sum(a<=chr(n)<b for a,b in zip('<P_nx‚Œ– ª´È','[tƒ—¡«ºÉÓìą'))
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*
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 a
ngn
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]
Spiegazione: una semplice forza bruta per memorizzare l'elenco delle risposte e stampare l'indice richiesto.
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↔”ι
... d
confrontato con 59
sommato a 5
volte la somma digitale del prefisso della stringa compressa 43322222224
, e ...
›θ⁺⁹⁰×⁵Σ…”)⊟+.D↥”ι
... d
confrontato con 90
sommato a 5
volte 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. d
viene confrontata con tutti loro, segnando 1
per distanze maggiori o uguali in posizioni dispari e -1
per distanze maggiori in pari posizioni e viene stampato il totale finale.
Python 3 , 62 60 byte
lambda d:sum(b//25<=b%25+23-d/5<=7for b in b'BUNSWYQ+-}')+1
C'è un carattere invisibile (su Stack Exchange) \x18
alla fine della stringa.
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')
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
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
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;}
Io , 89 byte
method(a," \"$("asList select(i,v,v at(0)<=a/5and a/5<=" \"%(*/4"at(i))size)
Pyth , 36 byte
s/RC-QTrV"2FUdnx‚Œ– ª¾""Qjyƒ—¡°¿Éâû
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
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
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;
}
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 :)
36 byte (grazie a @ovs)
"ÈĄ´ëªÒ ȹª xn_Ps<Z"Ç2ôε-P(d}O
Utilizzando la -P(d
mappa interna, che sottrarrà la coppia con l'input, la produrrà (i valori fuori intervallo saranno positivi), quindi applicare negative
con (
e verificare se il valore non è negativo utilizzando d
.
> <> , 51 byte
"Çɳº©«Ÿ¡•—‹ƒwÓmt^ìO["1&{:})${:}(*&+&55*0l3)?.&n;
(contiene 7 non stampabili)
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.
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\})
Elimina f(d)=
e sottrai 5 byte se ti piace usare un cursore come input.