Fléchettes rencontre Codegolf

11

Je pense que tout le monde connaît les fléchettes, certaines personnes ne comprennent pas les scores, donc pour ces personnes, voici un lien utile à ce sujet.

Le tableau

Un jeu de fléchettes peut être comparé à une tarte coupée en 20 morceaux. Chaque pièce est divisée en 4 sections.

  • un petit anneau extérieur appelé double (points x2)
  • un gros anneau appelé single (points x1)
  • un autre petit anneau appelé triple (points x3)
  • un autre grand anneau appelé single (points x1)

Au milieu du plateau se trouvent 2 autres anneaux, un vert et un rouge (plateau classique)

  • L'anneau rouge, au centre du plateau appelé bullseye ou double bull et est bon pour 50 points. Celui-ci compte comme un double et à cause de cela, il est autorisé à payer avec lui.
  • Anneau vert, appelé taureau, taureau simple ou simplement 25 et compte comme un seul.

Défi

Trouvez toutes les possibilités de paiement avec 3 fléchettes ou moins.
L'utilisateur peut entrer un entier et vous devrez vérifier s'il est possible d'obtenir le score à 0 avec 3 fléchettes (ou moins).

Exemples

Exemple 1:

Input: 170  
Output: T20, T20, Bullseye

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

Exemple 3:

Input: 169
Output: No possible checkout!

Règles

  • Règle de base de la fléchette, vous devez terminer par un double (anneau extérieur du plateau ou oeil de boeuf)
  • Pas d'utilisation de ressources externes.
  • Le codage en dur des extractions possibles est autorisé mais rappelez-vous que c'est codegolf, il ne raccourcira pas votre code;)
  • Les cellules à frapper seront affichées au format C + N où C = T pour Triple, D pour double et S pour simple.
    • bullseye peut être appelé bullseye ou DB, DBull ou quelque chose de simulaire.

Paiements possibles

Pour commencer, le paiement le plus élevé possible est de 170.
169.168.166.165.163.162.159 ne sont pas possibles en 3 fléchettes.
Le paiement le plus bas possible est de 2.

en plus

Ce n'est pas une exigence, ajoutez une possibilité d'afficher toutes les caisses possibles pour tous les scores. Fondamentalement parce que je me demande combien de combinaisons sont possibles: P

Le gagnant sera celui avec le code le plus court.

Codage heureux.

Teun Pronk
la source
1
La première règle répertoriée est incorrecte (et invalide le premier exemple) car vous pouvez également terminer sur un taureau. Il serait utile de préciser si vous attendez un programme, une fonction ou les deux; et la flexibilité du format de sortie.
Peter Taylor
1
@PeterTaylor Je vais clarifier cela, car l'anneau vert et l'anneau rouge au milieu sont appelés taureau simple et œil de taureau ou taureau double.
Teun Pronk
1
+1 pour une excellente question. C'est le genre de problème du monde réel que les ordinateurs sont bons à résoudre. Vous pouvez lancer un 6 dans S2 D1 D1, qui est absent de votre exemple de sortie (il devrait être là, sauf si vous considérez que S2 S2 D1 et D1 D1 D1 sont les mêmes, mais ils sont clairement répertoriés comme différents.) Il y en a ambiguïtés mineures sur le format de sortie et le comptage des résultats que j'aborderai dans ma réponse.
Level River St

Réponses:

2

C ++ 248/228 230/214 car.

Rév 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;}

Rev 1. Sauvegarde de certains caractères en déclarant toutes les variables à la fois et en éliminant les crochets inutiles. Il s'avère qu'en C ++ toute logique et bit à bit et / ou ont une priorité inférieure à celle des comparaisons.

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

J'ai fait une fonction plutôt qu'un programme, comme d'autres l'ont fait. Il renvoie le nombre total de possibilités trouvées. Il peut être réduit de 230 à 214 caractères en éliminant la fonction de totalisation.

Exemple de sortie, score 6:

entrez la description de l'image ici

Je compte différentes première et deuxième fléchettes comme la même combinaison, comme l'OP l'a fait (exemple:

T1 S1 D1 = S1 T1 D1) même si cela coûte 7 caractères supplémentaires. Je liste toujours le score le plus élevé en premier (en ignorant les doublons et les triples) car je pense que cela est plus pertinent pour le joueur (qui peut changer sa stratégie s'il manque avec la première fléchette.) Pour la même raison, je liste les fléchettes dans l'ordre selon la deuxième fléchette. Je considère que la 3e fléchette est complètement différente des deux autres, donc je considère D1 D2 et D2 D1 comme des cas différents alors que l'OP les a listés comme les mêmes.

Avec ce système de comptage, j'obtiens 42336 possibilités totales , les mêmes que mmumboss. En comptant différentes première et deuxième fléchettes comme différentes combinaisons, cela monte à 83349.

Je n'ai pas utilisé de boucle for avec des ensembles comme d'autres l'ont fait (je suis assez nouveau en C ++ et je ne sais même pas si c'est possible.) Au lieu de cela, j'abuse un conditionnel dans l'incrément de boucle pour passer de 20 à 25 J'utilise la variable d'une seule boucle pour encoder tous les scores possibles pour une seule fléchette, comme ceci: S1 D1 T1 S2 D2 T2 etc. avec module et division à décoder. Cela permet d'économiser sur la verbosité de déclarer plus pour les boucles, bien que cela rend les expressions plus compliquées.

