Converting binary array to decimal string strange behaviour - php

I'm currently implement left shift using int[] arrays in php and need to get back the decimal after operation. So I have written the following snippet to attempt conversion of binary array to decimal.
function bin2dec($bin)
{
$length = count($bin) - 1;
$sum = 0;
//convert using doubling
for($i = 0; $i < $length; $i++)
{
//use string_add if doubling bigger than int32
if($i >= 16)
{
$double = $this->string_add("$sum", "$sum");
$cr = $bin[$i];
if($cr == 0)
{
$sum = $this->string_add($sum, $double);
}
else{
return $i;//WHAT's UP??!
$add = $this->string_add($double, "$cr");
$sum = $this->string_add($sum, $add);
}
}
else{
$sum += ($sum * 2) + $bin[$i];
}
}
return $sum;
}
Now the weird problem is in the loop where $cr != 0, $i returns an unbelievable value already not satisfying the loop condition but I can't figure out why this is happening. Here's the rest of the relevant code.
function string_add($a, $b)
{
$lena = strlen($a); $lenb = strlen($b);
if($lena == $lenb)
{
$len = $lena - 1;//any
}
else if($lena > $lenb)
{
$b = str_pad($b, $lena, "0", STR_PAD_LEFT);
$len = $lena - 1;
}
else if($lenb > $lena){
$a = str_pad($a, $lenb, "0", STR_PAD_RIGHT);
$len = $lenb - 1;
}
$result = "";
for ($i = $len, $carry = 0; $i >= 0 || $carry != 0; $i--)
{
$add1 = $i < 0 ? 0 : $a[$i];
$add2 = $i < 0 ? 0 : $b[$i];
$add = $add1 + $add2 + $carry;
if ($add > 9) {
$carry = 1;
$add -= 10;
}
else {
$carry = 0;
}
$result .= $add;
}
return strrev($result);
}
$arr = array_pad(array(1), 62, 0);
$dec = bin2dec($arr);
return $dec;//test
I have also implemented a working version on ideone for testing. Does anyone understand why this is happening?
Thanks.

Ok, so apparently the problem was adding more than needed and unnecessarily subtracting 1 from length in bin2dec. Here's the final working version:
<?php
class MyClass{
function bin2dec($bin)
{
$length = count($bin);
$sum = 0;
//convert using doubling
for($i = 0; $i < $length; $i++)
{
//use string_add if doubling bigger than int32
if($i >= 16)
{
$sum = $this->string_add("$sum", "$sum");
$cr = $bin[$i];
if($cr != 0){
$sum = $this->string_add($sum, "$cr");
}
}
else{
$sum += $sum + $bin[$i];
}
}
return $sum;
}
function string_add($a, $b)
{
$lena = strlen($a); $lenb = strlen($b);
if($lena == $lenb)
{
$len = $lena - 1;//any
}
else if($lena > $lenb)
{
$b = str_pad($b, $lena, "0", STR_PAD_LEFT);
$len = $lena - 1;
}
else if($lenb > $lena){
$a = str_pad($a, $lenb, "0", STR_PAD_RIGHT);
$len = $lenb - 1;
}
$result = "";
for ($i = $len, $carry = 0; $i >= 0 || $carry != 0; $i--)
{
$add1 = $i < 0 ? 0 : $a[$i];
$add2 = $i < 0 ? 0 : $b[$i];
$add = $add1 + $add2 + $carry;
if ($add > 9) {
$carry = 1;
$add -= 10;
}
else {
$carry = 0;
}
$result .= $add;
}
return strrev($result);
}
}
$man = new MyClass();
$arr = array_pad(array(1), 62, 0);
$dec = $man->bin2dec($arr);
echo $dec;

