39
\$\begingroup\$

I was surprised to not find this asked already, though there is a great question on darts checkouts: Darts meets Codegolf

Your challenge is to calculate which scores are not possible with 'n' darts below the maximum score for 'n' darts. E.g. for n=3, the maximum possible score is 180 so you would return [163,166,169,172,173,175,176,178,179]

For a bare bones rule summary:

Possible scores for a single dart are:

  • 0 (miss)
  • 1-20, 25, 50
  • double or triple of 1-20

Rules:

  • standard code golf rules apply
  • you must take a single parameter 'n' in whatever way your language allows and return a list/array of all unique scores below the maximum score which cannot be scored with n darts. You may also print these values to the console.
  • order of results is unimportant
  • shortest code in bytes wins
\$\endgroup\$
  • 1
    \$\begingroup\$ Apologies for formatting, writing on a phone! \$\endgroup\$ – beirtipol Jun 19 at 18:28
  • \$\begingroup\$ somewhat related; I think there was another one about finding missing values from a range but I can't seem to find it. \$\endgroup\$ – Giuseppe Jun 19 at 18:35
  • 1
    \$\begingroup\$ Sincere apologies, I pulled those outputs from an answer to the basic question of 3 darts but did not verify! I will update the question! \$\endgroup\$ – beirtipol Jun 19 at 18:55
  • 2
    \$\begingroup\$ no worries :-) Looks fine to me! \$\endgroup\$ – Giuseppe Jun 19 at 19:02

21 Answers 21

32
\$\begingroup\$

Python 3, 80 79 59 57 bytes

-1 byte thanks to Arnauld
-20 bytes thanks to ArBo
-2 bytes thanks to negative seven

lambda x:[-i-~x*60for i in(x<2)*b'a[YUSOLI'+b'MJGDCA@>=']

Try it online!

\$\endgroup\$
  • 26
    \$\begingroup\$ I, errr, what?! \$\endgroup\$ – beirtipol Jun 19 at 19:29
  • 2
    \$\begingroup\$ @beirtipol there is a pattern on the numbers after the 2nd dart (well, its on the 1st dart too, but there are another numbers), this calculate the numbers based on this pattern. \$\endgroup\$ – Rod Jun 19 at 19:31
  • 4
    \$\begingroup\$ Ah, well played, well played indeed \$\endgroup\$ – beirtipol Jun 19 at 19:33
  • 8
    \$\begingroup\$ @EriktheOutgolfer If you're compressing, you might as well compress everything ;) 59 bytes \$\endgroup\$ – ArBo Jun 19 at 21:24
  • 2
    \$\begingroup\$ @negativeseven beat me to the 60 thing, was going to try that :) Good find on keeping the bytestrings separated though, hadn't thought of that. \$\endgroup\$ – ArBo Jun 20 at 15:40
14
\$\begingroup\$

Perl 6, 42 bytes

{^60*$_∖[X+] [[|(^21 X*^4),25,50]xx$_,]}

Try it online!

Brute force solution that works out all possible dart values.

\$\endgroup\$
9
\$\begingroup\$

JavaScript (ES6),  55  54 bytes

Saved 1 byte thanks to @Shaggy

Based on the pattern used by Rod.

n=>[...1121213+[n-1?33:2121242426]].map(x=>n-=x,n*=60)

Try it online!

\$\endgroup\$
  • 1
    \$\begingroup\$ s=60*n -> n*=60 to save a byte. \$\endgroup\$ – Shaggy Jun 20 at 10:19
  • \$\begingroup\$ @Shaggy Thanks. :) I missed that one because of my initial (unpublished) version where \$n\$ was re-used later. \$\endgroup\$ – Arnauld Jun 20 at 10:39
9
\$\begingroup\$

Perl 6, 39 bytes (37 chars)

