Sunteți pe pagina 1din 12

Problema de rezolvat:

Extindeți proiectul atașat. Să se implementeze și factorialul unui număr binar dat.

Pe prima linie aplicația primește codul operației:


1 - conversie de la baza 10 la baza 2
2 - conversie de la baza 2 la baza 10
3 - aplicarea operatorului NOT pe numărul în baza doi primit
4 - aplicarea operatorului OR pentru două numere binare date
5 - aplicarea operatorului AND pentru două numere binare date
6 - aplicarea operatorului XOR pentru două numere binare date
7 - mutare la stânga (shift left) N poziții pentru un număr binar dat
8 - mutare la dreapta (shift right) N poziții pentru un număr binar dat
9 - compară două numere binare date (operatorul mai mic decât - less than)
10 - compară două numere binare date (operatorul mai mare decât - greater than)
11 - compară două numere binare date (operatorul egal - equal)
12 - compară două numere binare date (operatorul diferit - not equal)
13 - adună două numere binare
14 - scăderea a două numere binare
15 - înmulțirea a două numere binare
16 - împărțirea a două numere binare
17 - factorialul unui număr binar dat

Pe următoarele linii sunt numărul sau numerele pentru care se execută operația
(câte un număr pe linie).

Exemplu:

Pentru datele de intrare:

17
100
La consolă se va afișa:

11000

using System;

