39
\$\begingroup\$

Not to be confused with Find the factorial!

Introduction

The factorial of an integer n can be calculated by $$n!=n\times(n-1)\times(n-2)\times(...)\times2\times1$$

This is relatively easy and nothing new. However, factorials can be extended to double factorials, such that $$n!!=n\times(n-2)\times(n-4)\times(...)\times4\times2$$ for even numbers, and $$n!!=n\times(n-2)\times(n-4)\times(...)\times3\times1$$ for odd numbers. But we're not limited to double factorials. For example $$n!!!=n\times(n-3)\times(n-6)\times(...)\times6\times3$$ or $$n!!!=n\times(n-3)\times(n-6)\times(...)\times5\times2$$ or $$n!!!=n\times(n-3)\times(n-6)\times(...)\times4\times1$$ depending on the starting value.

In summary: $${\displaystyle n!^{(k)}={\begin{cases}1&{\text{if }}n=0 \\n&{\text{if }}0<n\leq k\\n\cdot\left({(n-k)!}^{(k)}\right)&{\text{if }}n>k\end{cases}}}$$ where $${\displaystyle n!^{(k)}=n\underbrace{!\dots!}_{k}}$$ Or, in plain English: Subtract the factorial count from the base number repeatedly and multiply all resulting positive integers.

The Challenge

Write a function that will calculate any kind of repeated factorial for any non-negative integer.

Input

Either

  • A string containing a non-negative base-ten integer, followed by 1 or more exclamation marks. E.g. "6!" or "9!!" or "40!!!!!!!!!!!!!!!!!!!!".

or

  • The same values represented by two integers: one non-negative base value and one positive value representing the factorial count. This can be done according to any format from the default I/O rules.

Output

The result of said calculation.

Challenge remarks

  • 0! equals 1 by definition. Your code must account for this.
  • The factorial count is limited by $$ 0 < factorial~count \leq base~value $$outside this range, you are free to output whatever. Aside from 0!, which is the only exception to this rule.

Examples

Input                              Output

3!!!                               3
0!                                 1
6!                                 720
9!!                                945
10!!!!!!!!                         20
40!!!!!!!!!!!!!!!!!!!!             800
420!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  41697106428257280000000000000000

Try it with an ungolfed Python implementation: Try it online!

General remarks

\$\endgroup\$
8
  • 7
    \$\begingroup\$ The examples list 0! but the challenge remarks say that the factorial count will be less than or equal to the base value. \$\endgroup\$ Commented Aug 5, 2019 at 13:09
  • 1
    \$\begingroup\$ Wouldn't 3!!! be zero? n*(n-3) = 3*(3-3) = 0. \$\endgroup\$
    – ouflak
    Commented Aug 5, 2019 at 13:31
  • 2
    \$\begingroup\$ @ouflak If it works like 1!, not really. It's more like 1! = 1. 2!! = 2. 3!!! = 3. There's no calculation, because you are at the end of the recursiveness. No 0 in products or else every single factorial would drop down to 0 in the end. \$\endgroup\$ Commented Aug 5, 2019 at 14:16
  • 4
    \$\begingroup\$ 3!!!!!!! should not be undefined—it should just yield the answer 3. It's the same as 1!!=1 (not undefined). Also your input specification says that there will always be at least one !, so the first example 3 doesn't fit the specification. \$\endgroup\$ Commented Aug 5, 2019 at 18:04
  • 4
    \$\begingroup\$ @FabianRöling: But that's not what this is. It's not (3!)! instead it's removing terms from a factorial. It's a misleading name; I came in assuming it was going to be applying the Factorial function repeatedly in a chain and had to read carefully to see what it actually was. Fortunately the question does explain it clearly. A better name might be stride factorial or step factorial or something. \$\endgroup\$ Commented Aug 8, 2019 at 5:31

41 Answers 41

17
\$\begingroup\$

R, 33 bytes

function(n,k)prod(seq(n+!n,1,-k))

Try it online!

Handles \$n=0\$ by adding the logical negation of \$n\$.

