Дартс встречает Кодегольф

11

Я думаю, что все знакомы с дартс, некоторые люди не понимают счет, поэтому для этих людей здесь есть полезная ссылка на это.

Доска

Дартс можно сравнить с пирогом, разрезанным на 20 частей. Каждый кусок разделен на 4 раздела.

  • маленькое внешнее кольцо, называемое двойным (точки х2)
  • большое кольцо под названием один (точки х1)
  • другое маленькое кольцо, называемое тройным (точки х3)
  • еще одно большое кольцо, называемое одиночным (точки х1)

В середине доски еще 2 кольца, зеленое и красное (классическая доска)

  • Красное кольцо, центр доски называется яблочко или двойной бык и хорошо для 50 очков. Этот считается двойным, и из-за этого его можно оформить.
  • Зеленое кольцо, называется бык, один бык или просто 25 и считается за одного.

Вызов

Найти все возможности оформления заказа с 3 дротиками или меньше.
Пользователь может ввести целое число, и вам нужно будет проверить, можно ли получить счет до 0 с помощью 3 дротиков (или меньше).

Примеры

пример 1:

Input: 170  
Output: T20, T20, Bullseye

Пример 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;

Пример 3:

Input: 169
Output: No possible checkout!

правила

  • Основное правило дротика, вы должны заканчиваться двойным (внешнее кольцо доски или яблочко)
  • Нет использования внешних ресурсов.
  • Допускается жесткое кодирование возможных проверок, но помните, что это codegolf, ваш код не будет коротким;)
  • Ячейки для удара будут отображаться в формате C + N, где C = T для Triple, D для двойной и S для одиночной.
    • яблочко можно назвать яблочко или DB, DBull или что-то симулированное.

Возможные проверки

Чтобы начать, Максимально возможная проверка составляет 170.
169 168 166 165 163 162 159 невозможны в 3 дротика.
Минимально возможный заказ составляет 2.

К тому же

Это не является обязательным требованием, добавьте возможность показывать все возможные проверки для всех результатов. В основном потому, что мне интересно, сколько комбинаций возможно: P

Победителем станет тот, у кого самый короткий код.

Удачного кодирования.

Теун Пронк
источник
1
Первое перечисленное правило неверно (и делает недействительным первый пример), потому что вы также можете финишировать на быке. Было бы полезно уточнить, ожидаете ли вы программу, функцию или и то и другое; и сколько гибкости есть в выходном формате.
Питер Тейлор
1
@PeterTaylor Я поясню это, так как зеленое кольцо и красное кольцо в середине называются Одиночный бык и яблочко или двойной бык.
Теун Пронк
1
+1 за отличный вопрос. Это проблема реального мира, которую хорошо решают компьютеры. Вы можете бросить 6 в S2 D1 D1, чего нет в вашем примере вывода (оно должно быть там, если вы не считаете S2 S2 D1 и D1 D1 D1 одинаковыми, но они явно указаны как разные.) Есть некоторые незначительные неясности относительно формата вывода и подсчета результатов, которые я рассмотрю в своем ответе.
Уровень Река St

Ответы:

2

C ++ 248/228 230/214 символов

Ред. 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;}

Ред. 1. Сохранены некоторые символы, объявив все переменные одновременно и удалив ненужные скобки. Оказывается, в C ++ все логические и побитовые и / или имеют меньший приоритет, чем сравнения.

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;}

Я сделал функцию, а не программу, как другие. Возвращает общее количество найденных возможностей. Его можно уменьшить с 230 до 214 символов, исключив функцию суммирования.

Пример вывода, оценка 6:

введите описание изображения здесь

Я считаю разные первый и второй дротики одной и той же комбинацией, как это сделал ОП (пример:

T1 S1 D1 = S1 T1 D1), хотя это стоит дополнительно 7 символов. Сначала я всегда перечисляю более высокий счет (игнорируя удвоение и утроение), так как считаю, что это более актуально для игрока (который может изменить свою стратегию, если он пропустит первый дротик). По той же причине я перечисляю дротики в порядке согласно второй дротик Я считаю, что 3-й дротик полностью отличается от двух других, поэтому я считаю, что D1 D2 и D2 D1 - это разные случаи, в то время как в OP они перечислены как одинаковые.

С этой системой подсчета я получаю 42336 полных возможностей , так же, как mmumboss. Считая разные первый и второй дротики как разные комбинации, это дойдет до 83349.

