Inspired by this question by @CᴏɴᴏʀO'Bʀɪᴇɴ.

Taken from the question:

Your task is simple: given two integers a and b, output ∏[a,b]; that is, the product of the range between a and b. You may take a and b in any reasonable format, whether that be arguments to a function, a list input, STDIN, et cetera. You may output in any reasonable format, such as a return value (for functions) or STDOUT. a will always be less than b.

Note that the end may be exclusive or inclusive of b. I'm not picky. ^_^

The difference for this challenge is we are going to be picky about the range type. Input is a string of the form [a,b], (a,b], [a,b), or (a,b) where a [] is an inclusive boundary and () is an exclusive boundary. Given the explicit boundaries, provide the product of the range. Also the input range will always include at least 1 number, meaning ranges like (3,4) are invalid and need not be tested.

Test cases

[a,b) => result
[2,5) => 24
[5,10) => 15120
[-4,3) => 0
[0,3) => 0
[-4,0) => 24

[a,b] => result
[2,5] => 120
[5,10] => 151200
[-4,3] => 0
[0,3] => 0
[-4,-1] => 24

(a,b] => result
(2,5] => 60
(5,10] => 30240
(-4,3] => 0
(0,3] => 6
(-4,-1] => -6

(a,b) => result
(2,5) => 12
(5,10) => 3024
(-4,3) => 0
(0,3) => 2
(-4,0) => -6

This is a , so the shortest program in bytes wins.


The Stack Snippet at the bottom of this post generates the catalog from the answers a) as a list of shortest solution per language and b) as an overall leaderboard.

To make sure that your answer shows up, please start your answer with a headline, using the following Markdown template:

## Language Name, N bytes

where N is the size of your submission. If you improve your score, you can keep old scores in the headline, by striking them through. For instance:

## Ruby, <s>104</s> <s>101</s> 96 bytes

If there you want to include multiple numbers in your header (e.g. because your score is the sum of two files or you want to list interpreter flag penalties separately), make sure that the actual score is the last number in the header:

## Perl, 43 + 2 (-p flag) = 45 bytes

You can also make the language name a link which will then show up in the snippet:

## [><>](http://esolangs.org/wiki/Fish), 121 bytes

var QUESTION_ID=66285,OVERRIDE_USER=44713;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>


25 Answers 25


LabVIEW, 38 LabVIEW Primitives

"slightly" modified, now sets the ranges by scanning for () and [] and adding the index to the numbers.


  • 5
    \$\begingroup\$ By having a language that requires a fancy gif, you have immediately gained ∞ rep. GG. +1 \$\endgroup\$ Commented Dec 11, 2015 at 12:38

Vyxal, 24, 18 bytes


Try it Online!

I'm actually really proud of this answer, because it uses the new modifier parsing of 2.6.

With syntax highlighting:

syntax highlighted version


₌                  # Apply the following to the same stack:
 ≬                 #   The next 3 elements as a single lambda, taking argument n:
  k+iE             #     eval(n[1:-1]) - the two numbers separated by a comma
₌                  #   and
      ₍ht          #   [n[0], n[-1]] - the range brackets
         ‛(]f=     # Does the first bracket equal "(" and does the last bracket equal "]" - this determines how much to offset the range; because the two numbers in the original input will be passed to Vyxal's range function which acts like python's range() function
              +    # add those offsets: an exclusive range start means the first number needs to be incremented because range() includes the first argument. an inclusive range start means the last number needs to be incremented because range() stops before the last argument.
               ÷r  # push the range between the two numbers + their offsets
                 Π # and take the product

Minecraft 15w35a+, program size 638 total (see below)

Same as my answer here, but modified. Since Minecraft has no string input, I took the liberty of keeping scoreboard input. If that is a problem, consider this answer non-competitive.

enter image description here

This calculates PI a,b with inclusive / exclusive specified by the two levers. enter image description hereInput is given by using these two commands: /scoreboard players set A A {num} and /scoreboard players set B A {num}. Remember to use /scoreboard objectives add A dummy before input.

