Writing raw bits to a file in Lazarus - data-conversion

Let's suppose I generate a string of randomly ordered 1's and 0's.
If I write said string to a file, it will be written as an ANSI string, which is not what I want to do. I want to instead write the 1's and 0's in the string as raw bits. How can I achieve this?

You could iterate through the input string, character by character, and replace every '0' by a #0, and every '1' by a #1.
const
txt = '0001010001011110101110101010000001011111';
var
s: String;
i: Integer;
begin
SetLength(s, Length(txt));
for i:=1 to Length(txt) do
if txt[i] = '0' then
s[i] := #0
else if txt[i] = '1' then
s[i] := #1
else
begin
WriteLn('Unsupported character in input string');
Halt;
end;
//... write to file here (you should know how to do it) ...
end;
Or you could subtract the ordinal value of the character '0' from each character and cast the result back to char. The result will be #0 for '0' or #1 for '1'.
SetLength(s, Length(txt));
for i := 1 to Length(txt) do
s[i] := char(ord(txt[i]) - ord('0'));

Related

How to count number of occurrences of a character in an array in Pascal

I have to script a pascal code that rations into calculation the frequency of a character's appearance in the code and displays it through the output mode
Input P2 changes:
Second Attempt at the coding phase
I tried revisioning the code.I added the output variable writeln('input array of characters'); & writeln('Number of Occurrences',k);, which should help me output how many times did the S character appear overall in the code, plus utilised the for & if commands to have the final values showcased based on the conditions, if the frequency is 1 then count in S, still getting errors, take a look at the Input P2 & Output P2
Input P1
function Count(t, s: String): Integer;
var
Offset, P: Integer;
begin
Result := 0;
Offset := 1;
P := PosEx(t, s, Offset);
while P > 0 do
begin
Inc(Result);
P := PosEx(t, s, P + 1);
end;
end;
Output P2
Target OS: Linux for x86-64
Compiling main.pas
main.pas(5,3) Error: Identifier not found "Result"
main.pas(7,8) Error: Identifier not found "PosEx"
main.pas(8,3) Error: Identifier not found "unsigned"
main.pas(8,12) Fatal: Syntax error, ";" expected but "identifier N" found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
-------------------------------------------------------------------
Input P2
program p1
var S:string
i:integer
begin
writeln('input array of characters');
k:=O;
for i:=1 to length (S) do
if (S[i])='m') and (S[i+1]='a') then k:=k+1;
writeln('Number of Occurrences',k);
Readln;
end.
Output P2
Compiling main.pas
main.pas(2,1) Fatal: Syntax error, ";" expected but "VAR" found
Fatal: Compilation aborted
Error: /usr/bin/ppcx64 returned an error exitcode
The errors you see in the first block:
Identifier not found "Result"
Standard Pascal doesn't recognize the pseudovariable Result. In some Pascal implementations (like e.g. Delphi) it can be used to assign a value to the function result. The Pascal you are using needs to have the result of a function assigned to the name of the function. For example:
function Whatever(): integer;
begin
Whatever := 234;
end;
Identifier not found "PosEx"
Not all Pascal implementations include the PosEx() function. You need to use Pos() instead. But, the standard implementation of Pos() doesn't include the "search start position" that PosEx has. Therefore you need to ditch Pos() and do as you do in "Input P2", that is traverse the text character per character and count the occurances as you go.
Identifier not found "unsigned"
Seems you have removed that unknown identifier.
The error you see in the second block:
In Output P2 the error message should be clear. You are missing a semicolon where one is needed. Actually you are missing three of them.
You are also missing the line that reads user input: ReadLn(S);.
Finally, to calculate both upper and lower case characters you can use an extra string variable, say SU: string to which you assign SU := UpperCase(S) after reading user input, and then use that string to count the occurances.
I think this is more like what you want to do:
function Count(t, s: String): Integer;
var
Offset,Res, P: Integer;
begin
Res := 0
Offset := 1;
repeat
P := Pos(t, s, Offset);
if p>0 then
Inc(Res);
Offset := P+1
untl P = 0;
Count := Res;
end;
Now, if you don't have Pos, you can implement it:
Function Pos(const t,s:string; const Start:integer):Integer;
Var
LS, LT, {Length}
IxS, IxT, {Index)
R: Integer; {Result}
begin
R := 0;
{use only one of the two following lines of code}
{if your compiler has length}
LS := length(S); LT := Length(T);
{If it does not}
LS := Ord(s[0]); LT := Ord(T[0]);
if (LS <= LT) {if target is larger than search string, it's not there}
and (Start<=LT) and {same if starting position beyond size of S}
(Start+LT <-LS) then {same if search would go beyond size of S}
begin {Otherwise, start the search}
ixT := 1;
ixS := Start;
repeat
Inc(R); {or R:= R+1; if INC not available }
If (S[ixS] <> T[ixT]) then
R := 0 {they don't match, we're done}
else
begin {Move to next char}
Inc(ixS);
Inc(ixT);
end;
until (R=0) or (ixT>LT); {if search failed or end of target, done}
Pos := R;
end;

Need help understanding how gsub and tonumber are used to encode lua source code?

I'm new to LUA but figured out that gsub is a global substitution function and tonumber is a converter function. What I don't understand is how the two functions are used together to produce an encoded string.
I've already tried reading parts of PIL (Programming in Lua) and the reference manual but still, am a bit confused.
local L0_0, L1_1
function L0_0(A0_2)
return (A0_2:gsub("..", function(A0_3)
return string.char((tonumber(A0_3, 16) + 256 - 13 + 255999744) % 256)
end))
end
encodes = L0_0
L0_0 = gg
L0_0 = L0_0.toast
L1_1 = "__loading__\226\128\166"
L0_0(L1_1)
L0_0 = encodes
L1_1 = --"The Encoded String"
L0_0 = L0_0(L1_1)
L1_1 = load
L1_1 = L1_1(L0_0)
pcall(L1_1)
I removed the encoded string where I put the comment because of how long it was. If needed I can upload the encoded string as well.
gsub is being used to get 2 digit sections of A0_2. This means the string A0_3 is a 2 digit hexadecimal number but it is not in a number format so we cannot preform math on the value. A0_3 being a hex number can be inferred based on how tonubmer is used.
tonumber from Lua 5.1 Reference Manual:
Tries to convert its argument to a number. If the argument is already a number or a string convertible to a number, then tonumber returns this number; otherwise, it returns nil.
An optional argument specifies the base to interpret the numeral. The base may be any integer between 2 and 36, inclusive. In bases above 10, the letter 'A' (in either upper or lower case) represents 10, 'B' represents 11, and so forth, with 'Z' representing 35. In base 10 (the default), the number can have a decimal part, as well as an optional exponent part (see ยง2.1). In other bases, only unsigned integers are accepted.
So tonumber(A0_3, 16) means we are expecting for A0_3 to be a base 16 number (hexadecimal).
Once we have the number value of A0_3 we do some math and finally convert it to a character.
function L0_0(A0_2)
return (A0_2:gsub("..", function(A0_3)
return string.char((tonumber(A0_3, 16) + 256 - 13 + 255999744) % 256)
end))
end
This block of code takes a string of hex digits and converts them into chars. tonumber is being used to allow for the manipulation of the values.
Here is an example of how this works with Hello World:
local str = "Hello World"
local hex_str = ''
for i = 1, #str do
hex_string = hex_string .. string.format("%x", str:byte(i,i))
end
function L0_0(A0_2)
return (A0_2:gsub("..", function(A0_3)
return string.char((tonumber(A0_3, 16) + 256 - 13 + 255999744) % 256)
end))
end
local encoded = L0_0(hex_str)
print(encoded)
Output
;X__bJbe_W
And taking it back to the orginal string:
function decode(A0_2)
return (A0_2:gsub("..", function(A0_3)
return string.char((tonumber(A0_3, 16) + 13) % 256)
end))
end
hex_string = ''
for i = 1, #encoded do
hex_string = hex_string .. string.format("%x", encoded:byte(i,i))
end
print(decode(hex_string))

How to convert a string to a number

Is there a toInt, or parseInt function? There appears to be a StringToBinary, but I don't need a binary representation, I just want the number.
Be aware, that Number() works in one case unexpected. Strings will converted to 0, but "0" also. You have no chance, to see the difference. It's written in the help file (A string beginning with letters has a numeric value of zero.), but it is not satisfactory.
I've made my own function, that exactly works, like Number(). But if you pass an expression, that is a string or starts with a string, this returns an numeric value of your choice (default: 0xDEADBEEF) and sets #error to 1.
; #FUNCTION# ====================================================================================================================
; Name ..........: _Number
; Description ...: Works like "Number()", but avoids to convert a string to number 0!
; Syntax ........: _Number($_Expression, $_Flag)
; Parameters ....: $_Expression - An expression to convert into a number.
; ...............: $_iErrReturn - The numeric return value in error case. Default: 0xDEADBEEF
; ...............: You get also the default value by passing "Default" or empty string instaed.
; ...............: $_Flag - Can be one of the following:
; ...............: $NUMBER_AUTO (0) = (default) the result is auto-sized integer.
; ...............: $NUMBER_32BIT (1) = the result is 32bit integer.
; ...............: $NUMBER_64BIT (2) = the result is 64bit integer.
; ...............: $NUMBER_DOUBLE (3) = the result is double.
; Return values .: Success The converted number, if $_Expression is a number or starts with a (un/signed) number.
; ...............: Failure The Value from "$_iErrReturn", sets #error = 1 $_Expression is a string or starts with a string.
; Author ........: BugFix
; Remarks .......: In contrast to Number(), you get only a number, if $_Expression is a number or starts with it.
; ...............: Because 0 is also a number, Number() give unclear results:
; ...............: Number("foo") returns 0. Number("0") returns also 0. "0" converts to the real number 0, but "foo" also??
; ===============================================================================================================================
Func _Number($_Expression, $_iErrReturn=0xDEADBEEF, $_Flag=0)
If $_iErrReturn = Default Or $_iErrReturn = '' Then $_iErrReturn = 0xDEADBEEF
If StringRegExp($_Expression, '^(-\s\d|-\d|\d)') Then
Return Number($_Expression, $_Flag)
Else
Return SetError(1, 0, $_iErrReturn)
EndIf
EndFunc ;==>_Number
I figured it out, use the Number() function.
Number("5") becomes 5.

Missing operand in for loop

I have such a bubble sort statement;
procedure Bubble_Sort (Data: in out List) is
sorted: Boolean := false;
last : Integer := Data'LAST;
temp : Integer;
begin
while (not (sorted)) loop
sorted := true;
for check in range Data'First..(last-1) loop
if Data(check) < Data(check+1) then
-- swap two elements
temp := Data(check);
Data(check) := Data(check+1);
Data(check+1) := temp;
-- wasn't already sorted after all
sorted := false;
end if;
end loop;
last := last - 1;
end loop;
end Bubble_sort;
I have defined 'Data' like this:
Unsorted : constant List := (10, 5, 3, 4, 1, 4, 6, 0, 11, -1);
Data : List(Unsorted'Range);
And the type definition of 'List' is;
type List is array (Index range <>) of Element;
on the line
for check in range Data'Range loop
I get missing operand error. How can I solve this problem?
remove the range keyword:
for check in Data'Range loop
The range keyword is used to define ranges and subtypes (sometimes anonymous), which is not needed when you use the 'Range attribute.

Pascal. Recursive function to count amount of odd numbers in the sequence

I need to write recursive function to count amount of odd numbers in the sequence
Here my initial code:
program OddNumbers;
{$APPTYPE CONSOLE}
uses
SysUtils;
function GetOddNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
if((x[i] <> 0) and (x[i] mod 2=0)) then
begin
count:= count + 1;
GetOddNumbersAmount:=count;
end;
i:=i+1;
GetOddNumbersAmount:=GetOddNumbersAmount(x, count, i);
end;
var X: array[1..10] of integer;
i,amount: integer;
begin
writeln('Enter your sequence:');
for i:=1 to 10 do
read(X[i]);
amount:= GetOddNumbersAmount(X, 0, 1);
writeln('Amount of odd numbers: ', amount);
readln;
readln;
end.
When i type the sequence and press "enter", program closed without any errors and i can't see the result.
Also, i think my function isn't correct.
Can someone help with that code?
UPD:
function GetOddNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
if((x[i] <> 0) and (x[i] mod 2<>0)) then
count:= count + 1;
if(i = 10) then
GetOddNumbersAmount:=count
else
GetOddNumbersAmount:=GetOddNumbersAmount(x, count, i+1);
end;
You don't provide an end of recursion, i.e., you always call your function GetOddNumbersAmount again, and your program never terminates. Thus, you get an array index error (or a stack overflow) and your program crashes.
Please note, that every recursion need a case where it terminates, i.e. does not call itself. In your case, it should return if there are no elements in the array left.
In addition, you are counting the even numbers, not the odd ones.
You passed a static array to a dynamic so the index get confused:
Allocat the array with
SetLength(X,10)
allocates an array of 10 integers, indexed 0 to 9.
Dynamic arrays are always integer-indexed, always starting from 0!
SetLength(X,10)
for it:=0 to 9 do begin
X[it]:= random(100);
And second if you know the length a loop has more advantages:
function GetEvenNumbersAmount(const x: array of integer; count,i:integer):integer;
begin
for i:= 0 to length(X)-1 do
if((x[i] <> 0) and (x[i] mod 2=0)) then begin
inc(count);
//write(inttostr(X[i-1])+ ' ') :debug
end;
result:=count;
end;

Resources