15
\$\begingroup\$

Who doesn't absolutely love permutations, right? I know, they are amazing––so much fun!

Well, why not take this fun and make it funner?

Here's the challenge:

Given an input in the exact form: nPr, where n is the pool taken from and r is the number of selections from that pool (and n and r are integers), output/return the exact number of permutations. For those of you that are a bit rusty with the terminology: Permutation, def. 2a.

However, this is where the challenge comes into play (makes it not too easy):

You may not use any built in library, framework, or method for your permutation function. You may not use a factorial method, permutation method, or anything of the sort; you must write everything yourself.

If further clarification is needed, please, do not hesitate to tell me in the comments and I will promptly act accordingly.


Here is an I/O example:

Sample function is permute(String) -> int

Input:

permute("3P2")

Output:

6

This is code-golf, so shortest code wins!

\$\endgroup\$
11
  • 2
    \$\begingroup\$ Aww. I thought that this challenge would be on permutation groups. Cool stuff. This is cool too, and closely related to permutation groups. Love the challenge. \$\endgroup\$
    – Justin
    Nov 7, 2015 at 5:57
  • \$\begingroup\$ When you say no built-in or library methods, do you mean for permutations, or for anything? Can I use the built-in split to split the input at the P? What about a function that converts a string to a number? \$\endgroup\$
    – xnor
    Nov 7, 2015 at 6:33
  • 3
    \$\begingroup\$ May answers assume that 0 <= r <= n? \$\endgroup\$ Nov 7, 2015 at 8:08
  • 1
    \$\begingroup\$ @Dopapp Do you mean that r isn't greater than n? \$\endgroup\$
    – Dennis
    Nov 7, 2015 at 16:30
  • 1
    \$\begingroup\$ @RetoKoradi - I suppose that in an effort to not force most posters to redo their answers, you are just not allowed to use any factorial or permutation methods/functions. \$\endgroup\$
    – Daniel
    Nov 8, 2015 at 5:18

15 Answers 15

4
\$\begingroup\$

CJam, 15 14 bytes

r~\;~\),>UXt:*

Try it online in the CJam interpreter.

How it works

r              e# Read a token ("nPr") from STDIN.
 ~             e# Evaluate. This pushes the numbers n, Pi and r on the stack.
  \;           e# Discard Pi.
    ~          e# Take the bitwise NOT of r. Pushes -(r+1).
     \)        e# Increment n.    
       ,       e# Turn n+1 into [0 ... n].
        >      e# Keep only the last r+1 elements.
         UXt   e# Replace the first element with 1.
               e# This avoid dealing with the egde case nP0 separately.
            :* e# Compute their product.
\$\endgroup\$
4
\$\begingroup\$

Perl, 27 bytes

