Гольф диаграмма для гольфа

Aug 17 2020

Учитывая расстояние в метрах как целое число \$60\le d \le 260\$, верните количество клубов, которые можно использовать в соответствии со следующей произвольной таблицей, где оба \$min\$и \$max\$ включены:

 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

Примечания

  • Названия клубов даны только для информации.

  • Конечно, выбор клуба зависит от ряда других параметров. Например, Sand Wedge предназначен для выхода из песчаного бункера. Но для этой задачи имеет значение только расстояние.

  • Это, несомненно, вызов кодового гольфа .

пример

Для \$d=130\$, мы можем выбрать 6-железо , 7-железо , 8-железо или 9-железо , поэтому ожидаемый ответ - \$4\$.

Тестовые примеры

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

Или в виде списков:

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

Ответы

17 640KB Aug 17 2020 at 23:02

машинный код x86-16, 47 42 байта

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                 ..........

Листинг:

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

Callable функции, вход dв DX, выводится в BL.

Без сжатия (данные только 24 22 байта в двоичном формате) просто сравнение таблиц.

Изменить: огромные реквизиты для @SE - перестаньте увольнять хороших парней за переупорядочение списка и устранение необходимости смещения dзначения, сэкономив 5 байтов !

Программа тестирования запускается:

Альтернативная версия, 50 байт

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

Это в значительной степени вдохновлено ответом Джонатана Аллана . Это использует таблицу значений , dгде число переходов клубов либо +1или -1, и соответствующее двоичное число магии из 0x5556dкоторой 1указывает на положительное изменение , и 0указывает на отрицательное изменение.

К сожалению, здесь это не очень помогает, поскольку кодирование исходной таблицы составляет 24 байта по сравнению с 22 переходами плюс 3-байтовое магическое число, так что на самом деле оно больше. Хотя было весело попробовать!

12 ovs Aug 17 2020 at 22:05

Python 3 , 71 байт

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

Попробуйте онлайн!

Строки байтов содержат некоторые непечатаемые элементы, их экранированная форма - b'($" \x1e\x1c\x1a\x18\x16\x13\x10\x0c'и b'4/*(%" \x1e\x1c\x1a\x17\x12'.


Python 3 , 71 байт

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

Попробуйте онлайн!


Python 3.8 , 90 86 байт

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}])

Попробуйте онлайн!

Последнее условие также можно записать как a%10<1<a/10<7,a==90с такой же длиной.

7 JonathanAllan Aug 17 2020 at 20:59

Желе , 25 байт

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

Полная программа, которая печатает результат (или монадическая ссылка, которая возвращает одноэлементный список).

Попробуйте онлайн! Или посмотрите набор тестов .

Как?

Для любого допустимого ввода в \$[60,260]\$мы можем использовать хотя бы одну клюшку. Для любого заданного метража в \$[61,260]\$, мы можем использовать либо ту же клюшку, либо на одну больше, либо на одну клюшку меньше, чем могли бы, на один ярд меньше. Приведенный ниже код кодирует расстояния, при которых количество доступных клубов увеличивается, и те, при которых количество доступных клубов уменьшается, и использует это для вычисления результата.

“Ḳœẹ“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 байт

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

Попробуйте онлайн!

-5 байт благодаря xash

Кодирует списки в виде чисел с основанием 4, реконструирует, затем использует индекс интервала I.для подсчета того, в какие диапазоны попадает вход.

5 DominicvanEssen Aug 17 2020 at 23:53

R , 77 76 72 байта

Изменить: -4 байта благодаря Робину Райдеру

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))

Попробуйте онлайн!

Довольно наивное решение, но выигрывает от автоматической векторизации R и :оператора последовательности.

5 DanielH. Aug 17 2020 at 20:44

Python 3 , 180 155 153 97 88 байт

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

Попробуйте онлайн!

5 streetster Aug 17 2020 at 20:29

K (ОК) , 85 82 байта

Решение:

