This puzzle takes difficulty (or at least complexity) up a notch in languages without automatic memory management. The aim is to convert a string into unary code (blocks of zeros). First each character must be converted into its binary ascii code, then in unary.
I did not find any standard function useful to convert a character to its binary ascii code, so I wrote my own function to do it. This code is a good example of how to read through strings using pointers arithmetic. It also shows how to return a string using dynamic allocation (malloc) and a pointer
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Converts character 'c' to its binary code on 7 bits
char *toBinCode (char c) {
char *res = malloc(8*sizeof(char));
for (int i = 6; i >= 0; i--) {
res[i] = '0'+(c%2);
c/=2;
}
res[7] = '\0';
return res;
}
int main(int argc, char** argv)
{
// note that fgets keeps the \n at the end of the msg
char msg[100];
fgets(&msg,100,stdin);
char binMsg[700];
/* Iterating over msg and binMsg using pointers iter, binIter
converting each char in their binary code
which is appended at the end of binMsg */
char* iter = msg;
char* binIter = binMsg;
char *code;
while (*iter != '\n') {
code = toBinCode(*iter);
strncpy(binIter, code, 7);
free(code);
iter++;
binIter+=7;
}
*binIter = '\0';
/* prev contains the last character of binMsg read : '0' or '1'
count countains the number of consecutive identical characters */
char prev = '2';
int count = 0;
/* reads binMsg character by character, updating prev, count
and printing the solution gradually*/
for (binIter = binMsg; *binIter != '\0'; binIter++) {
if (*binIter != prev) {
for (int j = 0; j < count; j++)
printf("0");
if (count != 0)
printf(" ");
printf((*binIter == '0') ? "00 " : "0 ");
count = 1;
} else
count++;
prev = *binIter;
}
for (int j = 0 ; j < count ; j++)
printf("0");
return EXIT_SUCCESS;
}
For this puzzle I used Java StringBuilder, which allows to join differents strings without storing a new string in memory at each concatenation
import java.util.*;
import java.math.*;
class Solution {
public static void main(String args[]) {
Scanner in = new Scanner(System.in);
String msg = in.nextLine();
StringBuilder binMsg = new StringBuilder("");
/* Converts the message into its binary code, char by char
(without forgetting 0s in the beginning like toBinaryString does)*/
for (char c : msg.toCharArray()) {
String binChar = Integer.toBinaryString(c);
for (int j = binChar.length(); j < 7 ;j++)
binMsg.append("0");
binMsg.append(binChar);
}
/* prev contains the last character of binMsg read : '0' or '1'
count cointains the number of consecutive identical characters */
char prev = '2';
int count = 0;
/* reads binMsg character by character, updating prev, count
and printing the solution bit by bit*/
for (char c : binMsg.toString().toCharArray()) {
if (c != prev) {
for (int j = 0 ; j < count ; j++)
System.out.print("0");
if (count != 0)
System.out.print(" ");
System.out.print((c == '0') ? "00 " : "0 ");
count = 1;
} else {
count++;
}
prev = c;
}
for (int j = 0 ; j < count ; j++)
System.out.print("0");
}
}
String multiplication in Python as particularly handy for this puzzle where the string "0" is printed a lot. Python's advanced formatting function allows to convert easily a character into its binary ascii code.
msg = input()
binMsg = []
for c in msg:
# converts c to a 7digit 0 left padded binary code
binMsg.append('{0:07b}'.format(ord(c)))
# reunites the list of string into one string and browses it, updating :
# - prev which contains the last character of binMsg read : '0' or '1'
# - count which countains the number of consecutive identical characters
# and printing the result gradually
prev, count = None, 0
for c in ''.join(binMsg):
if c != prev:
print(('0' * count) + \
(' ' if count else '') + \
("00 " if c == '0' else "0 "), end='')
count = 1
else:
count+=1
prev = c
print("0" * count, end="")