Le résultat de cela est qu'une fléchette inutilisée est représentée par T0, mais je pense que ce que cela signifie est clair, d'autant plus que (en considérant différentes première et deuxième fléchettes comme la même combinaison), j'ai pu les regrouper toutes au début de ma sortie.

Version non golfée ici. Quelques autres fonctionnalités sont l'utilisation sélective des opérateurs & et && avec | de manière à donner l'ordre de priorité que je veux sans crochets.

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;
}
Level River St
la source
204 octets
Plafond
4

MATLAB ( 299 249 241 caractères)

C'est mon premier golf sérieux. Ma première tentative (136 caractères) donne le résultat correct, mais pas avec le formatage correct. Il donne toutes les possibilités en regardant le nombre de points pour chaque fléchette. Cela signifie que le simple 20 et le double 10 ont une entrée distincte, cependant, ils sont tous deux affichés comme 20. Bien sûr, la dernière fléchette est toujours un double.

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

Dans la deuxième tentative, le formatage est amélioré, ce qui a bien sûr augmenté le nombre de caractères:

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

Amélioré de 299 à 249 caractères, tout en améliorant en même temps le formatage de sortie. Pour cette version améliorée, la sortie des exemples de cas est:

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

Additionnel:

Selon mes compétences en calcul, il y a un grand total de 42336 possibilités pour terminer le jeu de fléchettes.

mmumboss
la source
Le résultat devrait montrer quelle cellule frapper, donc dans le premier il 60 60 50devrait l'être T20 T20 Bullseye. Je vais préciser cela dans la question. Bien joué, presque là :)
Teun Pronk
1
Oui, je l'ai déjà souligné moi-même. Il s'agit de la première tentative inachevée. ;)
mmumboss
oups désolé lol, j'étais trop curieux du code et du résultat je n'ai pas lu l'histoire ci-dessus xD
Teun Pronk
Ça devrait être mieux. La seule chose à laquelle je peux penser, c'est que le taureau est toujours affiché en tant que 25. Mais j'espère que ça va, car sinon il n'y a pas d'autre possibilité que de coder en dur, ce qui n'est tout simplement pas amusant.
mmumboss
Un taureau unique à 25 est en effet acceptable, c'est la seule façon de lancer 25 avec 1 fléchette de toute façon
Teun Pronk
2

Rubis (260 caractères)

"Le dernier devrait être un double" était la pièce manquante - ne pouvait pas comprendre pourquoi 168 ne devraient pas avoir de résultats ...:

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

c. (170)

T20,T20,DB;

c. (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;
Uri Agassi
la source
1

Python 2.7 (270 caractères)

Pas sûr que le python permettra un one-liner, mais il est en trois.

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

Ou 278+ caractères avec un bon message "Pas de paiement" (par exemple 290 ici):

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

Et c'est parti:

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

Choses dont je ne suis pas satisfait:

for x in a for y in a for z in

Cela représente plus de 10% du total. Existe-t-il un moyen plus compact sans itertools, etc.?

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

Ceci est utilisé pour éviter les doublons dans le cas d'une finition à deux fléchettes (par exemple ['', 'S1', 'D1'] et ['S1', '', 'D1']). Je considère que l'ordre est important (hé - la dernière fléchette doit être un double, donc clairement l'ordre importe), mais le non-lancer est un cas spécial.

psion5mx
la source
1

05AB1E , 43 octets

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

Assez lent. Sorties sous forme de liste de listes, ou une liste vide si aucune finition n'est possible. Mes taureaux sont S25et D25; si ce n'est pas permis, je peux le changer.

Essayez-le en ligne ou vérifiez quelques cas de test à la fois .

Explication:

Il y a deux étapes:

1) Créez une liste de toutes les fléchettes simples, doubles et triples possibles:

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) Obtenez tous les finisseurs possibles (se terminant par un double) jusqu'à 3 fléchettes:

Ð           # 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) Ne conservez que ceux dont le score total est égal à l'entier en entrée:

ʒ   }       # 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) Convertissez les données en une jolie liste de résultats (c'est-à-dire [[20,3],[5,1],[1,2]]devient ["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)
Kevin Cruijssen
la source
0

Kotlin , 254 octets

Remarque: algorythm est basé sur la réponse C ++ de 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!")}

Essayez-le en ligne!

JohnWells
la source