How to write numbers separated with commas in a loop on one line? - pascal

I am making a program of prime number in FreePascal.
How to output number divides with I1,I2 separated with commas instead of 2 lines?
var
P:Integer;
I:Integer;
J:Integer;
A:Integer;
begin
writeln('Prime number program');
writeln;
writeln('Insert number');
readln(P);
for I:=2 to P-1 do
begin
J:=P Mod I;
if (J=0) then
begin
writeln(P,' divides with ',I);
a:=a+1
end;
end;
if a=0 then
begin
writeln(P,' is prime number')
end;
end.

I know it's not a good way to teach you something, but here it is:
program Project1;
uses
SysUtils;
var
S: string;
I: Integer;
Count: Integer;
Input: Integer;
begin
Writeln('Prime number program');
Writeln;
Writeln('Insert a number:');
Readln(Input);
for I := 2 to Input-1 do
begin
if (Input mod I = 0) then
begin
Count := Count + 1;
if (S <> '') then
S := S + ', ';
S := S + IntToStr(I);
end;
end;
if (Count = 0) then
Writeln(Input, ' is a prime number.')
else
Writeln(Input, ' is not a prime number. It divides with ', S, '.');
Readln;
end.

prime := true;
for i := 2 to p - 1 do
if(p mod i = 0) then prime := false;
if prime then writeln("prime");
all program:
program Prime;
var
prime: boolean;
I, P: Integer;
begin
Writeln('Prime number program');
Writeln;
Writeln('Insert a number:');
Readln(P);
prime := true;
for i := 2 to p - 1 do
if(p mod i = 0) then prime := false;
if prime then writeln("prime");
else writeln("not prime");
Readln;
end.

No need to check all numbers below N, odd numbers below sqrt(N) are enough.
program PrimeTest;
var N, I, Divisor: LongInt;
Prime: Boolean;
begin
writeln('Prime number program');
writeln;
write('Insert number: ');
readln(N);
Divisor := 1;
Prime := True;
if N < 5 then
begin
Prime := (N = 2) or (N = 3);
if N = 4 then Divisor := 2;
end else if Odd(N) then
begin
I := 3;
while I*I <= N do
begin
if N mod I = 0 then
begin
Prime := False;
Divisor := I;
break;
end;
I := I + 2;
end;
end else begin
Prime := False;
Divisor := 2;
end;
if Prime then writeln(N, ' is a prime number')
else writeln(N, ' is divisible by ', Divisor);
end.
Of course, if you want to find all prime factors, or all divisors (not the same thing), you will need something a bit more complcated, but it's still better to do as few divisions as possible.
Here is a solution giving the whole prime factorization.
program PrimeTest;
var N, I, J, Index, M: LongInt;
Factor, Power: array[1 .. 32] of LongInt;
begin
writeln('Prime number program');
writeln;
write('Insert number: ');
readln(N);
M := N;
Index := 0;
if N mod 2 = 0 then
begin
J := 0;
while N mod 2 = 0 do
begin
Inc(J);
N := N div 2;
end;
Inc(Index);
Factor[Index] := 2;
Power[Index] := J;
end;
I := 3;
while I*I <= N do
begin
if N mod I = 0 then
begin
J := 0;
while N mod I = 0 do
begin
Inc(J);
N := N div I;
end;
Inc(Index);
Factor[Index] := I;
Power[Index] := J;
end;
I := I + 2;
end;
if (N > 1) or (Index = 0) then
begin
Inc(Index);
Factor[Index] := N;
Power[Index] := 1;
end;
if M = 1 then writeln('1 is not prime')
else if (Index > 1) or ((Index > 0) and (Power[1] > 1)) then
begin
if Power[1] = 1 then write(M, ' = ', Factor[1])
else write(M, ' = ', Factor[1], '^', Power[1]);
for I := 2 to Index do
begin
if Power[I] = 1 then write(' * ', Factor[I])
else write(' * ', Factor[I], '^', Power[I]);
end;
writeln;
end else writeln(M, ' is prime');
end.

Related

Error: BREAK not allowed in for looping pascal

