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="")