CombinationPermutation

by Nathaniel Oshunniyi: Y12 Age ~16

Introduction

Nathaniel is using this site to learn Pascal and, as requested on our Programs page, makes his own contribution after coming up with a fine idea to make use of some basic language features. The Math Forum has a clear explanation of the formulae used in this program for permutations and combinations.

Technical features and code (which you can compile in either Lazarus or Delphi) follow these screenshots of test runs on a PC and a Raspberry Pi.

Output

Output

Raspberry Pi Test

Raspberry Pi Test

Technical Features

The program benefits from:

  • own functions;
  • use of inbuilt routines such as Val, Length, MidStr and Sleep;
  • appropriate comments;
  • validation;
  • nested loops;
  • good use of case statements;
  • animated output of text.

Code

program CombinationPermutation;
{
    Copyright (c) 2014 Nathaniel Oshunniyi

    Licensed under the Apache License, Version 2.0 (the "License"); you may not
    use this file except in compliance with the License, as described at
    http://www.apache.org/licenses/ and http://www.pp4s.co.uk/licenses/
}

{$APPTYPE CONSOLE}

uses
  SysUtils, strutils;

var
  u: integer; //Loop control

  //These are the user validation variables:
  num1, num2, val1, val2: integer;
  crashcheck, wrong: boolean;

  choice, again, snum1, snum2: string; // user input variables (and validation)
  combin, permin: integer; // final answers

  // n!
  function nfactorial(n: integer): integer;
  var
    i: integer;
  begin
    Result := 1;
    for i := 1 to n do
      Result := Result * i;
  end;

  //(n-r)!
  function midman(d, e: integer): integer;
  var
    k, difference: integer;
  begin
    Result := 1;
    difference := (d - e);

    if difference < 0 then
      begin
        difference := difference * -1;
        Result := 0;
      end;

    for k := 1 to difference do
      Result := Result * k;
  end;

  //scrolling text writeln
  function scroll(Text: string): string;
  var
    o: integer;
  begin
    for o := 1 to length(Text) do
      begin
        write(midstr(Text, o, 1));
        sleep(10);
      end;
    writeln;
  end;

  //scrolling text write
  function scroll2(Text: string): string;
  var
    o: integer;
  begin
    for o := 1 to length(Text) do
      begin
        write(midstr(Text, o, 1));
        sleep(10);
      end;
    write(' ');
  end;

begin  // Main program
  //basic information to the user
  scroll('This is the combination/permutation calc.');
  sleep(200);
  scroll('Bear in mind you cannot enter negative numbers');
  scroll('and the first number must be larger than the second.');
  scroll('Also, don''t put massive numbers or you''ll crash everything :(');
  sleep(500);
  repeat
    repeat
      writeln;
      scroll('Do you want:');
      scroll('Combination');
      scroll('Permutation');
      scroll('Formulas');
      scroll('Nothing (Exit program)');
      writeln;
      write(' >> ');
      readln(choice);
      writeln;
      wrong := True;
      crashcheck := True;
      case choice[1] of
        //the user can incorrectly spell 'permutation' as long as they get the first letter
        'P', 'p':
          begin
            scroll('Permutation:');
            writeln;
            sleep(500);
            //input validation
            repeat
              scroll2('Enter no1:');
              readln(snum1);
              val(snum1, num1, val1);
            until val1 = 0;
            repeat
              crashcheck := True;
              scroll2('Enter no2:');
              readln(snum2);
              val(snum2, num2, val2);
              if num2 > num1 then
                crashcheck := False;
            until (val2 = 0) and (crashcheck = True);
            //calculations
            permin := (nfactorial(num1)) div (midman(num1, num2));
            if permin = 0 then
              begin
                writeln;
                scroll('MATH ERROR');
              end
            else
              begin
                writeln;
                scroll(IntToStr(num1));
                for u := 1 to length(snum1) do
                  write(' ');
                scroll('P');
                for u := 1 to length(snum1) + 1 do
                  write(' ');
                scroll2(IntToStr(num2));
                scroll2(':  ');
                writeln(permin);
                writeln;
                sleep(500);
              end;
          end;

        //the user can incorrectly spell 'combination' as long as they get the first letter
        'C', 'c':
          begin
            scroll('Combination:');
            writeln;
            sleep(500);
            //input validation
            repeat
              scroll2('Enter no1:');
              readln(snum1);
              val(snum1, num1, val1);
            until val1 = 0;
            repeat
              crashcheck := True;
              scroll2('Enter no2:');
              readln(snum2);
              val(snum2, num2, val2);
              if num2 > num1 then
                crashcheck := False;
            until (val2 = 0) and (crashcheck = True);
            //calculations
            combin := (nfactorial(num1)) div ((midman(num1, num2)) * (nfactorial(num2)));
            if combin = 0 then
              begin
                writeln;
                scroll('MATH ERROR');
              end
            else
              begin
                writeln;
                scroll(IntToStr(num1));
                for u := 1 to length(snum1) do
                  write(' ');
                scroll('C');
                for u := 1 to length(snum1) + 1 do
                  write(' ');
                scroll2(IntToStr(num2));
                scroll2(':  ');
                writeln(combin);
                writeln;
                sleep(500);
              end;
          end;

        'F', 'f':
          begin
            scroll('Combination:    n!');
            scroll('             ________');
            scroll('             (n-r)!r!');
            writeln;
            scroll('Permutation:    n!');
            scroll('              _____');
            scroll('              (n-r)!');
          end;

        'N', 'n', 'E', 'e':
          begin
            writeln;
            scroll('Thanks for using the program');
            scroll('  - Nathaniel, the Great (c)');
            sleep(1222);
            exit;
          end

        else
          begin
            scroll('Command not recognised [your spelling is very off]');
            wrong := False;
          end;
      end;
    until wrong = True;

    //repeating / wrapping up
    writeln;
    scroll('Do you wish to do something else? another calculation?');
    scroll('If you don''t, just say ''N''');
    writeln;
    scroll2(' >> ');
    readln(again);
  until (again = 'N') or (again = 'n');

  //  :)
  writeln;
  scroll('Thanks for using the program');
  scroll('  - Nathaniel, the Great (c)');
  sleep(1222);
end.

Remarks

Can you think of two ways of making this program handle larger input values?

Programming - a skill for life!

Student programs to inspire you!