This is definitely using a massive sledgehammer but it works. (It doesn't just brute force it, it brutally brute forces it)

{^60*$_∖[X+] (|(^21 X*^4),25,50)xx$_}

Try it online!

Here's an explanation of it:

{                                   } anonymous block for the 
       ∖                                set difference of
 ^60*$_                                   - 0 .. max score (60 * throwcount)
        [X+]                    xx$_      - the cross addition (throwcount times) of 
             (                 )              all possible score values, being 
              |(    X*  )                       flattened cross multiplication of
                ^21   ^4                          0..20 and 0..3 (for double and triple)
                         ,25,50                 and 25 and 50

The X* ^4 cross multiplier generates a lot of duplicate values (there will be 20+ zeros involved and that's before doing the cross addition), but that doesn't cause any problems since we use the set difference which works with the unique values.

This currently fails for $n == 1 (which should return an empty set), but there is an issue filed and will likely work in future versions. JoKing's version is a teeny bit longer, but works for $n == 1 in current Rakudo.

\$\endgroup\$
  • 1
    \$\begingroup\$ Wow, awkward... My extra bytes are from fixing the n=1 issue (though you can use $_ instead of $^n for -1) \$\endgroup\$ – Jo King Jun 19 at 22:51
  • 1
    \$\begingroup\$ @JoKing ha, I don't think there's anything wrong with two people getting virtually the same answer (especially since yours works in current versions versus mine that's currently theoretical) Also, thanks on the $_ , total brainfart on my part \$\endgroup\$ – guifa Jun 19 at 22:53
8
\$\begingroup\$

Jelly, 19 bytes

20Ż;25×Ɱ3ẎṖœċ⁸§ṪṖḟƊ

Try it online!

\$\endgroup\$
8
\$\begingroup\$

MATL, 25 23 bytes

Thanks to @Giuseppe, who fixed a mistake and golfed 2 bytes!

25tE3:!21:q*vZ^!stP:wX-

Try it online!

Explanation

Brute force approach.

25      % Push 25
tE      % Duplicate, double: gives 50
3:!     % Push column vector [1;2;3]
21:q    % Push row vector [0 1 ... 20]
*       % Multiply with broadcast. Gives a matrix with all products
v       % Concatenate everything into a column vector
Z^      % Implicit input: n. Cartesian power with exponent n
!s      % Sum of each row
tP      % Duplicate, flip: The first entry is now 60*n
:       % Push row vector [1 2 ... 60*n]
w       % Swap
X-      % Set difference. Implicit display
\$\endgroup\$
  • \$\begingroup\$ Your version doesn't work for n=2, so I fixed it and golfed off a byte to boot! Try it online! \$\endgroup\$ – Giuseppe Jun 20 at 20:11
  • \$\begingroup\$ Oh, found another byte by rearranging things :-) 23 bytes \$\endgroup\$ – Giuseppe Jun 20 at 20:15
  • \$\begingroup\$ @Giuseppe Hey, thank you so much! \$\endgroup\$ – Luis Mendo Jun 20 at 20:43
7
\$\begingroup\$

J, 48 45 bytes

2&>(35 44,q:626b66jh)&,60&*-1 4 8 14,q:@13090

Try it online!

-3 bytes thanks to FrownyFrog

Attempted a brute force solution, but was not able to beat this translation of Rod's idea.

\$\endgroup\$
  • \$\begingroup\$ tyvm as always, @FrownyFrog \$\endgroup\$ – Jonah Jun 20 at 13:26
  • \$\begingroup\$ even shorter 626b66jh \$\endgroup\$ – FrownyFrog Jun 20 at 13:38
  • \$\begingroup\$ what base is being used and how does J know to use it? \$\endgroup\$ – Jonah Jun 20 at 13:49
  • 1
    \$\begingroup\$ see codegolf.stackexchange.com/questions/113103/… \$\endgroup\$ – FrownyFrog Jun 20 at 13:56
  • \$\begingroup\$ ah, ty. i'd forgotten the b was the "delimiter" there and was reading it as part of the number.... \$\endgroup\$ – Jonah Jun 20 at 14:05
6
\$\begingroup\$

R, 64 bytes

function(n,`!`=utf8ToInt)c(60*n-!"",(!"#%),/")[n<2])

Try it online!

Ports the amazing answer found by Rod.

R, 85 73 68 bytes

function(n)setdiff(0:(60*n),combn(rep(c(0:20%o%1:3,25,50),n),n,sum))

Try it online!

Brute force generates all possible scores with n darts, then takes the appropriate set difference.

Credit to OrangeCherries' Octave solution for reminding me of combn.

5 more bytes thanks to Robin Ryder's suggestion of using %o%.

\$\endgroup\$
  • \$\begingroup\$ Very sorry about that, I should have double checked the example! \$\endgroup\$ – beirtipol Jun 19 at 18:55
  • 1
    \$\begingroup\$ Nice use of the FUN argument of combn! You can get 68 bytes with %o% instead of x*3,x*2. \$\endgroup\$ – Robin Ryder Jun 19 at 19:48
  • \$\begingroup\$ @RobinRyder duh. I even tried figuring out how to do broadcasting multiplication on the Octave answer! \$\endgroup\$ – Giuseppe Jun 19 at 19:50
4
\$\begingroup\$

Octave, 91 bytes 73 bytes 71 Bytes

Another brute force method.

@(n)setdiff(0:60*n,sum(combnk(repmat([x=0:20,x*2,x*3,25,50],1,n),n),2))

Down to 73 Bytes thanks to Giuseppe
Down to 71 Bytes by replacing nchoosek with combnk

Try it online!

\$\endgroup\$
3
\$\begingroup\$

Pyth, 22 bytes

-S*60Q+M^+yB25*M*U4U21

Try it online!

Times out in TIO for inputs greater than 3.

-S*60Q+M^+yB25*M*U4U21Q   Implicit: Q=eval(input())
                          Trailing Q inferred
                 U4       Range [0-3]
                   U21    Range [0-20]
                *         Cartesian product of the two previous results
              *M          Product of each
          yB25            [25, 50]
         +                Concatenate
        ^             Q   Cartesian product of the above with itself Q times
      +M                  Sum each
                            The result is all the possible results from Q darts, with repeats
  *60Q                    60 * Q
 S                        Range from 1 to the above, inclusive
-                         Setwise difference between the above and the possible results list
                          Implicit print
\$\endgroup\$
  • \$\begingroup\$ Not shorter, but if you change U4 to S3 the performance is improved a bit because both cartesian products don't have to deal with all those additional useless 0s. Input 3 outputs in ~13 seconds instead of ~30 in that case (although input 4 still times out, and this is code golf, so doesn't matter that much ;p). \$\endgroup\$ – Kevin Cruijssen Jun 20 at 13:59
  • \$\begingroup\$ @KevinCruijssen Very good point, I hadn't considered that I was including a 0 on both sides of the cartesian product. If I find any more golfs or reasons to edit I'll be sure to include that, thanks! \$\endgroup\$ – Sok Jun 20 at 14:27
  • \$\begingroup\$ Too bad there isn't a 0-based inclusive range builtin in Pyth.. I tried this -S*60QsM^*MP*S3aU21 25, but that space between 21 and 25 is a bit annoying.. With a 0-based inclusive range yT could be used instead of 21, kinda like this: -S*60QsM^*MP*S3a}ZyT25 (but then without the Z of course, with the } replaced with the 0-based inclusive range). Maybe you see something to golf in this alternative approach of adding the 25 to the list, and removing the 75 after the first cartesian product? \$\endgroup\$ – Kevin Cruijssen Jun 20 at 15:00
2
\$\begingroup\$

Stax, 24 bytes

¿ß☺o↕αg╠╩╬ò▼í¬«¥↕▄í■♣▓î►

Run and debug it

It's pretty slow for n=3, and gets worse from there.

\$\endgroup\$
2
\$\begingroup\$

Python 2, 125 bytes

lambda n:set(range(60*n))-set(map(sum,product(sum([range(0,21*j,j)for j in 1,2,3],[25,50]),repeat=n)))
from itertools import*

Try it online!


Python 3, 126 125 122 bytes

lambda n:{*range(60*n)}-{*map(sum,product(sum([[i,i*2,i*3]for i in range(21)],[25,50]),repeat=n))} 
from itertools import*

Try it online!

-3 bytes, thanks to Rod

\$\endgroup\$
  • \$\begingroup\$ @rod Thanks, :) \$\endgroup\$ – TFeld Jun 20 at 7:01