\$\endgroup\$
14
\$\begingroup\$

ArnoldC, 702 698 634 bytes

LISTEN TO ME VERY CAREFULLY f
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE n
I NEED YOUR CLOTHES YOUR BOOTS AND YOUR MOTORCYCLE p
GIVE THESE PEOPLE AIR
HEY CHRISTMAS TREE r
YOU SET US UP 1
HEY CHRISTMAS TREE c
YOU SET US UP 0
STICK AROUND n
GET TO THE CHOPPER r
HERE IS MY INVITATION r
YOU'RE FIRED n
ENOUGH TALK
GET TO THE CHOPPER n
HERE IS MY INVITATION n
GET DOWN p
ENOUGH TALK
GET TO THE CHOPPER c
HERE IS MY INVITATION 0
LET OFF SOME STEAM BENNET n
ENOUGH TALK
BECAUSE I'M GOING TO SAY PLEASE c
GET TO THE CHOPPER n
HERE IS MY INVITATION 0
ENOUGH TALK
YOU HAVE NO RESPECT FOR LOGIC
CHILL
I'LL BE BACK r
HASTA LA VISTA, BABY

Try it online!

Translated to pseudocode:

f(n,p) {
  r=1;
  c=0;
  while (n) {
    r=r*n;
    n=n-p;
    c=n<0;
    if (c) n=0;
  }
  return r;
}

Note: ArnoldC has only one type of data: 16-bit signed integer. Hence I cannot test the 420!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! case.

\$\endgroup\$
3
  • \$\begingroup\$ Just curious about your psuedocode. What is the variable 'c' for? \$\endgroup\$
    – ouflak
    Commented Aug 6, 2019 at 16:28
  • \$\begingroup\$ @ouflak I edited my answer a couple of times and forgot it. The c variable actually stores the value of the comparison between n and 0. \$\endgroup\$
    – Charlie
    Commented Aug 6, 2019 at 16:40
  • \$\begingroup\$ +1 and I borrowed it (minus the 'c') for my LUA answer. \$\endgroup\$
    – ouflak
    Commented Aug 6, 2019 at 16:42
13
\$\begingroup\$

Jelly, 4 bytes

RṚmP

Try it online!

How? Given \$n\$ and \$k\$, it first generates the range \$n,\cdots, 1\$ (with RṚ), then with m it keeps every \$k^{\text{th}}\$ element of this range (so \$n, n-k, n-2k,\cdots,n-\lfloor n/k\rfloor k\$), and finally multiplies them using P.

\$\endgroup\$
8
  • \$\begingroup\$ Works well, and so simple in the end. I don't know Jelly at all but at least it looks good :) \$\endgroup\$ Commented Aug 5, 2019 at 14:20
  • 1
    \$\begingroup\$ @V.Courtois Given \$n\$ and \$k\$, it first generates the range \$n,\cdots, 1\$ (with RṚ), then with m it keeps every \$k^{\text{th}}\$ element of this range (so \$n, n-k, n-2k,\cdots,n-\lfloor n/k\rfloor k\$), and finally multiplies them using P. Just the straightforward approach. Edit: I added this explanation in the answer. \$\endgroup\$
    – Mr. Xcoder
    Commented Aug 5, 2019 at 14:38
  • \$\begingroup\$ Hah thank you very much. One day I might want to golf in this language so I'll have to learn those monads, dyads etc. \$\endgroup\$ Commented Aug 5, 2019 at 14:58
  • \$\begingroup\$ Alternative that looks like CJam: r1mP. \$\endgroup\$ Commented Aug 5, 2019 at 18:07
  • 1
    \$\begingroup\$ @KyeWShi Jelly has its own codepage, so each of the 256 characters it contains is encoded as 1 byte. \$\endgroup\$
    – Mr. Xcoder
    Commented Aug 7, 2019 at 13:41
8
\$\begingroup\$

APL (Dyalog Extended), 7 bytesSBCS

Anonymous tacit prefix function. Takes [n,b] as argument.

