Jump to content

space every 3 characters


smerny

Recommended Posts

  • Replies 52
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

Got bored & played around with it.... a bit shorter.

 

<?php
$num="01101.1011";
function formatBinary($string) {
$a = explode('.',$string);
$count = 0;
foreach($a as $p => $x) {
	$length = strlen($x);
	$mod = $length%3;
	if($mod!=0) {
		if($count==0) 
			$side = STR_PAD_LEFT;
		else
			$side = STR_PAD_RIGHT;

		$x = str_pad($x, $length-$mod+3, '0', $side);
	}
	$a[$p] = wordwrap($x,3,' ',true);
	$count++;
}
return implode(' . ', $a);
}
echo formatBinary($num);

Takes the string, explodes it based off the delimiter (period in this case) then only on the first set does it pad to the left, the rest it pads to the right with 0s, grouping in triplets with a space in between.

 

Here's some example input/outputs:

InputOutput

01101.1011001 101 . 101 100

1101101.10111001 101 101 . 101 110

1101101111001 101 101 111

11.01101.1111011 . 011 010 . 111 100

Link to comment
Share on other sites

whale that flash kingphilp (( love that got board so rewrote it hahahaha))

 

yes i do, it a very clever way off thinking or out skill ing a hacker if i am on the wright lines of thinking?

 

ill get back to kingphilps version after 200 drinks whale

 

(( ill never get to think like a real programmer never to hard))

 

the examples on this page will make me cut my wrist lol

Link to comment
Share on other sites

That's interesting. It's cool to see different takes on the problem.

 