2
\$\begingroup\$

05AB1E, 21 20 18 bytes

20Ý25ª3Lδ*˜¨ãOZÝsK

-3 bytes thanks to @Grimy.

Times out pretty quickly the higher the input goes due to the cartesian product builtin ã.

Try it online or verify a few more test cases.

Explanation:

20Ý                 # Push a list in the range [0, 20]
   25ª              # Append 25 to this list
      3L            # Push a list [1,2,3]
        δ*          # Multiply the top two lists double-vectorized:
                    #  [[0,0,0],[1,2,3],[2,4,6],[3,6,9],...,[20,40,60],[25,50,75]]
          ˜         # Flatten this list: [0,0,0,1,2,...,40,60,25,50,75]
           ¨        # Remove the last value (the 75)
            ã       # Create all possible combinations of the (implicit) input size,
                    # by using the cartesian power
             O      # Sum each inner list of input amount of values together
              Z     # Get the maximum (without popping the list), which is 60*input
               Ý    # Create a list in the range [0, 60*input]
                s   # Swap so the initially created list is at the top of the stack again
                 K  # And remove them all from the [0, 60*input] ranged list
                    # (then output the result implicitly)
\$\endgroup\$
  • \$\begingroup\$ On that note, maximum is 60 * input, not 180. \$\endgroup\$ – Grimy Jun 20 at 21:35
  • \$\begingroup\$ @Grimy Yeah, ignore my stupidity.. I saw the incorrect result in the test suite, but of course I just made a mistake myself. I shouldn't codegolf in the evening after a long day at work.. >.> \$\endgroup\$ – Kevin Cruijssen Jun 21 at 6:23
