[Question]
  [
## Background
An **almost regular hexagon** is a hexagon where
* all of its internal angles are 120 degrees, and
* pairs of the opposite sides are parallel and have equal lengths (i.e. a [zonogon](https://en.wikipedia.org/wiki/Zonogon)).
The following is an example of an almost regular hexagon, with side lengths 2 (red), 4 (blue), and 3 (yellow).
![](https://i.stack.imgur.com/ZK0vS.png)
A **triangular domino** is a domino made of two unit triangles. A **triangular domino tiling** is a tiling on a shape using triangular dominoes. The following is a possible triangular domino tiling of the above shape (each color represents an *orientation* of each triangular domino):
![](https://i.stack.imgur.com/RQ4tn.png)
## Challenge
Given the lengths of the three sides of an almost regular hexagon, find the number of distinct triangular domino tilings. The three sides will be always positive integers.
## Alternative description
The second image shows that such a tiling can be viewed as an isometric view of stacked unit cubes. Now let's assign three directions to three axes in 3D:
* `x` = down-right / southeast / SE (blue edges in the first image)
* `y` = down-left / southwest / SW (red edges)
* `z` = up / north / N (yellow edges)
Then the stacked unit cubes can be represented as an `x`-by-`y` 2D array, whose items represent the height of the stack at that position. So the above challenge is equivalent to the following:
> 
> Given three positive integers `x`, `y`, and `z`, find the number of `x`-by-`y` arrays whose elements are between 0 and `z` inclusive and all rows and columns are in decreasing order.
> 
> 
> 
It happens that this is one definition of [plane partition](http://mathworld.wolfram.com/PlanePartition.html) in the form of \$ PL(x,y,z) \$, and it has a closed-form formula:
$$
PL(x,y,z) = \prod\_{i=1}^x \prod\_{j=1}^y \prod\_{k=1}^z \frac{i+j+k-1}{i+j+k-2}
$$
## Scoring and winning criterion
Standard [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'") rules apply. The shortest code in bytes wins.
Note that a submission is valid even if it suffers from integer overflows or floating-point inaccuracies, as long as the underlying algorithm is correct.
## Test cases
```
x,y,z => output
---------------
1,1,1 => 2
1,1,2 => 3
1,2,3 => 10
2,3,1 => 10 (the order of inputs doesn't matter, since it's the same hexagon)
2,3,4 => 490
3,4,2 => 490
3,3,5 => 14112
```
  
[Answer]
# [APL (Dyalog Classic)](https://www.dyalog.com/), 14 bytes
```
×/1+1÷1+∘,1⊥¨⍳
```
[Try it online!](https://tio.run/##SyzI0U2pTMzJT9dNzkksLs5M/v@ob6qn/6O2CQb/D0/XN9Q2PLzdUPtRxwwdw0ddSw@teNS7@X8aUPZRbx9EYVfzofXGj9omAnnBQc5AMsTDM/h/moKhgpGCMVcaiFQwAQA "APL (Dyalog Classic) – Try It Online")
Uses 0 indexing with `⎕IO←0`.
### Explanation:
```
             ⍳     ⍝ Cartesian product of the ranges from 0 to n-1
          1⊥¨      ⍝ Sum of each element (using base 1)
         ,         ⍝ Flattened
        ∘          ⍝ Composed with
  1+1÷1+           ⍝ 1 + 1/(n+1)
×/                 ⍝ And reduced by multiplication
```
[Answer]
# [Perl 6](https://github.com/nxadm/rakudo-pkg), ~~38~~ 30 bytes
```
{[*] map 1+1/(*+1),[X+] ^<<@_}
```
[Try it online!](https://tio.run/##Jc7RioMwEAXQ581X3KdWm4BG3YUudulnFKxdpI5V0ESSLGwp/XabVOblDFzuzExm/FqmOzYdDlge1a7G1MyQXCbRjstYVCde41KWx9/n0mmDaBwU2RgP9mGbOzrwspy@b8m55Ul1yWv2XKTwg8MPMhaYBeaemcgDZcq81oRMEbmeoE1LBrrDoOY/Z9Fqsmrr/C/OkRGwg7oSBre1CHHbTISe/pubVvG7rQhtxT5lnuvFdcnF5/tOIWX2Ag "Perl 6 – Try It Online")
Based on the formula given in the question
### Explanation:
```
{                            }    # Anonymous code block
                        ^<<@_     # Map each input to the range 0 to n-1
                   [X+]           # Get the cross product of sums
     map          ,               # Map these to
         1+1/(*+1)                # 1+1/(n+1) = (n+2/n+1)
                                  # Which is the formula compensating for the 0 based range
 [*]                              # And reduce by multiplication
```
[Answer]
# [Wolfram Language (Mathematica)](https://www.wolfram.com/wolframscript/), 28 bytes
```
Array[1+1/(##-2)&,#,1,1##&]&
```
[Try it online!](https://tio.run/##y00syUjNTSzJTE78n6Zg@9@xqCixMtpQ21BfQ1lZ10hTTUdZx1DHUFlZLVbtf0BRZl5JtLKCrp1CWrRybKyCmoK@g0J1taGOAgjV6ihAmUZQppGOgjGICaKhCiBMExATREPVGoNFTWtr/wMA "Wolfram Language (Mathematica) – Try It Online")
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), ~~13~~ 11 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
L.«â€˜OÍz>P
```
[Try it online](https://tio.run/##yy9OTMpM/f/fR@/Q6sOLHjWtOT3H/3BvlV3A///RxjomOkaxAA) or [verify all test cases](https://tio.run/##yy9OTMpM/V9Waa@k8KhtkoKSfeV/H71Dqw8vetS05vQc/8O9VXYB/3X@R0cb6gBhrI4CmGEEYRjpGIMYQAoiBWKYgBhACqLGGChiGhsLAA).
**Explanation:**
Uses the derived formula (inspired by *@JoKing*'s answers):
$$PL(x,y,z) = \prod\_{i=1}^x \prod\_{j=1}^y \prod\_{k=1}^z \frac{1}{i+j+k-2}+1$$
```
L            # Map each value in the (implicit) input-list to an inner [1,v]-ranged list
 .«          # (Right-)reduce these lists by:
   â         #  Taking the cartesian product between two lists
    €˜       # Then flatten each inner list
      O      # Sum each inner list
       Í     # Decrease all by 2
        z    # Take 1/v for each value
         >   # Increase all by 1
          P  # And take the product of that
             # (after which the result is output implicitly)
```
[Answer]
# [Haskell](https://www.haskell.org/), 44 bytes
```
foldr(\r k->k+k/(sum r-2))1.mapM(\n->[1..n])
```
[Try it online!](https://tio.run/##BcFNEkAgGADQq3wLixqVobHkBk5QLRqE6UdTXN/nvdNWv4eAbtLo7rAVogt4PvvWd6S@EQofKO1FtHkhOvFZ9UIkQzHaK8EEuVzpgQYcKMkkGw1@qwv2qMjXnH8 "Haskell – Try It Online")
Outputs floats. Thanks to @H.PWiz for 4 bytes using a fold.
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), ~~9~~ 8 bytes
```
Œp§_2İ‘P
```
[Try it online!](https://tio.run/##y0rNyan8///opIJDy@ONjmx41DAj4P/h9kdNayL//4821AHCWB0wbQSmjXSMgTSQBIuDaBMgDSTB8sZAvmksAA "Jelly – Try It Online")
Uses the altered form of the closed form expression. Takes input as a list `[x,y,z]`.
```
Œp          Cartesian product of the list.
            (Each element, being an integer, is implicitly converted to a range.)
  §         Sum the items of each triplet,
   _2       subtract 2 from each sum,
     İ      take the reciprocal of each lowered sum,
      ‘     increment each reciprocal,
       P    and return the product of the increments reciprocals.
```
[Answer]
# [K (ngn/k)](https://codeberg.org/ngn/k), ~~17~~ 15 bytes
```
%/*/'2 1+\:+/!:
```
[Try it online!](https://ngn.bitbucket.io/k#eJxLs1LV19JXN1Iw1I6x0tZXtOLiKrGqVomurCuySlOosE7Iz7bWSEhLzMyxrrCutC7SjK3lKok2VABCayO9WCjbyNoYyjZSMLY2NABzgEygIiSOibWJJYQHZAP1IHjGCqbWhiaGhkATFfTzy1KL0nLyywH9wicM)
last test fails because of an overflow
uses a 0-indexed version of the formula:
\$PL(x,y,z)=\prod\_{i=0}^{x-1}\prod\_{j=0}^{y-1}\prod\_{k=0}^{z-1}\frac{i+j+k+2}{i+j+k+1}\$
[Answer]
# [Bash](https://www.gnu.org/software/bash/), 75
Inputs are passed as a comma-separated list.
```
e={1..${1//,/\}+\{1..}}
eval eval echo \\$\[1 *\\\($e-1\\\) /\\\($e-2\\\) ]
```
[Try it online!](https://tio.run/##LYhLDsIwDET3PsUssmghNEoKK8RJMItAU6UfUQkkWEQ5e3ABW/PsN1f/jKWvaqQSTsk2jUrWGG04b3nVnCm8/IwfbnEBs@KzxYaZKxV2Vm4N8zf3tUvJ9I7DHPAIvsOAEdMR3UKQ6aEGrUatJuqWeygWsrTSCR1akkizck8S6Vv5Dx8 "Bash – Try It Online")
The last test fails due to integer overflow.
[Answer]
# JavaScript (ES6), ~~73 65~~ 64 bytes
```
(x,y,z)=>(g=n=>!n||g(n-1)/(s=n%z-~(n/z%y)+n/z/y%x|0)*-~s)(x*y*z)
```
[Try it online!](https://tio.run/##bc1BDoIwFATQvafABcn/2FpacOGi3IUgEI35NdYY2hCuXrtCAmQWs3jJzKP@1rZ5318fTubWhk4HGJhjHnUFvSZdHWkceyAuUYDVlHo@AQmfOjzFEi4dxhwzPlmEIXOZx9AYsubZnp@mhw4ki0FMhEh0lajDVtWsxUYVK2aV@YojLqZ3uZy5vK496uJ7zwt2@c@XUqrwAw "JavaScript (Node.js) – Try It Online")
### Commented
```
(x, y, z) => (              // (x, y, z) = input
  g = n =>                  // g is a recursive function taking a counter n
    !n ||                   //   if n = 0, stop recursion and return 1
    g(n - 1) / (            //   otherwise, divide the result of a recursive call by:
      s =                   //     s defined as the sum of:
        n % z               //       k, 0-indexed: n mod z
        - ~(n / z % y)      //       j, 1-indexed: floor((n / z) mod y) + 1
        + n / z / y % x | 0 //       i, 0-indexed: floor((n / z / y) mod x)
    )                       //   
    * -~s                   //   and multiply by s + 1
)(x * y * z)                // initial call to g with n = x * y * z
```
[Answer]
# [J](http://jsoftware.com/), 25 bytes
-4 bytes thanks to Bubbler!
```
[:*/1+1%1+1#.&>[:,@{i.&.>
```
[Try it online!](https://tio.run/##y/qfVmyrp2CgYAXEunoKzkE@bv@jrbT0DbUNVYFYWU/NLtpKx6E6U09Nz@6/JpeSnoJ6mq2euoKOQloxV2pyRr5CmpqdgiEIWoNIIyBppGBsDcRAERBpYg3EQHFjINtU4T8A "J – Try It Online")
# [J](http://jsoftware.com/), 29 bytes
```
[:*/[:(1+1%1++/)@>[:,@{<@i."0
```
[Try it online!](https://tio.run/##FYg7CoAwFAT7nGIR/EZi4qd5Uck9UopBbSwsxbPHF5YZlrlieBYFDYKOnprOU2WkyY2UXe1WT617Z3eqTMdaZAplWFSJFh8hPELs23EjFCtMmk3u2T0Gy3BJHi3DfeA/If4 "J – Try It Online")
A [J](http://jsoftware.com/) port of [@JoKing's APL answer](https://codegolf.stackexchange.com/a/196081/75681) (don't forget to upvote it), but twice as long. I'll try to golf it...
[Answer]
# [J](http://jsoftware.com/), 18 bytes
```
*/@,@(1+%)1++/&i./
```
[Try it online!](https://tio.run/##JcrBCoMwEATQ@37FULBWYxMnSQ8NCNKCJ@mhH6Ho/9/jamCHx@zunm8W9YIhoUaHHknztPj@5ym3buzGB03V0Bh336zLjaxDWjKxgqAU/aVHEK8G3RejBDXqPVz9Jb@PPf/A/pz4LmEk/QE "J – Try It Online")
Takes `z` on its left and `x y` on the right.
Uses [modified formula by Peter Taylor](https://codegolf.stackexchange.com/questions/196070/triangular-domino-tiling-of-an-almost-regular-hexagon#comment466589_196089):
$$
\begin{align}
\prod\_{i=1}^x \prod\_{j=1}^y \frac{i+j+z-1}{i+j-1} &= \prod\_{i=1}^x \prod\_{j=1}^y \left(1 + \frac{z}{i+j-1}\right) \\
&= \prod\_{i=0}^{x-1} \prod\_{j=0}^{y-1} \left(1 + \frac{z}{i+j+1}\right)
\end{align}
$$
### How it works
```
*/@,@(1+%)1++/&i./  NB. Left =: z, Right =: x y
                 /  NB. Reduce over x y...
              &i.   NB.   Apply range (n -> 0..n-1) to each item and
            +/      NB.   Outer product by addition
          1+        NB. Increment each, so that each cell has i+j+1
    @(1+%)          NB. Compute 1+z/(i+j+1) for each i and j
*/@,                NB. Flatten the matrix and compute the product
```
[Answer]
# [Ruby](https://www.ruby-lang.org/), ~~85~~ 75 bytes
```
->x,y,z{w=->t{(0...x*y*z).map{|r|r%x+(r/=x)%y+r/y+t}.reduce &:*};w[2]/w[1]}
```
[Try it online!](https://tio.run/##TcxJDoMgAIXhfU9B0tgoIsjQRdvARYiLDrozMUQDOJydkg5q3u5L3m@Ghw@NDIVyyKNxsrJQ/ZSWGGMHPRwz3N67aTazSVyeGiJdlvjcEJ/3Czb1a3jW4HSFy81qVhGrabWEDjSaorgKHAkBUgF2@Btbjf@MIb4aLT8YaXfeoVhRXL4abdfclKPzFhCUsvAG "Ruby – Try It Online")
[Answer]
# [Icon](https://github.com/gtownsend/icon), ~~81, 78~~ 70 bytes
-8 bytes thanks to Peter Taylor
```
procedure f(x,y,z)
p:=1&p*:=(1+z/(seq()\x+seq()\y-1.))&\u
return p
end
```
[Try it online!](https://tio.run/##Tc69DoMgEADgWZ4CFwOVtkHbxcQnUYZGz4ShSK/Sii9v0Q5yN1y@3E9Od6NZV4tjB71DoAObhRcLJ7aqZWZPVc1kvlzZG16Mt3P@r/4sL5xnrSMIk0NDLQHTR2eeD20YJzQEfAA9/aKegA1p2jRShFSCJMnW3lnELER5MCAe3ng7GBDvlqF7V4rvz/wA "Icon – Try It Online")
[Answer]
# [Python 3.8 (pre-release)](https://docs.python.org/3.8/), ~~79~~ 62 bytes
Based on @galen-ivanov's [answer](https://codegolf.stackexchange.com/a/196089/32604).
-17 bytes thanks to Jo King and xnor.
```
lambda x,y,z,t=1:[t:=t+t*z/(i%x-~i//x)for i in range(x*y)][-1]
```
[Try it online!](https://tio.run/##VcuxCsMgGATgvU/hUvBPDWJsIQR8kjSDIbUVWiPyD5qhr27tptz0cXc@4Wt3cvQhG3XPb/1ZN00iS@xgqMQ046Twgt3BqT3H/ms5j2D2QCyxjgTtng8auwTL3Isl@2AdUkMFKwE41R4aD0xWLmr2f18rFzV/WfobQP4B "Python 3.8 (pre-release) – Try It Online")
[Answer]
# [Charcoal](https://github.com/somebody1234/Charcoal), 25 bytes
```
ＮθＮηＦＮＦηＦθ⊞υ⊕⁺λ⁺κιＩ÷Π⊕υΠυ
```
[Try it online!](https://tio.run/##TYwxDsMgDEX3nMKjLdGl7ZaxXbJUXIECFaiENIBzfUpRpMbL139fz9qppBcVap3ih8uD56dNuNI4HLtr/bUkwCMkgs7cniuB5OyQBUxRJzvbWKxBGThjENDzLcBTu3GQyceCN5VLe1rufvPGokyLYf0jf5@JmrwP3OVaz3CBaz1t4Qs "Charcoal – Try It Online") Link is to verbose version of code. Explanation: Uses the 0-indexed version of the given formula.
```
ＮθＮηＦＮＦηＦθ
```
Input the three dimensions and loop over the implicit ranges.
```
⊞υ⊕⁺λ⁺κι
```
Take each incremented sum and save it in a list, thus flattening the Cartesian product.
```
Ｉ÷Π⊕υΠυ
```
Divide the product of the incremented list by the product of the list and cast to string for implicit print.
[Answer]
# [Japt](https://github.com/ETHproductions/japt), 18 [bytes](https://en.wikipedia.org/wiki/ISO/IEC_8859-1)
```
mo rï Ëc rÄ pJ ÄÃ×
```
[Try it](https://petershaggynoble.github.io/Japt-Interpreter/?v=1.4.6&code=bW8gcu8gy2MgcsQgcEogxMPX&input=W1sxLDIsM10sWzIsMyw0XV0KLW0)
input as array
```
mo rï               // cartesian product [0,n)
      Ëc            // flatten each triplet
         rÄ         // reduce with initial value of 1 ( -2 +3=>triplets 0 to 1
            pJ      // raised -1
               Ä    // +1
                Ã×  // reduce by multiplication
Implicit output, -m flag to run the program for each input
```
]