×/-\…1¨

Try it online!

 one for each element of the argument; [1,1]

-\ cumulative difference; [n,n-b]

 range using second element of left argument as indicator of step, e.g. [9,7] continues with 5

×/ product

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

Haskell, 21 bytes

n%a=product[n,n-a..1]

Try it online!

Combining the built-in product function with stepped range enumeration beats what I could code up recursively (even with flawr saving a byte).

22 bytes

n%a|n<1=1|m<-n-a=n*m%a

Try it online!

Here's a solution taking input in string format like 9!!, which I think is more interesting.

42 bytes

(\[(n,a)]->product[n,n-length a..1]).reads

Try it online!

\$\endgroup\$
1
  • 3
    \$\begingroup\$ I think you could shorten the recursive solution to n%a|n<1=1|m<-n-a=n*m%a \$\endgroup\$
    – flawr
    Commented Aug 5, 2019 at 8:41
6
\$\begingroup\$

Pyth, 6 bytes

These are all equivalent 6-byters:

*F:Q1E
*F:E1Q
*F%E_S

Try it online! (*F:Q1E)

Or, 11 bytes, taking input as a string:

*F:.vQ1/Q\!

Test suite.

\$\endgroup\$
5
\$\begingroup\$

JavaScript (ES6), 21 bytes

Takes input as (k)(n).

k=>g=n=>n<1||n*g(n-k)

Try it online!

Or 24 bytes to support BigInts.


JavaScript (ES6), 55 bytes

Takes input as a string, using the format described in the challenge.

s=>(a=s.split`!`,k=a.length-1,g=n=>n<1||n*g(n-k))(a[0])

Try it online!

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

Whitespace, 91 bytes

[S S S T    N
Push_1][S N
S _Duplicate_1][S N
S _Duplicate_1][T   N
T   T   _Read_STDIN_as_integer_(base)][T    T   T   _Retrieve_base][S S S N
_Push_0][T  N
T   T   _Read_STDIN_as_integer_(factorial)][N
S S N
_Create_Label_LOOP][S N
S _Duplicate_base][S S S T  N
_Push_1][T  S S T   _Subtract][N
T   T   S N
_If_negative_jump_to_Label_PRINT_RESULT][S N
S _Duplicate_base][S T  S S T   S N
_Copy_0-based_2nd_(result)][T   S S N
_Multiply][S N
T   _Swap_top_two][S S S N
_Push_0][T  T   T   _Retrieve_factorial][T  S S T   _Subtract][N
S N
N
_Jump_to_Label_LOOP][N
S S S N
_Create_Label_PRINT_RESULT][S N
N
_Discard_top][T N
S T _Print_result_as_integer]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

Try it online (with raw spaces, tabs and new-lines only).

Explanation in pseudo-code:

Integer result = 1
Integer base = STDIN as integer
Integer factorial = STDIN as integer
Start LOOP:
  If(base <= 0):
    Call function PRINT_RESULT
  result = result * base
  base = base - factorial
  Go to next iteration of LOOP

function PRINT_RESULT:
  Print result as integer to STDOUT
\$\endgroup\$
5
\$\begingroup\$

Python 2, 29 bytes

f=lambda n,b:n<1or n*f(n-b,b)

Try it online!

\$\endgroup\$
5
\$\begingroup\$

05AB1E, 10 8 7 bytes

ݦRIιнP

Input as two separated inputs: first input being base; second input being factorial.

Try it online or verify all test cases.

-2 bytes thanks to @Mr.Xcoder.
-1 byte thanks to @JonathanAllan.

Explanation:

Ý        # Create a list in the range [0, (implicit) base-input]
 ¦       # And remove the first item to make it the range [1, base]
         # (NOTE: this is for the edge case 0. For the other test cases simply `L` instead
         #  of `ݦ` is enough.)
  R      # Reverse this list so the range is [base, 1]
   Iι    # Uninterleave with the second input as step-size
         #  i.e. base=3, factorial=7: [[3],[2],[1],[],[],[],[]]
         #  i.e. base=10, factorial=8: [[10,2],[9,1],[8],[7],[6],[5],[4],[3]]
         #  i.e. base=420, factorial=30: [[420,390,360,...,90,60,30],[419,389,359,...],...]
     н   # Only leave the first inner list
      P  # And take the product of its values
         # (which is output implicitly as result)