I try to create a for looping for my Bubble Sort Algorithm and use break as a condition if there is no more number to be sorted anymore. But then the compiler said that BREAK not allowed. Here is my code
Procedure Sort(var data : arr; j : integer);
var
temp: integer;
begin
temp := data[j];
data[j] := data[j + 1];
data[j + 1] := temp;
end;
Procedure sortDescending(var data : arr; n : integer);
var
i, j : integer;
marker : boolean;
begin
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if(data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if(marker = false) then
begin
break;
end;
end;
end;
Here's your code.
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if(data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if(marker = false) then
begin
break;
end;
end;
Let's add some whitespace after loops and indentation to make the issue clearer.
for i := 1 to n do
marker := false;
begin
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
end;
Which is equivalent to:
for i := 1 to n do
marker := false;
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
The break is not within a loop.
You likely meant to put begin before marker := false;.
for i := 1 to n do
begin
marker := false;
for j := 1 to n do
begin
if (data[j] < data[j + 1]) then
begin
Sort(data, j);
marker := true;
end;
end;
if (marker = false) then
begin
break;
end;
end;

How can I show the sorting progress step by step on output screen?

I don't know how to make sorting process visible on output.. (like you can see the step by step of each sorting phase on output).
Below is example of a similar program.
And here's my current progress:
program insertsort;
const
max = 100;
type
arr = array [1..max] of integer;
var
data : arr;
n, i, j : integer;
procedure InsertionSort(size : integer);
var
i, j, index : integer;
begin
for i := 2 to size do
begin
index := data[i];
j := i;
while ((j > 1) and (data[j-1] < index)) do
begin
data[j] := data[j-1];
j := j - 1;
end;
data[j] := index;
end;
end;
begin
write('Input Data : ');
readln(n);
for i := 1 to n do
begin
write ('Data-',i,' = '); readln(data[i]);
end;
writeln;
write ('Unsorted : ');
for i := 1 to n do
write(data[i],' ');
InsertionSort(max);
writeln;
writeln;
writeln;
write('Sorted : ');
for i := 1 to n do
write(data[i],' ');
readln;
end.

What is that the Error of Illegal assignment and how to correct it?

procedure tri_selection(t: tab; n: Integer);
var
i, j, min, aux: Integer;
begin
for i := 1 to n - 1 do
begin
min := i;
for j := i + 1 to n do
if t[j] < t[min] then
j := min;
if min <> i then
begin
aux := t[i];
t[i] := t[min];
t[min] := aux;
end;
end;
end;
That's supposed to be a correct and well-known code to arrange integers from inferior to superior but compiler still insists saying "illegal assignment to for loop 'j' variable".
What's the problem?
The problem is here:
for j := i + 1 to n do
if t[j] < t[min] then
j := min; // <-- Not allowed to assign to FOR loop variable j
You are not allowed to assign to the for loop variable.
Perhaps you meant to write
for j := i + 1 to n do
if t[j] < t[min] then
min := j;
you forgot var before t in the header of the procedure

Program behaving differently in FPC and ObjFPC

Following is a program in lazarus to perform RC4 encryption and decryption when given a string. When the compiler directive {$mode fpc} is used and the string 123 is entered it crashes with External: SIGSEGV. However there is no crash when inputting the same string in {$mode objfpc}. Another inconsistency is that in {$mode objfpc} the program raises the exception External: SIGSEGV again with the input of hellow.
//{$mode fpc}
{$mode objfpc}
program project1;
uses
sysutils, strutils;
type
myArray = array[0..255] of integer;
dynamicArray = array of integer;
dynamicArrayString = array of string;
const
key = 'qwertyui';
var
plaintext : string;
function KSA(const key: string): myArray;
var
i, j, key_length, temp: integer;
S : myArray;
begin
key_length := length(key);
j := 0;
for i := Low(S) to High(S) do
S[i] := i;
for i := Low(S) to High(S) do
begin
j := ((j + S[i] + ord(key[i mod key_length + 1])) mod 256);
temp := S[i];
S[i] := S[j];
S[j] := temp;
end;
KSA := S;
end;
function PRGA(S : myArray; n : integer) : dynamicArray;
var
i, j, K, temp, sizeOfArray : integer;
key : dynamicArray;
begin
i := 0;
j := 0;
K := 0;
temp := 0;
sizeOfArray := n - 1;
SetLength(key, sizeOfArray);
while n > 0 do
begin
n := n - 1;
i := (i + 1) mod 256;
j := (j + S[i]) mod 256;
temp := S[i];
S[i] := S[j];
S[j] := temp;
K := S[(S[i] + S[j]) mod 256];
key[i-1] := K;
end;
PRGA := key;
end;
procedure getPlaintext;
begin
readln(plaintext);
end;
function encrypt : string;
var
sizeOfArray, i : integer;
cipherString : string;
cipher, keystream: dynamicArray;
S : myArray;
begin
S := KSA(key);
keystream := PRGA(S, length(plaintext));
sizeOfArray := 0;
for i := 0 to (length(plaintext) - 1) do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(cipher, sizeOfArray);
cipher[i] := (keystream[i]) xor (ord(plaintext[i + 1]));
end;
cipherString := '';
for i := 0 to High(cipher) do
cipherString := cipherString + IntToHex(cipher[I], 2);
encrypt := cipherString;
end;
function stringToHex(cipherString : string) : dynamicArrayString;
var
sizeOfArray, i: integer;
DecryptArrayString : dynamicArrayString;
begin
sizeOfArray := 0;
i := 0;
// Turn the string into an array of hex
while length(cipherString) > 0 do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(DecryptArrayString, sizeOfArray);
DecryptArrayString[i] := cipherString[1] + cipherString[2];
i := i + 1;
cipherString := rightstr(cipherString, length(cipherString) - 2);
end;
stringToHex := DecryptArrayString;
end;
function hexToDecimal(DecryptArrayString : dynamicArrayString) : dynamicArray;
var
sizeOfDecryptArrayInt, i : integer;
DecryptArrayInt : dynamicArray;
begin
sizeOfDecryptArrayInt := 0;
// Hex to decimal
for i := 0 to high(DecryptArrayString) do
begin
sizeOfDecryptArrayInt := sizeOfDecryptArrayInt + 1;
SetLength(DecryptArrayInt, sizeOfDecryptArrayInt);
DecryptArrayInt[i] := Hex2Dec(DecryptArrayString[i]);
end;
hexToDecimal := DecryptArrayInt;
end;
function decrypt(DecryptArrayInt : dynamicArray) : string;
var
DecryptedString : string;
S : myArray;
keystream, Decrypted : dynamicArray;
sizeOfArray, i : integer;
begin
sizeOfArray := 0;
for i := 0 to high(DecryptArrayInt) do
begin
sizeOfArray := sizeOfArray + 1;
SetLength(Decrypted, sizeOfArray);
S := KSA(key);
keystream := PRGA(S, length(plaintext));
Decrypted[i] := (keystream[i] xor DecryptArrayInt[i]);
end;
decryptedString := '';
// Turn array to string
for i := 0 to high(Decrypted) do
decryptedString := decryptedString + chr(Decrypted[i]);
decrypt := decryptedString;
end;
procedure encryptDecrypt;
var
cipherString, DecryptedString : string;
DecryptArrayString : dynamicArrayString;
DecryptArrayInt : dynamicArray;
begin
cipherString := encrypt;
writeln(cipherString);
DecryptArrayString := stringToHex(cipherString);
DecryptArrayInt := hexToDecimal(DecryptArrayString);
DecryptedString := decrypt(DecryptArrayInt);
writeln(DecryptedString);
end;
begin
getPlaintext;
encryptDecrypt;
readln;
end.
I've not been able to find the many specific cases that makes the program crash apart from a string of any three characters will always crash in {$mode fpc} but not in {$mode objfpc}
You should debug (and watch) your code so any error can be traced more easily. Use the FP IDE, it helps a lot.
Meanwhile, watch this line:
keystream := PRGA(S, length(plaintext));
And inside the PRGA function watch these lines:
sizeOfArray := n - 1;
SetLength(key, sizeOfArray);
What's wrong here? Well, suppose "plaintext" has only 1 character. So, "Length(plaintext)"=1, right? In PRGA you do "sizeOfArray:= n-1;", so sizeOfArray = 0. When you do SetLength, "Key" will be NIL because you're indicating a zero indexes length. Later, on loop, you have:
key[i-1] := K;
the program will fail because you are accessing at index 0 and the Key variable is NIL.
Careful: On "SetLength(key, sizeOfArray);" valid indexes for key are in range [0..sizeOfArray-1], but sizeOfArray must be at least 1 to be valid (sizeOfArray >= 1).
So, you should check your PRGA function. It's up to you to find the definitive solution. Don't give up. Good luck!

Permutation of numbers - all possible combinations [duplicate]

this is my simple code to generate
all possible combinations of a set for
example
1,2,3:
Display:
123
132
213
231
312
321
i want to create variable number of for loops to let the user determine the length of given string...
does anyone have an idea...
thank's in advance.
type
TNumber = '0'..'9';
procedure TForm1.Button1Click(Sender: TObject);
var
Numbers: array[0..3] of TNumber;
a, b, c, d: Integer;
s: string;
begin
Numbers[0] := '1';
Numbers[1] := '8';
Numbers[2] := '7';
Numbers[3] := '2';
for a := low(Numbers) to High(Numbers) do
for b := low(Numbers) to High(Numbers) do
for c := low(Numbers) to High(Numbers) do
for d := low(Numbers) to High(Numbers) do
begin
s := Numbers[a] + Numbers[b] + Numbers[c] + Numbers[d];
if
(Occurrences('1', s) > 1 ) or
(Occurrences('8', s) > 1 ) or
(Occurrences('7', s) > 1 ) or
(Occurrences('2', s) > 1 )
then
Continue
else
Memo1.Lines.Add(s);
end;
end;
function TForm1.Occurrences(const Substring, Text: string): Integer;
var
Offset: Integer;
begin
Result := 0;
Offset := PosEx(Substring, Text, 1);
while Offset <> 0 do
begin
Inc(Result);
Offset := PosEx(Substring, Text, offset + length(Substring));
end;
end;
end.
Here is some code that produces the output you desire. You'd need to work it around a bit for your needs, but the concept expressed in this recursive solution is the important thing:
program Permuatations;
{$APPTYPE CONSOLE}
type
TElements = '1'..'3';
procedure EnumerateCombinations(const Stem: string; Len: Integer);
var
i: Integer;
el: TElements;
Used: set of TElements;
begin
if Len=0 then
exit;
Used := [];
for i := 1 to Length(Stem) do
Include(Used, Stem[i]);
for el := low(el) to high(el) do
begin
if el in Used then
continue;
if Len=1 then
Writeln(Stem+el)
else
EnumerateCombinations(Stem+el, Len-1)
end;
end;
procedure Main;
begin
EnumerateCombinations('', 1+ord(high(TElements))-ord(low(TElements)));
end;
begin
Main;
Readln;
end.
Output:
123
132
213
231
312
321
If you change the definition of TElements, for example to '1'..'4' then you will see the 24 possible permutations.

Resources