namespace BinaryOperations
{
class Program
{
const int NumericalBase = 2;

const int OperationConvertToBinary = 1;


const int OperationConvertFromBinary = 2;
const int OperationBinaryNot = 3;
const int OperationBinaryOr = 4;
const int OperationBinaryAnd = 5;
const int OperationBinaryXor = 6;
const int OperationBinaryShiftLeft = 7;
const int OperationBinaryShiftRight = 8;
const int OperationBinaryLessThan = 9;
const int OperationBinaryGreaterThan = 10;
const int OperationBinaryEqual = 11;
const int OperationBinaryNotEqual = 12;
const int OperationBinaryAdd = 13;
const int OperationBinarySubstract = 14;
const int OperationBinaryMultiply = 15;
const int OperationBinaryDivide = 16;
const int OperationBinaryFactorial = 17;

static void Main()


{
if (int.TryParse(Console.ReadLine(), out int operation) && operation >=
OperationConvertToBinary && operation <= OperationBinaryFactorial)
{
ExecuteOperation(operation);
}
else
{
Console.WriteLine("Operatie invalida.");
}

Console.Read();
}

static void ExecuteOperation(int operation)


{
if (operation >= OperationConvertToBinary && operation <=
OperationConvertFromBinary)
{
ExecuteConversionOperation(operation);
return;
}

if (operation >= OperationBinaryNot && operation <= OperationBinaryXor)


{
ExecuteLogicalOperation(operation);
return;
}

if (operation >= OperationBinaryShiftLeft && operation <=


OperationBinaryShiftRight)
{
ExecuteShiftOperation(operation);
return;
}

if (operation >= OperationBinaryLessThan && operation <=


OperationBinaryNotEqual)
{
ExecuteComparisonOperation(operation);
return;
}

if (operation == OperationBinaryFactorial)
{
ExecuteFactorialOperation(operation);
return;
}

ExecuteArithmeticalOperation(operation);
}

private static void ExecuteArithmeticalOperation(int operation)


{
if (operation == OperationBinaryDivide)
{
BinaryDivideOperation();
}
else
{
BaseBinaryOperation(operation);
}
}

private static void ExecuteLogicalOperation(int operation)


{
if (operation == OperationBinaryNot)
{
BinaryNotOperation();
}
else
{
BaseBinaryOperation(operation);
}
}

private static void ExecuteConversionOperation(int operation)


{
if (operation == OperationConvertToBinary)
{
ConvertToBinaryOperation();
}
else
{
ConvertFromBinaryOperation();
}
}

static void BinaryDivideOperation()


{
if (!ReadBinaryNumber(out byte[] firstBinaryNumber))
{
return;
}

if (!ReadBinaryNumber(out byte[] secondBinaryNumber))


{
return;
}

if (BinaryComparison(secondBinaryNumber, new byte[] { 0 },


OperationBinaryEqual))
{
Console.WriteLine("Nu se poate imparti la 0!");
return;
}

byte[] resultedBinaryNumber = BinaryDivide(firstBinaryNumber,


secondBinaryNumber);
Console.WriteLine(BinaryNumberToString(resultedBinaryNumber));
}

static byte[] BinaryAdd(byte[] firstBinaryNumber, byte[]


secondBinaryNumber)
{
var (shorter, longer) = GetShorterAndLongerNumber(firstBinaryNumber,
secondBinaryNumber);
byte[] result = new byte[longer.Length];
int reminder = 0;

for (int i = 0; i < shorter.Length; i++)


{
result[i] = (byte)((shorter[i] + longer[i] + reminder) %
NumericalBase);
reminder = (shorter[i] + longer[i] + reminder) / NumericalBase;
}

for (int i = shorter.Length; i < longer.Length; i++)


{
result[i] = (byte)((longer[i] + reminder) % NumericalBase);
reminder = (longer[i] + reminder) / NumericalBase;
}

if (reminder == 1)
{
result = AddBinaryDigit(result, 1);
}

return result;
}

static void ExecuteComparisonOperation(int comparisonOperator)


{
if (!ReadBinaryNumber(out byte[] firstBinaryNumber))
{
return;
}

if (!ReadBinaryNumber(out byte[] secondBinaryNumber))


{
return;
}

Console.WriteLine(BinaryComparison(firstBinaryNumber,
secondBinaryNumber, comparisonOperator));
}

static bool BinaryComparison(byte[] firstNumber, byte[] secondNumber, int


comparisonOperator)
{
return comparisonOperator switch
{
OperationBinaryLessThan => BinaryLessThan(firstNumber,
secondNumber),
OperationBinaryGreaterThan => BinaryLessThan(secondNumber,
firstNumber),
OperationBinaryEqual => !BinaryLessThan(firstNumber, secondNumber)
&& !BinaryLessThan(secondNumber, firstNumber),
OperationBinaryNotEqual => BinaryLessThan(firstNumber,
secondNumber) || BinaryLessThan(secondNumber, firstNumber),
_ => false,
};
}

static bool BinaryLessThan(byte[] firstBinaryNumber, byte[]


secondBinaryNumber)
{
int firstLength = GetBinaryNumberRealLength(firstBinaryNumber);
int secondLength = GetBinaryNumberRealLength(secondBinaryNumber);
int x = 0;

if (firstLength < secondLength)


{
return true;
}

if (firstLength > secondLength)


{
return false;
}

for (int i = firstLength - 1; i >= 0; i--)


{
if (firstBinaryNumber[i] > secondBinaryNumber[i])
{
return false;
}

if (firstBinaryNumber[i] < secondBinaryNumber[i])


{
return true;
}

if (firstBinaryNumber[i] == secondBinaryNumber[i])
{
x++;
if (x == firstLength)
{
return false;
}
}
}

return true;
}

static int GetBinaryNumberRealLength(byte[] binaryNumber)


{
int result = binaryNumber.Length;
while (result > 1 && binaryNumber[result - 1] == 0)
{
result--;
}

return result;
}

static void ExecuteShiftOperation(int shiftType)


{
if (!ReadBinaryNumber(out byte[] binaryNumber))
{
return;
}

if (int.TryParse(Console.ReadLine(), out int positions) && positions <


0)
{
Console.WriteLine("Numarul de pozitii trebuie sa fie intreg si
pozitiv.");
return;
}

byte[] resultedBinaryNumber = ApplyShiftOperation(binaryNumber,


shiftType, positions);
Console.WriteLine(BinaryNumberToString(resultedBinaryNumber));
}

static byte[] ApplyShiftOperation(byte[] binaryNumber, int shiftType, int


positions)
{
int newLength = shiftType == OperationBinaryShiftLeft ?
binaryNumber.Length + positions :
binaryNumber.Length - positions;

if (newLength < 1)
{
return new byte[] { 0 };
}

Array.Reverse(binaryNumber);
Array.Resize(ref binaryNumber, newLength);
Array.Reverse(binaryNumber);
return binaryNumber;
}

static void ExecuteFactorialOperation(int operation)


{
if (!ReadBinaryNumber(out byte[] firstBinaryNumber))
{
return;
}

byte[] resultedBinaryNumber = BinaryFactorial(firstBinaryNumber);


Console.WriteLine(BinaryNumberToString(resultedBinaryNumber));
}

static void BaseBinaryOperation(int operationType)


{
if (!ReadBinaryNumber(out byte[] firstBinaryNumber))
{
return;
}

if (!ReadBinaryNumber(out byte[] secondBinaryNumber))


{
return;
}

byte[] resultedBinaryNumber = ApplyBinaryOperation(firstBinaryNumber,


secondBinaryNumber, operationType);
Console.WriteLine(BinaryNumberToString(resultedBinaryNumber));
}

static byte[] ApplyBinaryOperation(byte[] firstBinaryNumber, byte[]


secondBinaryNumber, int operationType)
{
switch (operationType)
{
case OperationBinaryOr:
case OperationBinaryAnd:
case OperationBinaryXor:
return BinaryLogicalOperation(firstBinaryNumber,
secondBinaryNumber, operationType);
case OperationBinaryAdd:
return BinaryAdd(firstBinaryNumber, secondBinaryNumber);
case OperationBinarySubstract:
return BinarySubtract(firstBinaryNumber, secondBinaryNumber);
case OperationBinaryMultiply:
return BinaryMultiply(firstBinaryNumber, secondBinaryNumber);
}

return null;
}

static byte[] BinaryDivide(byte[] dividend, byte[] divisor)


{
byte[] result = { 0 };
while (BinaryLessThan(divisor, dividend) ||
BinaryComparison(divisor, dividend, OperationBinaryEqual))
{
dividend = BinarySubtract(dividend, divisor);
result = BinaryAdd(result, new byte[] { 1 });
}

return result;
}

static byte[] BinaryMultiply(byte[] firstBinaryNumber, byte[]


secondBinaryNumber)
{
var (bigger, smaller) = GetBiggerAndSmallerNumber(firstBinaryNumber,
secondBinaryNumber);
byte[] result = { 0 };
for (byte[] index = { 0 }; BinaryLessThan(index, smaller); index =
BinaryAdd(index, new byte[] { 1 }))
{
result = BinaryAdd(result, bigger);
}

return result;
}

static byte[] BinaryFactorial(byte[] firstBinaryNumber)


{
byte[] one = { 1 };
byte[] zero = { 0 };
byte[] result = { 0 };
byte[] operation = firstBinaryNumber;
for (byte[] i = BinarySubtract(firstBinaryNumber, one);
BinaryLessThan(zero, i); i = BinarySubtract(i, one))
{
operation = BinaryMultiply(operation, i);
result = operation;
}

if (BinaryNumberToString(one) ==
BinaryNumberToString(firstBinaryNumber))
{
result = firstBinaryNumber;
}

return result;
}

static byte[] BinarySubtract(byte[] firstBinaryNumber, byte[]


secondBinaryNumber)
{
var (bigger, smaller) = GetBiggerAndSmallerNumber(firstBinaryNumber,
secondBinaryNumber);
byte[] result = new byte[GetBinaryNumberRealLength(bigger)];
int smallerLength = GetBinaryNumberRealLength(smaller);
int reminder = 0;

for (int i = 0; i < result.Length; i++)


{
int digit = i < smallerLength ?
bigger[i] - smaller[i] - reminder :
bigger[i] - reminder;

if (digit < 0)
{
result[i] = (byte)(digit * -1 % NumericalBase);
reminder = 1;
}
else
{
result[i] = (byte)digit;
reminder = 0;
}
}

return result;
}

static byte[] BinaryLogicalOperation(byte[] firstBinaryNumber, byte[]


secondBinaryNumber, int operationType)
{
var (shorter, longer) = GetShorterAndLongerNumber(firstBinaryNumber,
secondBinaryNumber);
byte[] result = new byte[longer.Length];

for (int i = 0; i < shorter.Length; i++)


{
result[i] = CalculateLogicalOperationResult(shorter[i], longer[i],
operationType);
}

for (int i = shorter.Length; i < longer.Length; i++)


{
result[i] = CalculateLogicalOperationResult(0, longer[i],
operationType);
}

return result;
}

static byte CalculateLogicalOperationResult(byte firstDigit, byte


secondDigit, int operationType)
{
return operationType switch
{
OperationBinaryOr => (byte)(firstDigit + secondDigit > 0 ? 1 : 0),
OperationBinaryAnd => (byte)(firstDigit + secondDigit ==
NumericalBase ? 1 : 0),
OperationBinaryXor => (byte)(firstDigit + secondDigit == 1 ? 1 :
0),
_ => 0,
};
}

static (byte[] shorter, byte[] longer) GetShorterAndLongerNumber(byte[]


firstBinaryNumber, byte[] secondBinaryNumber)
{
byte[] shorter;
byte[] longer;

if (firstBinaryNumber.Length > secondBinaryNumber.Length)


{
shorter = secondBinaryNumber;
longer = firstBinaryNumber;
}
else
{
shorter = firstBinaryNumber;
longer = secondBinaryNumber;
}

return (shorter, longer);


}

static (byte[] bigger, byte[] smaller) GetBiggerAndSmallerNumber(byte[]


firstBinaryNumber, byte[] secondBinaryNumber)
{
byte[] bigger;
byte[] smaller;

if (BinaryLessThan(firstBinaryNumber, secondBinaryNumber))
{
bigger = secondBinaryNumber;
smaller = firstBinaryNumber;
}
else
{
bigger = firstBinaryNumber;
smaller = secondBinaryNumber;
}
return (bigger, smaller);
}

static void BinaryNotOperation()


{
if (!ReadBinaryNumber(out byte[] binaryNumber))
{
return;
}

binaryNumber = ApplyBinaryNot(binaryNumber);
Console.WriteLine(BinaryNumberToString(binaryNumber));
}

static byte[] ApplyBinaryNot(byte[] binaryNumber)


{
for (int i = 0; i < binaryNumber.Length; i++)
{
binaryNumber[i] = (byte)((binaryNumber[i] + 1) % NumericalBase);
}

return binaryNumber;
}

static void ConvertFromBinaryOperation()


{
if (!ReadBinaryNumber(out byte[] binaryNumber))
{
return;
}

Console.WriteLine(ConvertToDecimal(binaryNumber));
}

static bool ReadBinaryNumber(out byte[] binaryNumber)


{
bool result = TryParseBinaryNumberFromString(Console.ReadLine(), out
binaryNumber);
if (!result)
{
Console.WriteLine("Nu s-a introdus un numar binar valid (format
doar din 0 si 1).");
}

return result;
}

static int ConvertToDecimal(byte[] binaryNumber)


{
int result = 0;
int power = 1;
for (int i = 0; i < binaryNumber.Length; i++)
{
result += binaryNumber[i] * power;
power *= NumericalBase;
}

return result;
}
static bool TryParseBinaryNumberFromString(string binaryNumberText, out
byte[] binaryNumber)
{
binaryNumber = new byte[binaryNumberText.Length];
if (binaryNumberText.Length == 0)
{
return false;
}

for (int i = 0; i < binaryNumberText.Length; i++)


{
if (binaryNumberText[i] != '0' && binaryNumberText[i] != '1')
{
return false;
}

binaryNumber[binaryNumber.Length - i - 1] =
Convert.ToByte(binaryNumberText[i].ToString());
}

return true;
}

static void ConvertToBinaryOperation()


{
if (int.TryParse(Console.ReadLine(), out int number) && number > 0)
{
byte[] binaryNumber = ConvertToBinary(number);
Console.WriteLine(BinaryNumberToString(binaryNumber));
}
else
{
Console.WriteLine("Programul converteste doar numere intregi
pozitive.");
}
}

static string BinaryNumberToString(byte[] binaryNumber)


{
string result = "";
bool initialZeros = true;
for (int i = binaryNumber.Length - 1; i >= 0; i--)
{
if (binaryNumber[i] == 0 && initialZeros)
{
continue;
}

initialZeros = false;
result += binaryNumber[i];
}

if (result == "")
{
result = "0";
}

return result;
}

static byte[] ConvertToBinary(int number)


{
byte[] result = null;
while (number != 0)
{
result = AddBinaryDigit(result, (byte)(number % NumericalBase));
number /= NumericalBase;
}

return result;
}

static byte[] AddBinaryDigit(byte[] binaryNumber, byte digit)


{
byte[] result = binaryNumber ?? (new byte[0]);
Array.Resize(ref result, result.Length + 1);

result[^1] = digit;
return result;
}
}
}

S-ar putea să vă placă și