{+/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*

Попробуйте онлайн!

Пояснение:

Определенно наивный; весьма вероятно, что это плохой подход. Хотя хороший гольф от ngn для упрощения логики сравнения! .

{+/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

Дополнительно:

  • -3 байта благодаряngn
3 ManishKundu Aug 17 2020 at 20:45

Python 3 , 105 байт

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]

Попробуйте онлайн!

Объяснение: Простой перебор для сохранения списка ответов и печати необходимого индекса.

3 Neil Aug 18 2020 at 02:16

Уголь , 44 байта

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

Попробуйте онлайн! Ссылка на подробную версию кода. Порт ответа @JonathanAllen. Пояснение:

Nθ

Вход d.

IΣE¹²⁻

Сопоставьте 12 клубов и выведите сумму результатов в строку, взяв разницу между ...

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

... dпо сравнению с 59добавленной в 5раз цифровой суммой префикса сжатой строки 43322222224и ...

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

... dпо сравнению с 90добавленной в 5раз цифровой суммой префикса сжатой строки 53222233235.

Предыдущий 48-байтовый ответ:

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение: Конечная и начальная дистанции 12 треф разделены из сжатой строки целых чисел от 12 до 52, которые умножаются на 5. d, сравниваются со всеми ними, подсчитываются очки 1за большие или равные дистанции в нечетных позициях и -1за большие дистанции в четных. позиции и окончательная сумма будет напечатана.

3 flornquake Aug 19 2020 at 07:08

Python 3 , 62 60 байт

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

Попробуйте онлайн!

В \x18конце строки есть невидимый (на Stack Exchange) символ.

2 Arnauld Aug 18 2020 at 21:10

Я думаю, что можно добиться более агрессивной степени сжатия в большинстве неэзолангов.

В качестве небольшого стимула вот мои собственные оценки по Python и Node.

Я представлю оба фрагмента кода ниже, как только будет опубликован (или обновлен) более короткий или такой же длинный ответ на любом языке, или в 14:00 по всемирному координированному времени в пятницу, 21 августа 2020 г., в том маловероятном случае, если к тому времени такой ответ не будет опубликован.

РЕДАКТИРОВАТЬ (2020-08-19): Поздравляем @flornquake за то, что он первым опубликовал ответ Python размером менее 70 байт, используя идею, аналогичную моей, но продвигая ее еще дальше, в общей сложности 62 байта!


Python 3.8 (предварительная версия) , 70 байт

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

Попробуйте онлайн!


JavaScript (Node.js) , 74 байта

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

Попробуйте онлайн!

2 DomHastings Aug 19 2020 at 18:55

Perl 5 , 70 байт

Первый байт в строке добавлен в \x##обозначениях для облегчения тестирования, но является буквальным байтом.

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

Сохраняет данные для каждого клуба (разделенные на 5) в виде байта, где первые четыре бита - это разница между началом предыдущего диапазона и началом этого, а вторые четыре бита - разницей между началом этого диапазона и конец.

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

Попробуйте онлайн!

1 rtpax Aug 17 2020 at 23:18

C (gcc) , 83 75 байт

(не все символы отображаются правильно при обмене стеками, но верны в TIO)

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

Попробуйте онлайн!

1 Noname Aug 18 2020 at 08:04

Io , 89 байт

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

Попробуйте онлайн!

1 Mukundan314 Aug 18 2020 at 10:55

Pyth , 36 байт

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

Попробуйте онлайн!

Объяснение

              "...   # 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 байт

-10 байт: применен -9 к диапазонам и вводу после деления, а не только деления на 10 (вдохновленный другими ответами, понял, почему это того стоило, после наблюдения моего диапазона / 10 чисел)

-15 байт благодаря улучшениям Арно

-5 байт благодаря дальнейшим улучшениям Шэгги

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

Попробуйте онлайн!

Довольно наивное решение, но мне было неудобно пытаться использовать более сложные методы, используемые в других ответах (не говоря уже о том, что я не уверен, что они вообще возможны / стоят того, чтобы играть в гольф в JS!). Тем не менее, я с радостью воспользуюсь советом / улучшением.

Unminified и объяснение (немного устарело, но все же объясняет общий процесс):

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 байт

38 байт

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

Я плохо умею сжимать :( Лучшее, что я мог придумать, - это преобразовать каждое число в символ ASCII.

Пояснение:

"ÈĄ´ëªÒ È–¹Œª‚ 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 байт (спасибо @ovs)

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

Использование -P(dвнутри карты, которая будет вычитать пару с входом, продуктом она (из значений диапазона будет положительной), а затем применить negativeс (и проверить , если значение является неотрицательное использованием d.

Попробуйте онлайн!

1 SE-stopfiringthegoodguys Aug 21 2020 at 03:10

> <> , 51 байт

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

(содержит 7 непечатных материалов)

Попробуйте онлайн!

Поскольку для каждого входа существует как минимум 1 клуб, можно переупорядочить диапазоны, чтобы избавиться от одного диапазона, что дает дополнительное преимущество в виде удаления части «260», которая едва выходит за пределы диапазона байта.

1 CarterSande Aug 24 2020 at 15:46

Десмос , 106 байт:

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\})

Посмотреть график онлайн

Удалите f(d)=и вычтите 5 байтов, если вам нравится использовать ползунок в качестве ввода.

MBaas Aug 20 2020 at 17:31

APL, 52 45 50 байт:

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

Попробуйте онлайн!