Scored using: {program size} + ( 2 * {input command} ) + {scoreboard command} = 538 + ( 2 * 33 ) + 34 = 638.

This code corresponds to the following psuedocode:

R = 1
T = A
  R *= A
  A += 1
  if A == B:
    if A.exclusive:
      R /= T
    if B.exclusive:
      R /= B
    print R
    end program

Download the world here.


Python 2, 72 bytes

lambda s:reduce(int.__mul__,range(*eval(s[1:-1]+'+'+`']'in s`))[s<'[':])

To extract the numbers we evaluate s[1:-1], the input string with ends removed, which gives a tuple. The idea is to get the range of this tuple and take the product.

lambda s:reduce(int.__mul__,range(*eval(s[1:-1]))

The fudging happens to adjust the endpoints. The upper endpoint is easy, just cut off the first element if the input starts with (, done as [s<'[':].

The other endpoint is trickier. Python doesn't have a clean way to conditionally remove the last element of a list because l[:0] removes the whole thing. So, we do something weird. We modify the tuple string before it is evaluated to tack on the string "+True" or "+False" depending on whether s ends in ] or ). The result is that something like 3,7 becomes either 3,7+False which is 3,7, or 3,7+True which is 3,8.

Alternate, prettier 72:

lambda s:eval("reduce(int.__mul__,range((s<'[')+%s+(']'in s)))"%s[1:-1])

Pyth, 20 bytes


Try it online: Demonstration or Test Suite


*FPW}\)ztW}\(z}FvtPz   implicit: z = input string
                 tPz   remove the first and last character of z
                v      evaluate, returns a tuple of numbers
              }F       inclusive range
        tW             remove the first number, if
          }\(z            "(" in z
  PW                   remove the last number, if
    }\)z                  ")" in z
*F                     compute the product of the remaining numbers

Ruby, 79 77 bytes

->s{a,b=s.scan /\-?\d+/;(a.to_i+(s[?[]?0:1)..b.to_i-(s[?]]?0:1)).reduce 1,:*}

79 bytes

->s{a,b=s.scan(/\-?\d+/).map &:to_i;((s[?[]?a:a+1)..(s[?]]?b:b-1)).reduce 1,:*}


-> s {
  a,b=s.scan /\-?\d+/    # Extracts integers from the input string, s
    a.to_i+(s[?[]?0:1).. # Increase start of the range by 1 if s contains `(`
    b.to_i-(s[?]]?0:1)   # Decrease end of the range by 1 if s contains `)`
  ).reduce 1,:*


->s{a,b=s.scan /\-?\d+/;(a.to_i+(s[?[]?0:1)..b.to_i-(s[?]]?0:1)).reduce 1,:*}["(2,5]"]
=> 60

Seriously, 31 bytes


Takes input as a string (wrapped in double quotes)

Try it online (input must be manually entered)