#!perl -pl61
$\*=$`-$%++for/P/..$'}{

Counting the shebang as 4, input is taken from stdin.


Sample Usage

$ echo 3P2 | perl npr.pl
6

$ echo 7P4 | perl npr.pl
840
\$\endgroup\$
2
  • \$\begingroup\$ What sort of option is l61? \$\endgroup\$
    – feersum
    Nov 7, 2015 at 11:43
  • \$\begingroup\$ @feersum it sets $\ to 1 (char 49, octal 61). \$\endgroup\$
    – primo
    Nov 7, 2015 at 11:48
3
\$\begingroup\$

Haskell, 71 66 bytes

p s|(u,_:x)<-span(/='P')s,(n,k)<-(read u,read x)=product[n-k+1..n]

Pretty straightforward stuff: split at the 'P' then take the product between (n-k+1) and n.

Thanks to nimi for their idea to use pattern guards rather than a where clause, it shaved off 5 bytes.

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

Minkolang 0.11, 13 25 19 bytes

Thanks to Sp3000 for suggesting this!

1nnd3&1N.[d1-]x$*N.

Try it here.

Explanation

1        Push 1
n        Take integer from input (say, n)
n        Take integer from input (say, k); ignores non-numeric characters in the way
d3&1N.   Output 1 if k is 0
[   ]    Loop k times
 d1-     Duplicate top of stack and subtract 1
x        Dump top of stack
$*       Multiply all of it together
N.       Output as integer

This uses the same algorithm as Alex's: n P k = n(n-1)(n-2)...(n-k+1).

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

Julia, 63 58 48 bytes

s->((n,r)=map(parse,split(s,"P"));prod(n-r+1:n))

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

Ungolfed:

function f(s::AbstractString)
    # Get the pool and number of selections as integers
    n, r = map(parse, split(s, "P"))

    # Return the product of each number between n-r+1 and n
    return prod(n-r+1:n)
end

This uses the fact that the number of permutations is n(n-1)(n-2)...(n-k+1).

Saved 10 bytes thanks to Glen O!

\$\endgroup\$
2
  • \$\begingroup\$ No need for Int, so you can just use map(parse,...). \$\endgroup\$
    – Glen O
    Nov 7, 2015 at 17:18
  • \$\begingroup\$ @GlenO My mind has been blown. I didn't realize Int was necessary in that situation. Thanks so much! \$\endgroup\$
    – Alex A.
    Nov 7, 2015 at 19:35
2
\$\begingroup\$

Bash + Linux utils, 33

jot -s\* ${1#*P} $[${1/P/-}+1]|bc

jot produces the sequence of r integers starting at n-r+1, and separates them with *. This expression is piped to bc for arithmetic evaluation.

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

MATLAB, 54 bytes

[n,r]=strread(input(''),'%dP%d');disp(prod((n-r+1):n))

Tried to make it smaller, but one of the things MATLAB is really bad at is getting inputs. It takes 32 characters just to get the two numbers from the input string!

Fairly self explanatory code. Get the input in the form %dP%d where %d is an integer. Split that into n and r. Then display the product of every integer in the range n-r+1 to n. Interestingly this works even for xP0 giving the correct answer of 1. This is because in MATLAB the prod() function returns 1 if you try and do the product of an empty array. Whenever r is zero, the range will be an empty array, so bingo we get 1.


This also works perfectly with Octave as well. You can try it online here.

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

Javascript, 59 57 bytes

s=>(f=(n,k)=>k?(n- --k)*f(n,k):1,f.apply(f,s.split('P')))
\$\endgroup\$
1
\$\begingroup\$

Java(594 - bytes)

import java.util.*;import java.lang.*;public class Perm {private String a;private static int[] nr=new int[2];private static int sum=1;Scanner in=new Scanner(System.in);public String input(){a=in.nextLine();return a;}public void converter(String a){this.a=a;String b=a.substring(0,1);String c=a.substring(2);nr[0]=Integer.parseInt(b);nr[1]=Integer.parseInt(c);}public int param(){for(int counter=0; counter < nr[1]; counter++){sum=sum*nr[0]--;}return sum;}public static void main(String args[]){Perm a;a=new Perm();String k=a.input();a.converter(k);int ans=a.param();System.out.println(ans);}}
\$\endgroup\$
1
\$\begingroup\$

J, 23 bytes

^!._1/@(".;._1)@('P'&,)

An anonymous function. Example:

   f =. ^!._1/@(".;._1)@('P'&,)
   f '10P4'
5040

Explanation:

       (  ;._1)@('P'&,)   Split over 'P', and on each slice,
        ".                read a number.
      @                   Then,
^!._1/                    fold (/) with the built-in "stope function" (^!.k) for k=1.

The stope function I used might border on counting as a built-in... It rests somewhere between the generality of the multiplication operator and the specificity of the factorial operator.

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

APL, 23

{{×/⍵↑⍳-⍺}/-⍎¨⍵⊂⍨⍵≠'P'}

Takes the string as argument. Explanation:

              ⍵⊂⍨⍵≠'P'  ⍝ Split by 'P'.
           -⍎¨          ⍝ Convert to numbers and negate making a vector (−n −r)
 {       }/             ⍝ Reduce it by a defined function, which
      ⍳-⍺               ⍝ makes a vector of numbers from 1 to n (⍺)
    ⍵↑                  ⍝ takes r last elements (⍵←−r)
  ×/                    ⍝ and multiplies them together.
\$\endgroup\$
2
  • \$\begingroup\$ Which APL is this? I get an error with my copy of Dyalog. \$\endgroup\$
    – lirtosiast
    Nov 8, 2015 at 2:08
  • 1
    \$\begingroup\$ @ThomasKwa Use ⎕ML←3 in Dyalog. \$\endgroup\$
    – user46915
    Nov 8, 2015 at 2:16
1
\$\begingroup\$

Python 2, 66

def f(s):a,b=map(int,s.split('P'));P=1;exec"P*=a;a-=1;"*b;print P

Pretty straightforward. Processes the number input as a,b. Keeps a running product as P, which is multiplied by the first b terms of a, a-1, a-2, ....

\$\endgroup\$
3
  • 2
    \$\begingroup\$ I don't see how input() could not result in an error. \$\endgroup\$
    – feersum
    Nov 7, 2015 at 11:45
  • \$\begingroup\$ @feersum I tried it and it indeed throws a syntax error. \$\endgroup\$
    – Alex A.
    Nov 7, 2015 at 19:33
  • \$\begingroup\$ I was taking input with quotes like "3P2", which I think is usually allowed, but here the challenge says "an input in the exact form", so I change it to a function which takes a string. \$\endgroup\$
    – xnor
    Nov 8, 2015 at 2:01
1
\$\begingroup\$

TI-BASIC, 52 bytes

Ans→Str1
expr(sub(Ans,1,⁻1+inString(Ans,"P→P        ;n
1
If expr(Str1                               ;If n^2*r ≠ 0
prod(randIntNoRep(P,P+1-expr(Str1)/P²
Ans

TI-BASIC has a "product of a list" function, so getting around the restriction on builtins isn't too hard. However, TI-BASIC doesn't support empty lists—so we need to

To extract the two numbers, I extract the first number as a substring. This is expensive; it takes up the whole second line. To keep from needing to do this again for the second number, I set the variable P to that number, and evaluate the whole string using expr(, then divide by P².

Finally, I take a random permutation of the list between the two numbers (taking care to add one to the second number) and take the product.

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

Ouroboros, 47 45 bytes

Some of this is pretty ugly--I'd imagine it could be golfed further.

Sr.r-1(
)s.!+S1+.@@.@\<!@@*Ys.!+*S.!!4*.(sn1(

Each line of code in Ouroboros represents a snake eating its tail.

Snake 1

S switches to the shared stack. r.r reads one number, duplicates it, and reads another. (Nonnumeric characters like P are skipped.) - subtracts the two. If the input was 7P2, we now have 7, 5 on the shared stack. Finally, 1( eats the final character of the snake. Since this is the character that the instruction pointer is on, the snake dies.

Snake 2

)s does nothing the first time through. .!+ duplicates the top of snake 2's stack, checks if it's zero, and if so adds 1. On the first iteration, the stack is empty and treated as if it contained infinite zeros, so this pushes 1; on later iterations, the stack contains a nonzero value and this has no effect.

Next, S switches to the shared stack, where we have the number n and a counter for calculating the product. 1+ increments the counter. .@@.@\<! duplicates both numbers and pushes 1 if n is still greater than or equal to the counter, 0 otherwise. @@*Y then multiplies the counter by this quantity and yanks a copy onto snake 2's stack.

s.!+ switches back to snake 2's stack and uses the same code as earlier to convert the top number to 1 if it was 0 and keep it the same otherwise. Then * multiplies the result by the partial product that was sitting on this stack.

We now go back to the shared stack (S), duplicate the counter-or-zero (.), and negate it twice (!!) to turn a nonzero counter into a 1. 4*.( multiplies this by 4, duplicates, and eats that many characters from the end of the snake.

  • If we haven't reached the halting condition, we've got a 4 on the stack. The four characters after the ( are eaten, and control loops around to the beginning of the code. Here ) regurgitates four characters, s switches back to snake 2's stack, and execution continues.
  • If the counter has passed n, we've got a 0 on the stack, and nothing is eaten. sn switches to snake 2's stack and outputs the top value as a number; then 1( eats the last character and dies.

The result is that the product (r+1)*(r+2)*...*n is calculated and output.

Try it out

// Define Stack class
function Stack() {
  this.stack = [];
  this.length = 0;
}
Stack.prototype.push = function(item) {
  this.stack.push(item);
  this.length++;
}
Stack.prototype.pop = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack.pop();
    this.length--;
  }
  return result;
}
Stack.prototype.top = function() {
  var result = 0;
  if (this.length > 0) {
    result = this.stack[this.length - 1];
  }
  return result;
}
Stack.prototype.toString = function() {
  return "" + this.stack;
}

// Define Snake class
function Snake(code) {
  this.code = code;
  this.length = this.code.length;
  this.ip = 0;
  this.ownStack = new Stack();
  this.currStack = this.ownStack;
  this.alive = true;
  this.wait = 0;
  this.partialString = this.partialNumber = null;
}
Snake.prototype.step = function() {
  if (!this.alive) {
    return null;
  }
  if (this.wait > 0) {
    this.wait--;
    return null;
  }
  var instruction = this.code.charAt(this.ip);
  var output = null;
  console.log("Executing instruction " + instruction);
  if (this.partialString !== null) {
    // We're in the middle of a double-quoted string
    if (instruction == '"') {
      // Close the string and push its character codes in reverse order
      for (var i = this.partialString.length - 1; i >= 0; i--) {
        this.currStack.push(this.partialString.charCodeAt(i));
      }
      this.partialString = null;
    } else {
      this.partialString += instruction;
    }
  } else if (instruction == '"') {
    this.partialString = "";
  } else if ("0" <= instruction && instruction <= "9") {
    if (this.partialNumber !== null) {
      this.partialNumber = this.partialNumber + instruction;  // NB: concatenation!
    } else {
      this.partialNumber = instruction;
    }
    next = this.code.charAt((this.ip + 1) % this.length);
    if (next < "0" || "9" < next) {
      // Next instruction is non-numeric, so end number and push it
      this.currStack.push(+this.partialNumber);
      this.partialNumber = null;
    }
  } else if ("a" <= instruction && instruction <= "f") {
    // a-f push numbers 10 through 15
    var value = instruction.charCodeAt(0) - 87;
    this.currStack.push(value);
  } else if (instruction == "$") {
    // Toggle the current stack
    if (this.currStack === this.ownStack) {
      this.currStack = this.program.sharedStack;
    } else {
      this.currStack = this.ownStack;
    }
  } else if (instruction == "s") {
    this.currStack = this.ownStack;
  } else if (instruction == "S") {
    this.currStack = this.program.sharedStack;
  } else if (instruction == "l") {
    this.currStack.push(this.ownStack.length);
  } else if (instruction == "L") {
    this.currStack.push(this.program.sharedStack.length);
  } else if (instruction == ".") {
    var item = this.currStack.pop();
    this.currStack.push(item);
    this.currStack.push(item);
  } else if (instruction == "m") {
    var item = this.ownStack.pop();
    this.program.sharedStack.push(item);
  } else if (instruction == "M") {
    var item = this.program.sharedStack.pop();
    this.ownStack.push(item);
  } else if (instruction == "y") {
    var item = this.ownStack.top();
    this.program.sharedStack.push(item);
  } else if (instruction == "Y") {
    var item = this.program.sharedStack.top();
    this.ownStack.push(item);
  } else if (instruction == "\\") {
    var top = this.currStack.pop();
    var next = this.currStack.pop()
    this.currStack.push(top);
    this.currStack.push(next);
  } else if (instruction == "@") {
    var c = this.currStack.pop();
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(c);
    this.currStack.push(a);
    this.currStack.push(b);
  } else if (instruction == ";") {
    this.currStack.pop();
  } else if (instruction == "+") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a + b);
  } else if (instruction == "-") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a - b);
  } else if (instruction == "*") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a * b);
  } else if (instruction == "/") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a / b);
  } else if (instruction == "%") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(a % b);
  } else if (instruction == "_") {
    this.currStack.push(-this.currStack.pop());
  } else if (instruction == "I") {
    var value = this.currStack.pop();
    if (value < 0) {
      this.currStack.push(Math.ceil(value));
    } else {
      this.currStack.push(Math.floor(value));
    }
  } else if (instruction == ">") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a > b));
  } else if (instruction == "<") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a < b));
  } else if (instruction == "=") {
    var b = this.currStack.pop();
    var a = this.currStack.pop();
    this.currStack.push(+(a == b));
  } else if (instruction == "!") {
    this.currStack.push(+ !this.currStack.pop());
  } else if (instruction == "?") {
    this.currStack.push(Math.random());
  } else if (instruction == "n") {
    output = "" + this.currStack.pop();
  } else if (instruction == "o") {
    output = String.fromCharCode(this.currStack.pop());
  } else if (instruction == "r") {
    var input = this.program.io.getNumber();
    this.currStack.push(input);
  } else if (instruction == "i") {
    var input = this.program.io.getChar();
    this.currStack.push(input);
  } else if (instruction == "(") {
    this.length -= Math.floor(this.currStack.pop());
    this.length = Math.max(this.length, 0);
  } else if (instruction == ")") {
    this.length += Math.floor(this.currStack.pop());
    this.length = Math.min(this.length, this.code.length);
  } else if (instruction == "w") {
    this.wait = this.currStack.pop();
  }
  // Any unrecognized character is a no-op
  if (this.ip >= this.length) {
    // We've swallowed the IP, so this snake dies
    this.alive = false;
    this.program.snakesLiving--;
  } else {
    // Increment IP and loop if appropriate
    this.ip = (this.ip + 1) % this.length;
  }
  return output;
}
Snake.prototype.getHighlightedCode = function() {
  var result = "";
  for (var i = 0; i < this.code.length; i++) {
    if (i == this.length) {
      result += '<span class="swallowedCode">';
    }
    if (i == this.ip) {
      if (this.wait > 0) {
        result += '<span class="nextActiveToken">';
      } else {
        result += '<span class="activeToken">';
      }
      result += escapeEntities(this.code.charAt(i)) + '</span>';
    } else {
      result += escapeEntities(this.code.charAt(i));
    }
  }
  if (this.length < this.code.length) {
    result += '</span>';
  }
  return result;
}

// Define Program class
function Program(source, speed, io) {
  this.sharedStack = new Stack();
  this.snakes = source.split(/\r?\n/).map(function(snakeCode) {
    var snake = new Snake(snakeCode);
    snake.program = this;
    snake.sharedStack = this.sharedStack;
    return snake;
  }.bind(this));
  this.snakesLiving = this.snakes.length;
  this.io = io;
  this.speed = speed || 10;
  this.halting = false;
}
Program.prototype.run = function() {
  this.step();
  if (this.snakesLiving) {
    this.timeout = window.setTimeout(this.run.bind(this), 1000 / this.speed);
  }
}
Program.prototype.step = function() {
   for (var s = 0; s < this.snakes.length; s++) {
    var output = this.snakes[s].step();
    if (output) {
      this.io.print(output);
    }
  }
  this.io.displaySource(this.snakes.map(function (snake) {
      return snake.getHighlightedCode();
    }).join("<br>"));
 }
Program.prototype.halt = function() {
  window.clearTimeout(this.timeout);
}

var ioFunctions = {
  print: function (item) {
    var stdout = document.getElementById('stdout');
    stdout.value += "" + item;
  },
  getChar: function () {
    if (inputData) {
      var inputChar = inputData[0];
      inputData = inputData.slice(1);
      result = inputChar.charCodeAt(0);
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  getNumber: function () {
    while (inputData && (inputData[0] < "0" || "9" < inputData[0])) {
      inputData = inputData.slice(1);
    }
    if (inputData) {
      var inputNumber = inputData.match(/\d+/)[0];
      inputData = inputData.slice(inputNumber.length);
      result = +inputNumber;
    } else {
      result = -1;
    }
    var stdinDisplay = document.getElementById('stdin-display');
    stdinDisplay.innerHTML = escapeEntities(inputData);
    return result;
  },
  displaySource: function (formattedCode) {
    var sourceDisplay = document.getElementById('source-display');
    sourceDisplay.innerHTML = formattedCode;
  }
};
var program = null;
var inputData = null;
function showEditor() {
  var source = document.getElementById('source'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');
  
  source.style.display = "block";
  stdin.style.display = "block";
  sourceDisplayWrapper.style.display = "none";
  stdinDisplayWrapper.style.display = "none";
  
  source.focus();
}
function hideEditor() {
  var source = document.getElementById('source'),
    sourceDisplay = document.getElementById('source-display'),
    sourceDisplayWrapper = document.getElementById('source-display-wrapper'),
    stdin = document.getElementById('stdin'),
    stdinDisplay = document.getElementById('stdin-display'),
    stdinDisplayWrapper = document.getElementById('stdin-display-wrapper');
  
  source.style.display = "none";
  stdin.style.display = "none";
  sourceDisplayWrapper.style.display = "block";
  stdinDisplayWrapper.style.display = "block";
  
  var sourceHeight = getComputedStyle(source).height,
    stdinHeight = getComputedStyle(stdin).height;
  sourceDisplayWrapper.style.minHeight = sourceHeight;
  sourceDisplayWrapper.style.maxHeight = sourceHeight;
  stdinDisplayWrapper.style.minHeight = stdinHeight;
  stdinDisplayWrapper.style.maxHeight = stdinHeight;
  sourceDisplay.textContent = source.value;
  stdinDisplay.textContent = stdin.value;
}
function escapeEntities(input) {
  return input.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
}
function resetProgram() {
  var stdout = document.getElementById('stdout');
  stdout.value = null;
  if (program !== null) {
    program.halt();
  }
  program = null;
  inputData = null;
  showEditor();
}
function initProgram() {
  var source = document.getElementById('source'),
    stepsPerSecond = document.getElementById('steps-per-second'),
    stdin = document.getElementById('stdin');
  program = new Program(source.value, +stepsPerSecond.innerHTML, ioFunctions);
  hideEditor();
  inputData = stdin.value;
}
function runBtnClick() {
  if (program === null || program.snakesLiving == 0) {
    resetProgram();
    initProgram();
  } else {
    program.halt();
    var stepsPerSecond = document.getElementById('steps-per-second');
    program.speed = +stepsPerSecond.innerHTML;
  }
  program.run();
}
function stepBtnClick() {
  if (program === null) {
    initProgram();
  } else {
    program.halt();
  }
  program.step();
}
function sourceDisplayClick() {
  resetProgram();
}
function stdinDisplayClick() {
    resetProgram();
}
.container {
    width: 100%;
}
.so-box {
    font-family:'Helvetica Neue', Arial, sans-serif;
    font-weight: bold;
    color: #fff;
    text-align: center;
    padding: .3em .7em;
    font-size: 1em;
    line-height: 1.1;
    border: 1px solid #c47b07;
    -webkit-box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
    text-shadow: 0 0 2px rgba(0, 0, 0, 0.5);
    background: #f88912;
    box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3), 0 2px 0 rgba(255, 255, 255, 0.15) inset;
}
.control {
    display: inline-block;
    border-radius: 6px;
    float: left;
    margin-right: 25px;
    cursor: pointer;
}
.option {
    padding: 10px 20px;
    margin-right: 25px;
    float: left;
}
h1 {
    text-align: center;
    font-family: Georgia, 'Times New Roman', serif;
}
a {
    text-decoration: none;
}
input, textarea {
    box-sizing: border-box;
}
textarea {
    display: block;
    white-space: pre;
    overflow: auto;
    height: 50px;
    width: 100%;
    max-width: 100%;
    min-height: 25px;
}
span[contenteditable] {
    padding: 2px 6px;
    background: #cc7801;
    color: #fff;
}
#stdout-container, #stdin-container {
    height: auto;
    padding: 6px 0;
}
#reset {
    float: right;
}
#source-display-wrapper , #stdin-display-wrapper{
    display: none;
    width: 100%;
    height: 100%;
    overflow: auto;
    border: 1px solid black;
    box-sizing: border-box;
}
#source-display , #stdin-display{
    font-family: monospace;
    white-space: pre;
    padding: 2px;
}
.activeToken {
    background: #f93;
}
.nextActiveToken {
    background: #bbb;
}
.swallowedCode{
    color: #999;
}
.clearfix:after {
    content:".";
    display: block;
    height: 0;
    clear: both;
    visibility: hidden;
}
.clearfix {
    display: inline-block;
}
* html .clearfix {
    height: 1%;
}
.clearfix {
    display: block;
}
<!--
Designed and written 2015 by D. Loscutoff
Much of the HTML and CSS was taken from this Befunge interpreter by Ingo Bürk: http://codegolf.stackexchange.com/a/40331/16766
-->
<div class="container">
<textarea id="source" placeholder="Enter your program here" wrap="off">Sr.r-s1(
)s.!+S1+.@@.@\<!@@*Ys.!+*S.!!4*.(sn1(</textarea>
<div id="source-display-wrapper" onclick="sourceDisplayClick()"><div id="source-display"></div></div></div><div id="stdin-container" class="container">
<textarea id="stdin" placeholder="Input" wrap="off">3P2</textarea>
<div id="stdin-display-wrapper" onclick="stdinDisplayClick()"><div id="stdin-display"></div></div></div><div id="controls-container" class="container clearfix"><input type="button" id="run" class="control so-box" value="Run" onclick="runBtnClick()" /><input type="button" id="pause" class="control so-box" value="Pause" onclick="program.halt()" /><input type="button" id="step" class="control so-box" value="Step" onclick="stepBtnClick()" /><input type="button" id="reset" class="control so-box" value="Reset" onclick="resetProgram()" /></div><div id="stdout-container" class="container"><textarea id="stdout" placeholder="Output" wrap="off" readonly></textarea></div><div id="options-container" class="container"><div class="option so-box">Steps per Second:
<span id="steps-per-second" contenteditable>20</span></div></div>

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

Husk, 11 bytes

FöΠ↑↔ḣmrx'P

Try it online!

How?

        x'P    # split input on the character 'P'
      mr       # and map each of the 2 strings to a value;
Fö             # now, fold over these 2 values by calculating
  Π            # the product of
   ↑           # the first r elements (where r = second value) of
     ḣ         # the series 1..n (where n = first value)
    ↔          # reversed
\$\endgroup\$

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.