Using strings...
function bin2dec($bin)
{
$length = count($bin);
$sum = "";
for ( $i = 0; $i < $length; $i++)
{
$sum = $sum . ( $bin[$i} == 0 ? '0' : '1');
}
return $sum;
}
function string_add($a, $b)
{
// not efficient, but obvious
$maxlen = ( strlen($a) > strlen($b) ? strlen($a) : strlen($b);
// make them both same length as longest
$a = str_pad($a, $maxlen, "0", STR_PAD_LEFT);
$b = str_pad($b, $maxlen, "0", STR_PAD_LEFT);
$result = "";
$carry = 0;
// start from the right end
for ($i = $maxlen - 1; $i >= 0; $i--)
{
$val = $a[$i] + $b[$i] + $carry;
$result = ( $val % 10 ) . $result;
$carry = $val / 10;
}
// handle final carry if present
if ( $carry > 0 )
{
$result = $carry . $result;
}
return $result;
}
$arr = array_pad(array(1), 62, 0);
$dec = bin2dec($arr);
return $dec;//test

Related

Unneccesary new line php

I have a PHP code. The code is supposed to print the output followed by a new line.
The code works fine but i have unneccesary new line at the end. There should be only one newline at the end, but my code prints several new lines. What could be the issue? Please help.
<?php
/* Read input from STDIN. Print your output to STDOUT*/
$fp = fopen("php://stdin", "r");
//Write code here
$loop = 0;
$n = 0; $arr = [];
while(!feof($fp)) {
$arr = []; $n = 0;
if($loop == 0) {
$total = fgets($fp);
}
else {
if($loop%2 == 1) {
$n = fgets($fp);
}
else {
$arr = fgets($fp);
}
}
if($loop > 0 && $loop%2 == 0) {
$arr = explode(" ", $arr);
$m = [];
for($i = 0; $i < 1<<10; $i++) {
$m[$i] = -1;
}
$n = count($arr);
$r = 0;
for($i = 0; $i < 1<<10; $i++) {
$r = max($r, fd_sum($i, $m, $arr, $n));
}
echo $r."\n";
}
$loop++;
}
fclose($fp);
?>
<?php
function fd_sum($i, $m, $arr, $n) {
if($i == 0) {
return $m[$i] = 0;
}
else if($m[$i] != -1) {
return $m[$i];
}
else {
$rr = 0;
for($j = 0; $j < $n; $j++) {
$num = (int)$arr[$j];
$b = save($num);
if(($i | $b) == $i) {
$z = $i^save($num);
$y = fd_sum($z, $m, $arr, $n);
$v = ($y + $num);
$rr = max($v, $rr);
}
}
return $m[$i] = $rr;
}
}
?>
<?php
function save($nm)
{
$x = 0;
for($i = 1; $nm/$i > 0; $i *= 10) {
$d = ($nm/$i) % 10;
$x = $x | (1 << $d);
}
return $x-1;
}
?>
My input is
3
4
3 5 7 2
5
121 3 333 23 4
7
32 42 52 62 72 82 92
My output is
17
458
92
-
-
-
-
The expected output is
17
458
92
-
Note : I have used '-' to indicate a new line
What am i doing wrong? Please help.
The PHP interpreter is reading the new lines after the closing tags and just spitting it right back out as output. Removing the extra opening/closing tags should remove the extra new lines.
Also, php closing tags are not necessary and i recommend omitting them.
<?php
/* Read input from STDIN. Print your output to STDOUT*/
$fp = fopen("php://stdin", "r");
//Write code here
$loop = 0;
$n = 0; $arr = [];
while(!feof($fp)) {
$arr = []; $n = 0;
if($loop == 0) {
$total = fgets($fp);
}
else {
if($loop%2 == 1) {
$n = fgets($fp);
}
else {
$arr = fgets($fp);
}
}
if($loop > 0 && $loop%2 == 0) {
$arr = explode(" ", $arr);
$m = [];
for($i = 0; $i < 1<<10; $i++) {
$m[$i] = -1;
}
$n = count($arr);
$r = 0;
for($i = 0; $i < 1<<10; $i++) {
$r = max($r, fd_sum($i, $m, $arr, $n));
}
echo $r."\n";
}
$loop++;
}
fclose($fp);
function fd_sum($i, $m, $arr, $n) {
if($i == 0) {
return $m[$i] = 0;
}
else if($m[$i] != -1) {
return $m[$i];
}
else {
$rr = 0;
for($j = 0; $j < $n; $j++) {
$num = (int)$arr[$j];
$b = save($num);
if(($i | $b) == $i) {
$z = $i^save($num);
$y = fd_sum($z, $m, $arr, $n);
$v = ($y + $num);
$rr = max($v, $rr);
}
}
return $m[$i] = $rr;
}
}
function save($nm)
{
$x = 0;
for($i = 1; $nm/$i > 0; $i *= 10) {
$d = ($nm/$i) % 10;
$x = $x | (1 << $d);
}
return $x-1;
}

Migration from depricated function create_function

I have function in my script but after updating my php version to 7.3 i receive an notice that function create_function is deprecated. How can i migrate and what can i use instead of create_function?
function rc4($key, $data){
// Store the vectors "S" has calculated
static $SC;
// Function to swaps values of the vector "S"
$swap = create_function('&$v1, &$v2', '
$v1 = $v1 ^ $v2;
$v2 = $v1 ^ $v2;
$v1 = $v1 ^ $v2;
');
$ikey = crc32($key);
if (!isset($SC[$ikey])) {
// Make the vector "S", basead in the key
$S = range(0, 255);
$j = 0;
$n = strlen($key);
for ($i = 0; $i < 255; $i++) {
$char = ord($key{$i % $n});
$j = ($j + $S[$i] + $char) % 256;
$swap($S[$i], $S[$j]);
}
$SC[$ikey] = $S;
} else {
$S = $SC[$ikey];
}
// Crypt/decrypt the data
$n = strlen($data);
$data = str_split($data, 1);
$i = $j = 0;
for ($m = 0; $m < $n; $m++) {
$i = ($i + 1) % 256;
$j = ($j + $S[$i]) % 256;
$swap($S[$i], $S[$j]);
$char = ord($data[$m]);
$char = $S[($S[$i] + $S[$j]) % 256] ^ $char;
$data[$m] = chr($char);
}
return $data; implode('', $data);
}
enter code here

RC4 Decodeing Using PHP

I am trying to decode the rc4 encoded value using follwong function.
function rc4($key, $data){
// Store the vectors "S" has calculated
static $SC;
// Function to swaps values of the vector "S"
$swap = create_function('&$v1, &$v2', '
$v1 = $v1 ^ $v2;
$v2 = $v1 ^ $v2;
$v1 = $v1 ^ $v2;
');
$ikey = crc32($key);
if (!isset($SC[$ikey])) {
// Make the vector "S", basead in the key
$S = range(0, 255);
$j = 0;
$n = strlen($key);
for ($i = 0; $i < 255; $i++) {
$char = ord($key{$i % $n});
$j = ($j + $S[$i] + $char) % 256;
$swap($S[$i], $S[$j]);
}
$SC[$ikey] = $S;
} else {
$S = $SC[$ikey];
}
// Crypt/decrypt the data
$n = strlen($data);
$data = str_split($data, 1);
$i = $j = 0;
for ($m = 0; $m < $n; $m++) {
$i = ($i + 1) % 256;
$j = ($j + $S[$i]) % 256;
$swap($S[$i], $S[$j]);
$char = ord($data[$m]);
$char = $S[($S[$i] + $S[$j]) % 256] ^ $char;
$data[$m] = chr($char);
}
return $data; implode('', $data);
}
If i use this function to decode simple text it works fine, but when i go for bigger key, it gives something like this
Œù©>Ç ¾¾óÅ,ŒŒ£f®ãápXŽ×{
Which i am not getting what it is???
Can you please explain whats wrong with it?
My Key is f033b52440607260e131d4f4a0f55cae and data is: 4522261326835a46d78099e0

Optimize substrings anagram compare algorithm

Im trying to solve one challenge where you have to check all string substrings are they anagrams. The condition is basically For S=abba, anagramic pairs are: {S[1,1],S[4,4]}, {S[1,2],S[3,4]}, {S[2,2],S[3,3]} and {S[1,3],S[2,4]}
Problem is that I have string with 100 chars and execution time should be below 9 secs. My time is around 50 secs... Below is my code, I will appreciate any advice - if you give me only directions or pseudo code it is even better.
$time1 = microtime(true);
$string = 'abdcasdabvdvafsgfdsvafdsafewsrgsdcasfsdfgxccafdsgccafsdgsdcascdsfsdfsdgfadasdgsdfawdascsdsasdasgsdfs';
$arr = [];
$len = strlen($string);
for ($i = 0; $i < strlen($string); $i++) {
if ($i === 0) {
for ($j = 1; $j <= $len - 1; $j++) {
$push = substr($string, $i, $j);
array_push($arr, $push);
}
} else {
for ($j = 1; $j <= $len - $i; $j++) {
$push = substr($string, $i, $j);
array_push($arr, $push);
}
}
}
$br = 0;
$arrLength = count($arr);
foreach ($arr as $key => $val) {
if ($key === count($arr) - 1) {
break;
}
for ($k = $key + 1; $k < $arrLength; $k++) {
if (is_anagram($val, $arr[$k]) === true) {
$br++;
}
}
}
echo $br."</br>";
function is_anagram($a, $b)
{
$result = (count_chars($a, 1) == count_chars($b, 1));
return $result;
}
$time2 = microtime(true);
echo "Script execution time: ".($time2-$time1);
Edit:
Hi again, today I had some time so I tried to optimize but couldnt crack this... This is my new code but I think it got worse. Any advanced suggestions ?
<?php
$string = 'abdcasdabvdvafsgfdsvafdsafewsrgsdcasfsdfgxccafdsgccafsdgsdcascdsfsdfsdgfadasdgsdfawdascsdsasdasgsdfs';
$arr = [];
$len = strlen($string);
for ($i = 0; $i < strlen($string); $i++) {
if ($i === 0) {
for ($j = 1; $j <= $len - 1; $j++) {
$push = substr($string, $i, $j);
array_push($arr, $push);
}
} else {
for ($j = 1; $j <= $len - $i; $j++) {
$push = substr($string, $i, $j);
array_push($arr, $push);
}
}
}
$br = 0;
$arrlen = count ($arr);
foreach ($arr as $key => $val) {
if (($key === $arrlen - 1)) {
break;
}
for ($k = $key + 1; $k < $arrlen; $k++) {
$result = stringsCompare($val,$arr[$k]);
if ($result === true)
{
$br++;
}
}
echo $br."\n";
}
function stringsCompare($a,$b)
{
$lenOne = strlen($a);
$lenTwo = strlen ($b);
if ($lenOne !== $lenTwo)
{
return false;
}
else {
$fail = 0;
if ($lenOne === 1) {
if ($a === $b) {
return true;
}
else
{
return false;
}
}
else
{
for ($x = 0; $x < $lenOne; $x++)
{
$position = strpos($b,$a[$x]);
if($position === false)
{
$fail = 1;
break;
}
else
{
$b[$position] = 0;
$fail = 0;
}
}
if ($fail === 1)
{
return false;
}
else
{
return true;
}
}
}
}
?>
You should think of another rule that all anagrams of a certain string can meet. For example, something about the number of occurrences of each character.

what i use in place of indexOf in php

here's my code so please tell me what i used in place of indexOf usind php because there is no indexOf function in php .
function generate($arrLength)
{
$arr = array();
$n = 0;
$start = 10;
$end = 20;
for($i=0; $i < $arrLength; $i++)
{
do{
$n = $start + round(rand()*($end - $start));
}while($arr.indexOf($n) !== -1);
$arr[$i] = $n;
}
return $arr;
}
$generatedArr = generate(4);
You can use array_search() in this case:
function generate($arrLength) {
$arr = array();
$n = 0;
$start = 10;
$end = 20;
for($i=0; $i < $arrLength; $i++) {
do {
$n = $start + round(rand()*($end - $start));
} while(array_search($n, $arr) !== false);
$arr[$i] = $n;
}
return $arr;
}
$generatedArr = generate(4);
echo '<pre>';
print_r($generatedArr);

Categories