,#d@p@                             get input, take first and last character off and push them individually
      ',@s`εj≈`Mi                  split on commas, map: join on empty, cast to int; explode list
                 (@)']=+)'(=+      increment start and end if braces are ( and ] respectively (since range does [a,b))
                             xπ    make range, push product

JavaScript (ES6), 68 bytes

  • \$\begingroup\$ Welcome to Code Golf, and nice answer! \$\endgroup\$ Commented Dec 7, 2021 at 14:30

Julia 0.4, 75 bytes


Try it online!

This is an anonymous function that accepts a string and returns an integer. To call it, give it a name, e.g. f=s->....


function f(s::AbstractString)
    # Extract the numbers in the input
    x = map(parse, split(s[2:end-1], ","))

    # Construct a range, incrementing or decrementing the endpoints
    # based on the ASCII value of the surrounding bracket
    r = x[1]+(s[1] == 40):x[2]-(s[end] == 41)

    # Return the product over the range
    return prod(r)

Python 3, 104

for x in range(t+1,int(r[:-1])+(r[-1]>'[')):t*=x

Takes input from stdin.

  • \$\begingroup\$ we actually posted our answers in the same second O.o \$\endgroup\$
    – Eumel
    Commented Dec 10, 2015 at 15:40
  • \$\begingroup\$ @Eumel That should be a badge. \$\endgroup\$ Commented Dec 10, 2015 at 15:41
  • \$\begingroup\$ ill actually post that on Meta right now^^ \$\endgroup\$
    – Eumel
    Commented Dec 10, 2015 at 15:42
  • \$\begingroup\$ @Eumel: Actually you posted yours 1 second before Morgan Thrapp's \$\endgroup\$
    – user46167
    Commented Dec 11, 2015 at 2:11
  • \$\begingroup\$ oh really? it showed answered n seconds ago on both answers \$\endgroup\$
    – Eumel
    Commented Dec 11, 2015 at 8:47

MATLAB, 86 70 bytes


This also works with Octave. You can try online here. I have added the code as a script to that workspace, so you can just enter productRange at the prompt, then enter your input, e.g. '(2,5]'.

So the code first scans the input to extract the brackets and the numbers together:


This returns an array which is made of [bracket, number, number, bracket].

The array is compared with 42, actually any number between 42 and 90 inclusive will do. This determines which sort of bracket it was, giving a 1 if it is an exclusive bracket, and a 0 if an inclusive bracket.


Finally, we display the product of the required range:


The product is of numbers staring with the first number s(2) plus the first bracket type a(1) (which is a 1 if an exclusive bracket), ranging up to and including the second number s(3) minus the second bracket type a(4). This gives the correct inclusive/exclusive range.


PowerShell, 146 104 Bytes


Golfed off 42 bytes by changing how the numbers are extracted from the input. Woo!

param($i)                          # Takes input string as $i
$a,$b=$i.trim("[]()")-split','     # Trims the []() off $i, splits on comma,
                                   # stores the left in $a and the right in $b

# Index into a dynamic array of either $a or $a+1 depending upon if the first
# character of our input string is a ( or not
# .. ranges that together with
# The same thing applied to $b, depending if the last character is ) or not
# Then that's joined with asterisks before
# Being executed (i.e., eval'd)

Perl 6, 60 bytes

{s/\((\-?\d+)/[$0^/;s/(\-?\d+)\)/^$0]/;s/\,/../;[*] EVAL $_}

There is a bit of mis-match because the way you would write the (2,5] example in Perl 6 would be 2^..5 ([2^..5] also works).
So I have to swap (2 with [2^, and , with .., then I have to EVAL it into a Range.


# give it a name
my &code = {...}

# the `$ =` is so that it gets a scalar instead of a constant

say code $ = '(2,5)'; # 12
say code $ = '[2,5)'; # 24
say code $ = '(2,5]'; # 60
say code $ = '[2,5]'; # 120

say code $ = '(-4,0)' # -6
say code $ = '[-4,0)' # 24
say code $ = '(-4,0]' # 0
say code $ = '[-4,0]' # 0

say code $ = '(-4,-1)' # 6
say code $ = '[-4,-1)' # -24
say code $ = '(-4,-1]' # -6
say code $ = '[-4,-1]' # 24

# this is perfectly cromulent,
# as it returns the identity of `*`
say code $ = '(3,4)'; # 1

Mathematica, 128 bytes


This is too long... Currently thinking about a StringReplace + RegularExpression solution.


JavaScript (ES6), 90 bytes



  eval(`                    // use eval to allow for loop without return or {}
      n=s.match(/-*\\d+/g), // n = array of input numbers [ a, b ]
      i=n[0],               // i = current number to multiply the result by
      c=s[0]<"["||i;        // c = result, initialise to a if inclusive else 1
      ++i<+n[1]             // iterate from a to b
        +(s.slice(-1)>")"); // if the end is inclusive, increment 1 more time
      c*=i                  // multiply result
  `)                        // implicit: return c


var solution = s=>eval(`for(n=s.match(/-*\\d+/g),i=n[0],c=s[0]<"["||i;++i<+n[1]+(s.slice(-1)>")");)c*=i`)
<input type="text" id="input" value="(5,10]" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>


TI-Basic, 69 bytes

Input Str1

Output is stored in Ans and displayed. Replace randIntNoRep( with seq(I,I, (+3 bytes) if the calculator does not support it.


Wolfram Language (Mathematica), 57 bytes


Try it online!

Input a list of characters.

Fairly straightforward. Mathematica uses [ ] to introduce arguments, and Range is inclusive on both ends.

Wolfram Language (Mathematica), 69 bytes


Try it online!

Input a string.


Japt, 43 41 bytes


Try it online!


CJam, 34 bytes


Try it online


r       Read input.
)       Split off last character.
\       Swap rest of input to top.
(       Split off first character.
@       Rotate last character to top.
+       Concatenate first and last character, which are the two braces.
"[()]"  Push string with all possible braces.
2/      Split it into start and end braces.
\       Swap braces from input to top.
.#      Apply find operator to vector elements, getting the position of each brace
        from input in corresponding list of possible braces. The lists of braces
        are ordered so that the position of each can be used as an offset for the
        start/end value of the interval.
\       Swap remaining input, which is a string with two numbers separated by
        a comma, to top.
',/     Split it at comma.
:i      Convert the two values from string to integer.
.+      Element-wise addition to add the offsets based on the brace types.
~       Unwrap the final start/end values for the interval.
1$      Copy start value to top.
-       Subtract it from end value.
,       Build 0-based list of values with correct length.
f+      Add the start value to all values.
:*      Reduce with multiplication.

R, 102 104 bytes

f=function(s){x=scan(t=gsub('\\(|\\[|,|\\)|\\]',' ',s))+c(grepl('^\\(',s),-(grepl('\\)$',s)));prod(x[1]:x[2])}


    # remove delimiting punctuation from input string, parse and return an atomic vector
    x=scan(t=gsub('\\(|\\[|,|\\)|\\]',' ',s)) +
    # add /subtract from the range dependent on the `[)` pre/suf-fixes
    # get the product of the appropriate range of numbers

edit to allow negative numbers [at the expense of 2 more characters

  • \$\begingroup\$ Language?​​​​​​ \$\endgroup\$ Commented Dec 11, 2015 at 3:38
  • \$\begingroup\$ @ThisSuitIsBlackNot --R (and fixed in answer) \$\endgroup\$
    – mnel
    Commented Dec 11, 2015 at 4:22

JavaScript (ES6), 79

As an anonymous method


Test snippet



  r=F(t[0]),k=t[1],console.log(t[0]+' -> '+r+' (check '+k+ (k==r?' ok)':' fail)'))
<pre id=O></pre>


Japt, 25 bytes

Ugly as hell!

ůJ q, rÈ°+Uø'()õY-Uø')Ã×

Try it (includes all test cases)


Haskell, 94 bytes

f=(\(h:a,_:b)->product[a!h..init b!last b]).span(','/=);c!')'=c!' '-1;c!'('=c!' '+1;c!_=read c

Try it online!


Julia 0.4, 64 bytes


Try it online!

Based on Alex A's answer

Julia 1.0, 69 bytes


Try it online!


Pip, 20 bytes


Replit! Or, verify all test cases with this 22-byte version in Pip Classic: Try it online!


Conveniently, , is Pip's range operator; it is inclusive on the lower end and exclusive on the upper end. So if we turn the brackets into appropriate tweaks to the numbers, we can use eval to generate the range.

   aR                 In the input, replace each string in
      "(][)"           This string
     ^                 Split into a list of characters
                      with the corresponding string in
            [      ]  this list:
             'U        ( becomes U (increment the following number)
               "+1"    ] becomes +1 (add 1 to the preceding number)
                       [ and ) don't have a corresponding replacement, so they are
                       simply deleted (leaving the numbers unchanged)
  V                   Evaluate the result as a Pip expression
$*                    Fold on multiplication

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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