1
\$\begingroup\$

Jelly, 28 bytes

21Ḷ×þ3R¤;25;50FœċµS€³×60¤R¤ḟ

Try it online!

\$\endgroup\$
1
\$\begingroup\$

MathGolf, 26 bytes

╟*rJrN▐3╒*mÅ~*╡ak.ε*mÉa─Σ-

Try it online!

-2 bytes thanks to Kevin Cruijssen

Explanation

╟*r                          push [0, ..., 60*input-1]
   Jr                        push [0, ..., 20]
     N▐                      append 25 to the end of the list
       3╒                    push [1, 2, 3]
         *                   cartesian product
          mÅ                 explicit map
            ~                evaluate string, dump array, negate integer
             *               pop a, b : push(a*b)
              ╡              discard from right of string/array
               a             wrap in array
                k            push input to TOS
                 .           pop a, b : push(b*a) (repeats inner array input times)
                  ε*          reduce list with multiplication (cartesian power)
                    mÉ       explicit map with 3 operators
                      a      wrap in array (needed to handle n=1)
                       ─     flatten array
                        Σ    sum(list), digit sum(int)
                         -   remove possible scores from [0, 60*input-1]
\$\endgroup\$
  • \$\begingroup\$ -2 bytes by changing 3╒*mÅ~*N_∞α+ to N▐3╒*mÅ~*╡. (PS: Why do you mention "for input 3" in your explanation header?) \$\endgroup\$ – Kevin Cruijssen Jun 20 at 15:06
  • \$\begingroup\$ Nice job, I'll change it when I'm back on my laptop! I had a 31-byter when I started writing the answer, which was more complicated, so I wanted to add a thorough explanation, but then I found the solution in the post \$\endgroup\$ – maxb Jun 22 at 14:24
1
\$\begingroup\$

Wolfram Language (Mathematica), 69 bytes