Original 10 bytes answer:

L0KD¤-IÖÏP

Input as two separated inputs: first input being base; second input being factorial.

Try it online or verify all test cases.

Explanation:

L           # Create a list in the range [1, (implicit) base-input]
 0K         # Remove all 0s (edge case for input 0, which will become the list [1,0])
   D        # Duplicate this list
    ¤       # Get the last value (without popping)
            # (could also be `Z` or `¹` for max_without_popping / first input respectively)
     -      # Subtract it from each item in the list
      IÖ    # Check for each if they're divisible by the second factorial-input
        Ï   # In the list we copied, only leave the values at the truthy indices
         P  # And take the product of those
            # (which is output implicitly as result)
\$\endgroup\$
9
  • 1
    \$\begingroup\$ This 6-byter: LR²ιнP (Try it online!) works for every test case, except for 0. \$\endgroup\$
    – Mr. Xcoder
    Commented Aug 5, 2019 at 8:20
  • \$\begingroup\$ But I guess that 0 case can be fixed in at most 2 bytes. If you figure out a way to fix it, you may take it :) EDIT: Perhaps LR²ιн0KP for 8 bytes? \$\endgroup\$
    – Mr. Xcoder
    Commented Aug 5, 2019 at 8:20
  • \$\begingroup\$ @Mr.Xcoder Nice answer! Never even used uninterleave with a given step. :) \$\endgroup\$ Commented Aug 5, 2019 at 8:29
  • \$\begingroup\$ 0K should be unnecessary as 0! is an invalid input by the specification (even though it's been included in the examples) - I have commented about this. \$\endgroup\$ Commented Aug 5, 2019 at 19:10
  • 1
    \$\begingroup\$ ...and if 0! is in the input domain ݦRXιнP saves a byte. \$\endgroup\$ Commented Aug 5, 2019 at 19:15
4
\$\begingroup\$

Perl 6, 22 bytes

{[*] $^a,*-$^b...^1>*}

Try it online!

Anonymous codeblock that returns the product of the range starting from the first input, decreasing by the second until it is below 1, excluding the last number. This works for 0, since the base case of a the reduce by product is 1, so the output is 1.

\$\endgroup\$
4
\$\begingroup\$

x86-64 machine code, 12 bytes

Same machine code does the same thing in 32-bit mode, and for 16-bit integers in 16-bit mode.

This is a function, callable with args n=RCX, k=ESI. 32-bit return value in EAX.

Callable from C with the x86-64 System V calling convention with dummy args to get the real args into the right registers. uint32_t factk(int, uint32_t k, int, uint64_t n); I couldn't just use Windows x64 because 1-operand mul clobbers RDX, and we don't want REX prefixes to access R8/R9. n must not have any garbage in the high 32 bits so JRCXZ works, but other than that it's all 32-bit.

NASM listing (relative address, machine code, source)

 1                         factk:
 2 00000000 6A01             push 1
 3 00000002 58               pop rax             ; retval = 1
 4 00000003 E306             jrcxz  .n_zero      ; if (n==0) return
 5                         .loop:                ; do {
 6 00000005 F7E1              mul   ecx            ; retval *= n  (clobbering RDX)
 7 00000007 29F1              sub   ecx, esi       ; n -= k
 8 00000009 77FA              ja   .loop         ; }while(sub didn't wrap or give zero)
 9                         .n_zero:
10 0000000B C3               ret

0xc = 12 bytes


Or 10 bytes if we didn't need to handle the n=0 special case, leaving out the jrcxz.

For standard factorial you'd use loop instead of sub/ja to save 2 bytes, but otherwise the exact same code.


Test caller that passes argc as k, with n hard-coded.

align 16
global _start
_start:
  mov  esi, [rsp]
;main:
  mov  ecx, 9
  call factk

  mov  esi, eax
  mov  edx, eax
  lea  rdi, [rel print_format]
  xor  eax, eax
extern printf
  call printf
extern exit
  call exit

section .rodata
print_format: db `%#x\t%u\n`

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

APL (Dyalog Unicode), 11 bytesSBCS

Anonymous tacit infix function. Takes n as right argument and b as left argument.

×/1⌈⊢,⊢-×∘⍳

Try it online!

×∘⍳ multiply b by the ɩntegers 1 through n

⊢- subtract that from n

⊢, prepend n

1⌈ max of one and each of those

×/ product

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

Ruby, 25 bytes

f=->s,r{s<1?1:s*f[s-r,r]}

Try it online!

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

Wolfram Language (Mathematica), 22 21 bytes

1##&@@Range[#,1,-#2]&

Try it online!

-1 thanks to attinat: Times --> 1##&

Explanation: use Range to make a list of the values {n, n-k, n-2k, n-3k, ...}, stopping before going below 1 (i.e., stopping just right). Then multiply all numbers in this list with Times (or 1##&).

\$\endgroup\$
1
  • \$\begingroup\$ -1 byte with 1##& instead of Times \$\endgroup\$
    – att
    Commented Aug 5, 2019 at 17:49
3
\$\begingroup\$

Java 10, 44 bytes

f->b->{int r=1;for(;b>0;b-=f)r*=b;return r;}

Takes the factorial as first input, base as second.

Try it online.

This above doesn't work for the largest test case due to the limited integer range (32-bits). To fix this we can use BigIntegers, which coincidentally is exactly double the size - 88 79 bytes:

f->b->{var r=f.ONE;for(;b.signum()>0;b=b.subtract(f))r=r.multiply(b);return r;}

-9 bytes thanks to @OlivierGrégoire.

Try it online.

Explanation:

f->b->{       // Method with two integer parameters and integer return-type
  int r=1;    //  Result-integer, starting at 1
  for(;b>0;   //  Loop as long as the base is still larger than 0
      b-=f)   //    After every iteration: decrease the base by the factorial
    r*=b;     //   Multiply the result by the base
  return r;}  //  Return the result
\$\endgroup\$
2
3
\$\begingroup\$

Vyxal, 4 bytes

ɾṘḞΠ

Try it Online!

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

Knight, 34 33 bytes

;=p=xE P;=yP;W<0=x-x y=p*x pO+p!p

Try it online!

-1 byte thanks to Aiden Chow

\$\endgroup\$
3
  • \$\begingroup\$ 33 bytes: ;=pT;=xP;=yP;W<0x;=p*x p=x-Ex yOp. \$\endgroup\$
    – Aiden Chow
    Commented Aug 17, 2022 at 2:33
  • \$\begingroup\$ @AidenChow I tried that initially. That doesn't work for 0! as it will output true instead. \$\endgroup\$
    – naffetS
    Commented Aug 17, 2022 at 3:20
  • \$\begingroup\$ Oops didn't test it lol. What about this? ;=p=xE P;=yP;W<0=x-x y=p*x pO+p!p \$\endgroup\$
    – Aiden Chow
    Commented Aug 17, 2022 at 6:14
2
\$\begingroup\$

Japt, 8 bytes

TõUV f ×

Try it

-1 thanks to EoI pointing out how dumb uncaffeinated Shaggy can be!

\$\endgroup\$
2
  • \$\begingroup\$ kT can be replaced with f for 1 byte \$\endgroup\$
    – Gymhgy
    Commented Aug 5, 2019 at 9:47
  • 1
    \$\begingroup\$ @EmbodimentofIgnorance, of course it can! I knew it was too early for golf! :\ \$\endgroup\$
    – Shaggy
    Commented Aug 5, 2019 at 9:48
2
\$\begingroup\$

C (gcc), 41 bytes

r;f(n,k){for(r=1;n>0;n-=k)r*=n;return r;}

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ 36 bytes r;f(n,k){for(r=1;n>0;n-=k)r*=n;n=r;} for C(gcc) \$\endgroup\$
    – GPS
    Commented Aug 8, 2019 at 9:48
2
\$\begingroup\$

MathGolf, 7 6 bytes

╙╒x%ε*

Try it online!

Found a clever way to handle 0! without changing the other test cases. Takes input as k n (reverse order), which helps with implicit popping.

Explanation

╙        maximum of two elements (pops largest of k and n,
         which is n for every valid case except 0!, where 1 is pushed)
 ╒       range(1,n+1)
  x      reverse int/array/string
   %     slice every k:th element
    ε*   reduce list with multiplication
\$\endgroup\$
2
\$\begingroup\$

Attache, 21 19 bytes

${x<y∨x*$[x-y,y]}

Try it online! Pretty direct recursive implementation. (Note: true is essentially 1, as it can be used in arithmetic operations as 1.) This is one of the few programs I've written for this site where using a unicode operator saves bytes (1, to be precise).

Alternatives

20 bytes: ${x<y or x*$[x-y,y]}

21 bytes: Prod@${{_%y=x%y}\1:x}

27 bytes: ${x*[`1,$][x>y][x-y,y]∨1}

27 bytes: ${If[x>y,x*$[x-y,y],_or 1]}

27 bytes: ${x*[`1,$][x>y][x-y,y]or 1}

29 bytes: ${If[x>y,x*$[x-y,y],_+not _]}

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

Scala, 53 bytes

Takes two arguments, the first being the number and the second being the ! count.
Somehow breaks on the big test case. This step range costs many bytes in the end because of this -1* so improvements ought to be possible by refactoring.
I have, as always, a doubt about how we count bytes for function declarations, because everyone doesn't do the same way everywhere down there, so well... It's 17 bytes less, so 36 bytes, if we count out func variables' (a and b) declaration and func brackets.

(a:Int,b:Int)=>{var s=1
for(i<-a to b by -1*b)s*=i
s}

Try it online! I commented out the broken test cases, because, well, they do break.

\$\endgroup\$
2
  • \$\begingroup\$ You need the function declaration, otherwise this would be a snippet that takes input via predefined variables. Typically only the function assignment is left out since anonymous functions are allowed as submissions, though it depends on the language and the question \$\endgroup\$
    – Jo King
    Commented Aug 6, 2019 at 6:57
  • \$\begingroup\$ Ok thanks, so it is 53 indeed. \$\endgroup\$ Commented Aug 6, 2019 at 7:00
2
\$\begingroup\$

Rust, 92 73 61 bytes

fn f(n:i128,k:i128)->i128{if n<=0{return 1}return n*f(n-k,k)}

I am just starting to learn rust, so I'm sure this can be shorter. Will update as I learn. The return value should be i128 in order to compute the last test.

Edit: Recursion is shorter.

Try it online!

You can add your own test, or edit one of the already existing ones.

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

q, 59 57 55 53 bytes

{prd 2+(&)1_i=last i:("J"$x(&)not[n])#(!)sum n:"!"=x}

explanation:

q)x:"12!!" / let our input be 12!!, assign to x
q)sum n:"!"=x / count "!"s
2i
q)(!)sum n:"!"=x / (!)m -> [0,m)
0 1
q)("J"$x(&)not[n]) / isolate the number in input
12
q)("J"$x(&)not[n])#(!)sum n:"!"=x / x#y means take x items from list y, if x>y, circle around
0 1 0 1 0 1 0 1 0 1 0 1
q)i:("J"$x(&)not[n])#(!)sum n:"!"=x / assign to i
q)i
0 1 0 1 0 1 0 1 0 1 0 1
q)(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / take last elem of i and see which are equal in i
010101010101b
q)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / drop first elem
10101010101b
q)(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / indices of 1b (boolean TRUE)
0 2 4 6 8 10
q)2+(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / add 2 across array
2 4 6 8 10 12
q)prd 2+(&)1_(last i)=i:("J"$x(&)not[n])#(!)sum n:"!"=x / product across array
46080