I could make mine shorter, but I added some protection (for example support if there's more than one delimiter), but I noticed that's stupid because there would be other problems with my code if there was one more than one. And if it was just a decimal (as the OP noted) then there would be no need to have more than one.

 

So removing the pointless stuff, and changing it a bit, I came up with this:

 

$str = '1011101.1011';
$split = str_split($str);

$str = str_pad($str, 3 - array_search('.', $split) % 3 + strlen($str), "0", STR_PAD_LEFT);
$str = str_pad($str, 3 - ((count($split) - 1) - array_search('.', $split)) % 3 + strlen($str), "0", STR_PAD_RIGHT);

$split = str_split($str);
for($i = 0;$i < count($split);$i++)
if($split[$i] == '.')
	$split[$i] = ' . ';
else if($i % 4 == 0)
	array_splice($split, $i, 0, ' ');

echo implode($split);

 

@KingPhilip: Thanks, never knew about str_pad :P

 

Edit: Oh I guess it did need support for without a decimal. Oh well, no time to edit it now, going to bed, was fun.

Link to comment
Share on other sites

If you wanted to go even shorter on mine:

function formatBinary($s) {
$p = STR_PAD_LEFT;
foreach(explode('.',$s) as $x) {
	$l = strlen($x);
	$a[] = wordwrap(str_pad($x, $l-($l%3)+3, '0', $p),3,' ',true);
	$p = STR_PAD_RIGHT;
}
return implode(' . ', $a);
}
$num="01101.1011";
echo formatBinary($num);

 

Should still work the same.

Link to comment
Share on other sites

I'll throw my hat into the ring

function padByOct($value)
{
    $parts = explode('.', $value);
    $pre  = str_pad($parts[0], (strlen($parts[0])+((3-strlen($parts[0])%3)%3)), '0', STR_PAD_LEFT);
    $post = str_pad($parts[1], (strlen($parts[1])+((3-strlen($parts[1])%3)%3)), '0', STR_PAD_RIGHT);
    return preg_replace("/(.{3})/", "\1 ", $pre).'.'.preg_replace("/(.{3})/", " \1", $post);
}

$str = '1011101.1011';
echo padByOct($str); //Output: 001 011 101 . 101 100

Link to comment
Share on other sites

seems to be a lot of enthusiasm on this little project lol

 

mj, i don't really understand regex... can you explain that part for me?

 

Speaking for myself, I like problems where you have to think outside the box. And I like the challenge of trying to solve a problem with an elegant, concise solution.

 

I'm no RegEx guru, but I can stumble my way through when I have to. This RegEx is not very complicated though. preg_replace() simply finds text that matches the expression of the first parameter and replaces it with the text in the second parameter (with the third parameter being the text to be operated on). The one part that is a little more "advanced" is the use of a back reference. Let me explain.

 

Here is the RegEx pattern:

"/(.{3})/"

 

The period is a wildcard character that matches any character. The "{3}" states that I want to find three of those, i.e. 3 of any character. So, that will find all groupings of three characters. Then by putting parents around that I create a backreference to the matches. I can then use that backreference in the replacement expression.

 

The backreferences are referenced using "\1" for the first backreference, and \2 for the second, etc. I only had one backreference so, I just use "\1" in my replacement expression which is "\1 ".

 

So basically the full line finds all three character parts and replaces then with their original value plus a space.

Link to comment
Share on other sites

I reverted back to kingphilips latest one, and just put this code previous:

 

	$input = $_POST['input'];
$neg = false;
if(strpos($input, "-") === true)
{
	$input = str_replace("-","",$input);
	$neg = true;
}

 

and added this before the output

 

($neg == true ? "-" : "")

 

but apparently i did something wrong...  it wont remove the "-"

Link to comment
Share on other sites

input: -1.1

output: -001 . 100

 

currently it's giving me: 0-1 . 100

 

but I think I would rather do this outside of your function, just remove the negative sign from $input and instead store it in boolean $neg (basically what i was trying to do in my last post)... it will give me more flexibility for other things i'll want to do

Link to comment
Share on other sites

hey kingphilip, i just made a pretty neat function based off of yours somewhat...

 

			function bin2octal($s)
		{
			$p = STR_PAD_LEFT;
			foreach(explode('.',$s) as $x) 
			{
				$l = strlen($x);
				$a[] = base_convert(str_pad($x, $l-($l%3)+3, '0', $p),2,;
				$p = STR_PAD_RIGHT;
			}
			return implode('.', $a);
		}

 

this function will convert binary numbers into octals, decimal or not... the base_convert function would not work with decimals

Link to comment
Share on other sites

but I think I would rather do this outside of your function, just remove the negative sign from $input and instead store it in boolean $neg (basically what i was trying to do in my last post)... it will give me more flexibility for other things i'll want to do

 

That's what I would do. You could do it with regex, like what mjdamato was going for, but just removing it & storing a temp var is fine too.

 

function formatBinary($s) {
$p = STR_PAD_LEFT;
if(strpos($s,'-')!==false) {
	$s = str_replace('-','',$s);
	$n = true;
}
foreach(explode('.',$s) as $x) {
	$l = strlen($x);
	$a[] = wordwrap(str_pad($x, $l-($l%3)+3, '0', $p),3,' ',true);
	$p = STR_PAD_RIGHT;
}
if(isset($n))
	return '- '.implode(' . ', $a);
return implode(' . ', $a);	
}
$num="-11101.1011";
echo formatBinary($num);

 

I do realize that the math in str_pad ($l-($l%3)+3) will cause the correct numbers to be padded (e.g. 111 would become 000 111.) If you're concerned about that, just do a quick check to see if the modulus is 0 or not.

Link to comment
Share on other sites

thanks, if anyone cares to see what i did exactly, check it out here.

 

note that i only did the binary => octal conversion so far...  here is sample output:

-10111.11011two
-010 111 . 110 110 (Group in threes)
-  2    7    .    6    6 (Convert the groups to octal)
-27.66eight

 

does anyone know of a good way to line up the binary octals in line 2 with the octals in line 3? i played around with spacing but it's not very accurate especially when there gets to be more numbers..

Link to comment
Share on other sites

I do realize that the math in str_pad ($l-($l%3)+3) will cause the correct numbers to be padded (e.g. 111 would become 000 111.) If you're concerned about that, just do a quick check to see if the modulus is 0 or not.

 

I had the same problem and discovered a solution - using modulus twice!.

 

str_pad($l + (3-($l%3)%3))

 

Link to comment
Share on other sites

function formatBinary($s) {
$p = STR_PAD_LEFT;
if(strpos($s,'-')!==false) {
	$s = str_replace('-','',$s);
	$n = true;
}
foreach(explode('.',$s) as $x) {
	$l = strlen($x);
	$a[] = wordwrap(str_pad($x, $l + (3-($l%3))%3, '0', $p),3,' ',true);
	$p = STR_PAD_RIGHT;
}
if(isset($n))
	return '- '.implode(' . ', $a);
return implode(' . ', $a);	
}
$num="-1111101.1011";
echo formatBinary($num);

Works fine for me

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.