Complement[Range[60#],Tr/@{Array[1##&,{4,21},0,##&],25,50}~Tuples~#]&

Try it online!

Based off of lirtosiast's answer.

Array's third argument specifies the offset (default 1), and its fourth argument specifies the head to use instead of List. ##& is equivalent to Sequence, so Array[1##&,{4,21},0,##&] returns a (flattened) Sequence containing members of the outer product of 0..3 and 0..20.

\$\endgroup\$
0
\$\begingroup\$

Charcoal, 36 bytes

I⁺E…wvtsqpmjgkhea_[YS⎇⊖θ⁹¦¹⁷℅ι×⁶⁰⁻θ²

Try it online! Link is to verbose version of code. Uses @Rod's algorithm; brute force would have taken 60 bytes. Works by truncating the string to 9 characters if the input is greater than 1, then taking the ordinals of the characters and adding the appropriate multiple of 60.

\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 305 bytes

(a,b)=>(int)Math.Pow(a,b);f=n=>{var l=new List<int>(new int[21].SelectMany((_,x)=>new[]{x,x*2,x*3})){25,50};int a=l.Count,b,c,d,e=P(a,n),f;var r=new int[e];for(b=e;b>0;b--)for(c=0;c<n;c++){d=b;while(d>P(a,c+1))d-=P(a,c+1);f=(d/P(a,c))-1;r[b-1]+=l[f>0?f:0];}return Enumerable.Range(0,l.Max()*n).Except(r);}

Well, there doesn't seem to be an easy way of calculating all the possible combinations in C#, so this disaster of a code is all I could come up with.

Plus it takes about 30s to complete...

Would love to see a better solution.

P=(a,b)=>(int)Math.Pow(a,b);
F=n=>
{
    var l=new List<int>(new int[21].SelectMany((_,x)=>new[]{x,x*2,x*3})){25,50};
    int a=l.Count,b,c,d,e=P(a,n),f;
    var r=new int[e];
    for(b=e;b>0;b--)
        for(c=0;c<n;c++)
        {
            d=b;
            while(d>P(a,c+1))
                d-=P(a,c+1);
            f=(d/P(a,c))-1;
            r[b-1]+=l[f>0?f:0];
        }
    return Enumerable.Range(0,l.Max()*n).Except(r);
}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Seems you forgot to post your actual golfed answer. Usually people put the unrolled form of it below the golfed one. \$\endgroup\$ – Veskah Jun 20 at 16:17
  • \$\begingroup\$ @Veskah well, I usually post the golfed one if it's comprehensible, but since this one was a tad too long I saw no point on doing it since it can be found in the tio link anyway, but I guess you're right nevertheless \$\endgroup\$ – Innat3 Jun 21 at 7:37
0
\$\begingroup\$

Kotlin, 118 bytes

{n:Int->val i=if(n<2)listOf(23,24,31,25,37,41,44,47)
else
List(0){0}
i+List(9){n*60-listOf(17,14,11,8,7,5,4,2,1)[it]}}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Perl 5 -n, 96 93 91 bytes

$"=',';@b=map{$_,$_*2,$_*3,25,50}0..20;map$r[eval]=1,glob"+{@b}"x$_;map$r[$_]||say,0..$_*60

Try it online!

It was optimized for code length rather than run time, so it's kind of slow. It generates a lot of redundant entries for its lookup hash. Running the @b array through uniq speeds it up greatly, but costs 5 more bytes, so I didn't do it.

\$\endgroup\$
0
\$\begingroup\$

Wolfram Language (Mathematica), 81 bytes

Complement[Range[60#-1],Total/@Tuples[Flatten[{Array[Times,{3,20}],0,25,50}],#]]&

Try it online!

Mathematica has a few related builtins including FrobeniusSolve and the restricted form of IntegerPartitions, but none of them are shorter than brute force.

\$\endgroup\$
  • \$\begingroup\$ This is incorrect - it should return {163,166,169,172,173,175,176,178,179} \$\endgroup\$ – attinat Jul 30 at 4:36
  • 1
    \$\begingroup\$ @attinat Fixed. \$\endgroup\$ – lirtosiast Jul 30 at 5:44
  • \$\begingroup\$ 69 bytes \$\endgroup\$ – attinat Jul 30 at 8:31
  • \$\begingroup\$ @attinat Post it yourself. \$\endgroup\$ – lirtosiast Jul 30 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.