Print binary in only 0(zeros)

what if i want to print binary with only 0 ?

for example;

String "C" should output 1000011 in binary.
Well i want to output this 1000011 binary in only zeros ; 0 0 00 0000 0 00

0 0 (the first series consists of only a single 1), 00 0000 (the second series consists of four 0), 0 00 (the third consists of two 1).

Two consecutive blocks are used to produce a series of same value bits (only 1 or 0 values):

  • First block: it is always 0 or 00. If it is 0, then the series contains 1, if not, it contains 0
  • Second block: the number of 0 in this block is the number of bits in the series

It's a strange encoding, but I'd also point out that it's not only zeros, but also significant spaces.

1 Like

Any rust documentation to help me do this ?

You can use the {:b} formatting string to convert numbers to binary strings. For example, format!("{:b}", 'C' as u32) returns "1000011".

Then it should be a simple matter of looping over the chars or bytes of the string, looking for sequences of 0s and 1s, and printing the appropriate number of 0s and spaces for each sequence.

1 Like

I did this one for the output to be in binary ;

message.as_bytes().iter().for_each(|b|  print!("{:b}", b));

with format! doesn't print nothing, with println! it does ;

println!("{:b}", 'C' as u32);

That is correct. format!() will format the input as a string in memory, while print!() (and it's bigger brother, println!()) will perform the formatting and then print it out.

2 Likes

But when we want the binary from a string ;

let mut type = String::new();
let _errtype = io::stdin().read_line(&mut type).unwrap();
let take = type.trim_end().to_string(); 

How can we do that ? is there any method for strings ?

You can use the parse method:

let val: i32 = take.parse::<i32>().unwrap();
1 Like

this output a panic ...

It will help a lot if you provide very specific questions about what parts of the code you are having problems understanding, including exact copies of any error messages you are asking about. Also, please read through the Rust book and the str documentation to learn the basics of programming and string handling in Rust.

It sounds like you want to treat a string as a series of bytes, and encode each byte in your special binary notation. From your previous comment, you know how to loop over each byte of a string. If you want to print each byte in your encoding, then you just need a function that takes a single byte and encodes it:

fn encode(byte: u8) -> String {
    // ...
}

for byte in message.bytes() {
    let encoded = encode(byte);
    println!("{}", encoded);
}

To write the encode function, see my first comment. Begin by using format! to convert the byte to a binary string, then loop through that string looking for runs of zeros or ones. You'll need to keep track of how much of the string you have already encoded, and stop when you reach the end:

fn encode(byte: u8) -> String {
    // Convert the number into a binary string.
    let binary = format!("{:b}", byte).into_bytes();
    
    let mut result = String::new();
    let mut start = 0;
    
    while start < binary.len() {
        // Check if the next byte is b'0' or b'1'.
        let b = binary[start];
        result.push_str(if b == b'1' { "0 " } else { "00 " });
        
        // See how many bytes in a row are the same.
        let count = binary[start..].iter().take_while(|x| **x == b).count();
        result.push_str(&"0".repeat(count));
        result.push(' ');
        
        // Next time, skip all the bytes we've already encoded.
        start += count;
    }
    result
}

There are also more efficient ways to do this using bitwise operators instead of converting to a string, but this way is a little simpler to explain and probably fast enough for most purposes.

3 Likes

Using https://docs.rs/itertools

fn encode (bytes: &'_ [u8])
  -> String
{
    use ::itertools::Itertools;
    bytes
        .iter()
        .map(|&byte| {
            (0 .. 8)
                .rev()
                .map(|shift| (byte & (1 << shift)) != 0)
                .group_by(|&it| it)
                .into_iter()
                .map(|(is_one, bits)| format!(
                    "{id} {:0^count$}", "",
                    id = if is_one { "0" } else { "00" },
                    count = bits.count(),
                ))
                .join(" ")
        })
        .join(" | ")
}
2 Likes
use std::io;

macro_rules! parse_input {
    ($x:expr, $t:ident) => ($x.trim().parse::<$t>().unwrap())
}


 fn encode (bytes: &'_ [u8])
  -> String
{
    use ::itertools::Itertools;
    bytes
        .iter()
        .map(|&byte| {
            (0 .. 7)
                .rev()
                .map(|shift| (byte & (1 << shift)) != 0)
                .group_by(|&it| it)
                .into_iter()
                .map(|(is_one, bits)| format!(
                    "{id} {:0^count$}", "",
                    id = if is_one { "0" } else { "00" },
                    count = bits.count(),
                ))
                .join(" ")
        })
        .join(" ")
}

fn main() {
    let mut input_line = String::new();
    let a = io::stdin().read_line(&mut input_line).unwrap();
    let message = input_line.trim_end().to_string();
    
    //dbg!(encode(b"C"));
    println!("{}", encode(message))
}

Compiler Error;

error[E0308]: mismatched types
  --> /tmp/Answer.rs:39:27
   |
39 |     println!("{}", encode(message))
   |                           ^^^^^^^ expected &[u8], found struct `std::string::String`
   |
   = note: expected type `&[u8]`
              found type `std::string::String`

You can use message.as_bytes() to convert from String to &[u8], as you did earlier.

2 Likes

Oh i tried with to_bytes() earlier, but as_bytes() works great, Ok Solved by @mbrubeck @Yandros
Thank you guys! And rust is the future ! I am having some hard times learning rust as my first programming language,but nothing is impossible and i want to much to learn this language! Thank you all for your responses :smiley:

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.