here also is a version in k (same logic), 4241 bytes

{*/2+&1_i=last i:("J"$x@&~:n)#!+/n:"!"=x}
\$\endgroup\$
6
  • \$\begingroup\$ Welcome to the site! I've added code formatting to your post which can be done with four spaces before the line or by enclosing it with triple backticks. \$\endgroup\$
    – Wheat Wizard
    Commented Aug 9, 2019 at 13:51
  • \$\begingroup\$ @SriotchilismO'Zaic thanks :-) \$\endgroup\$
    – scrawl
    Commented Aug 9, 2019 at 14:30
  • 1
    \$\begingroup\$ I recommend adding an explanation and maybe a link to an online interpreter like TIO. Code-only answers are usually automatically flagged as low quality. \$\endgroup\$
    – mbomb007
    Commented Aug 9, 2019 at 14:45
  • \$\begingroup\$ @mbomb007 interesting. is there a bot flagging answers? what happens to low-quality submissions? i will update soon! \$\endgroup\$
    – scrawl
    Commented Aug 9, 2019 at 15:09
  • \$\begingroup\$ Yes, there is a bot. StackExchange uses bots to look for potential spam and low quality answers. People with high enough reputation can view the Review Queue. meta.stackexchange.com/a/161391/285610 \$\endgroup\$
    – mbomb007
    Commented Aug 9, 2019 at 15:40
2
+400
\$\begingroup\$

Factor + math.unicode, 30 29 24 bytes

  • Saved 1 byte thanks to @Bubbler
  • Saved 5 bytes thanks to @chunes!
[ 1 rot neg <range> Π ]

Try it online!

Takes k (which -th factorial) and then n. First we push an n onto the stack, then rot makes the stack look like n 1 k. neg negates k, which will act as the step for a range from n to 1 (made using <range>). Then Π finds the product of that range, and that's it.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ If you take the arguments in k n order, you can do 1 rot neg instead of neg 1 swap to save a byte. \$\endgroup\$
    – Bubbler
    Commented Mar 29, 2021 at 23:19
  • 1
    \$\begingroup\$ You can save 5 bytes with Π from math.unicode instead of product. \$\endgroup\$
    – chunes
    Commented Mar 30, 2021 at 0:26
2
\$\begingroup\$

Nibbles, 3.5 bytes (7 nibbles)

`*`%@\,
      ,         # get the range from 1..first input,
     \          # reverse it,
   %            # and take each element in steps of
    @           # the second input,
`*              # and finally get the product

enter image description here


Or 7.5 bytes (15 nibbles) with input as string of a base-ten integer followed by exclamation marks:

`*`%,|$\$D\,`r$

enter image description here

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

Physica, 22 bytes

f=>n;k:n<1||n*f[n-k;k]

Try it online!


26 bytes

Re-learning how to use my own "language" \o/... If I knew how to write a parser 2 years ago, this would have been 20 bytes :(

->n;k:GenMul##[n…1]{%%k}

or

->n;k:GenMul##Range[n;1;k]

Try it online!

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

Retina, 66 bytes

^0
1
\d+
*!,
+`(!+)(!+),\1$
$1$2,$2,$1
!+$
1
+`(!+),(\d+)
$.($2*$1

Try it online! Link includes faster test cases. Mauls numbers without exclamation marks. Explanation:

^0
1

Fix up 0!.

\d+
*!,

Convert n to unary and add a separator.

+`(!+)(!+),\1$
$1$2,$2,$1

Repeatedly subtract k from n while n>k, and collect the results.

!+$
1

Replace k with 1 (in decimal).

+`(!+),(\d+)
$.($2*$1

Multiply by each intermediate value in turn, converting to decimal.

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

Japt, 8 bytes

1õUV f ×

Try it

\$\endgroup\$

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