Я не использовал цикл for с множествами, как это делали другие (я довольно плохо знаком с C ++ и даже не знаю, возможно ли это.) Вместо этого я злоупотребляю условным приращением цикла, чтобы перейти с 20 на 25 Я использую переменную из одного цикла, чтобы закодировать все возможные оценки для одного дротика, например: S1 D1 T1 S2 D2 T2 и т. Д. С модулем и делением для декодирования. Это экономит на многословности объявления большего количества циклов, хотя и усложняет выражения.

Результатом этого является то, что неиспользованный дротик отображается как T0, но я думаю, что понятно, что имеется в виду, тем более что (рассматривая разные первый и второй дротики как одну и ту же комбинацию) я смог сгруппировать их все вместе в начале моего выхода.

Безголовая версия здесь. Пара других функций - использование операторов & и && выборочно с | таким образом, чтобы дать порядок приоритета я хочу без скобок.

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;
}
Уровень реки St
источник
204 байта
потолочная кошка
4

MATLAB ( 299 249 241 символов)

Это мой первый серьезный гольф. Моя первая попытка (136 символов) дает правильный результат, но не с правильным форматированием. Это дает все возможности, глядя на количество очков для каждого дротика. Это означает, что одинарные 20 и двойные 10 имеют отдельную запись, однако они оба отображаются как 20. Конечно, последний дротик всегда является двойным.

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

Во второй попытке улучшено форматирование, что, конечно, увеличило количество символов:

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

Улучшено с 299 до 249 символов, при этом даже улучшено форматирование вывода. Для этой улучшенной версии выходные данные для примеров:

е (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

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

Согласно моим расчетным навыкам, есть всего 42336 возможностей закончить игру в дартс.

mmumboss
источник
Результат должен показывать, в какую ячейку попадать, поэтому в первом 60 60 50должно быть написано T20 T20 Bullseye. Я сделаю это более ясным в вопросе. Хорошо идет, хотя, почти там :)
Teun Pronk
1
Да, я уже указывал на это сам. Это первая незаконченная попытка. ;)
mmumboss
ой, извините, лол, мне было любопытно узнать код и результат, я не читал рассказ выше xD
Teun Pronk
Это должно быть лучше. Единственное, о чем я могу думать, это то, что бык по-прежнему отображается как 25. Но я надеюсь, что это нормально, так как в противном случае нет другой возможности, кроме как жестко закодировать это, что просто неинтересно.
mmumboss
Одиночный бык как 25 действительно приемлем, это единственный способ, которым вы можете бросить 25 с 1 дротиком
Teun Pronk
2

Рубин (260 символов)

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

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(?,)};"})})}

с. (170)

T20,T20,DB;

с. (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;
Ури Агасси
источник
1

Python 2,7 (270 символов)

Не уверен, что Python позволит однострочно, но он в три.

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

Или 278+ символов с правильным сообщением «Нет проверки» (например, 290 здесь):

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

Вот так:

е (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

Вещи, которыми я не доволен:

for x in a for y in a for z in

Это более 10% от общего количества. Есть ли более компактный способ без itertools и т. Д.?

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

Это используется для предотвращения дублирования в случае двух дротиков (например, ['', 'S1', 'D1'] и ['S1', '', 'D1']). Я считаю, что порядок имеет значение (эй, последний дротик должен быть двойным, поэтому порядок важен), но не бросок - это особый случай.

psion5mx
источник
1

05AB1E , 43 байта

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

Довольно медленно. Выводит в виде списка списков или пустого списка, если окончание невозможно. Мои быки S25и D25; если это не разрешено, я могу изменить это.

Попробуйте онлайн или проверьте несколько тестовых случаев одновременно .

Объяснение:

Есть несколько шагов:

1) Создайте список всех возможных одиночных, двойных и тройных дротиков:

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) Получите все возможные финишеры (заканчивающиеся двойным) до 3 дротиков:

Ð           # 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) Сохраняйте только те, для которых общий балл равен целочисленному вводу:

ʒ   }       # 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) Преобразуйте данные в довольно распечатанный список результатов (то есть [[20,3],[5,1],[1,2]]становится ["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)
Кевин Круйссен
источник
0

Котлин , 254 байта

Примечание: алгоритм основан на ответе C ++ Level 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!")}

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

JohnWells
источник