Кодировка - пазл Чака Норриса в C - PullRequest
0 голосов
/ 11 апреля 2020

Я учусь C и, чтобы сделать его более интересным, я использую Codingame: веб-сайт, где вы должны решать задачи с помощью кода. Есть такая головоломка, которая называется «Чак Норрис», где вы получаете массив символов и вам необходимо выдать определенный результат, используя одну функцию printf (). Например, символ 'C' представлен как 1000011 в двоичном виде. 1 представлен одним '0', за которым следует пробел и число 0, соответствующее числу 1. Итак:
1 -> 0 0 11 ->0 00 111 ->0 000
Если двоичный файл равен 0, он будет работать так же, но будет быть представленным двойным 0.
0 -> 00 0 00 -> 00 00 000 ->00 000
Таким образом, для символа C (1000011) результат будет "0 0 00 0000 0 00".

  • ввод состоит из символов ASCII (7-разрядных).
  • Если вы получили строку, вам не нужно добавлять пробелы между конечным 0 и первым нулем второго символа. Так что «CC» будет «0 0 00 0000 0 000 0 00 0000 0 00».
  • '/ n' не рассматривается.

Итак, я решил это но, похоже, я не очень хорошо это сделал: код отнимает слишком много времени, а веб-сайт говорит, что я мог бы его жестко закодировать. Ниже вы найдете мой мыслительный процесс и мой код.

Мыслительный процесс

Чтобы преобразовать строку в двоичный файл, мне понадобится цикл, который проходит по каждому символу и делит значение int 2 проверяя напоминание. После этого я должен сохранить его в массиве, в 7 раз превышающем strlen указанной строки. Теперь у меня есть массив со всеми символами, которые хранятся в двоичном виде: мне просто нужно go через массив в обратном порядке и посчитать количество 0 или 1 с в строке. Если a имеет n 0 в строке, мне просто нужно объединить переменную, добавив «00», «0» n раз и пробел. То же самое для 1с подряд. Итак, вот мой код:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/**
 * Auto-generated code below aims at helping you parse
 * the standard input according to the problem statement.
**/

 int main()
{
    char MESSAGE[101], bits[strlen(MESSAGE)*7]; // Message is the variable in input given by the 
website. Bits is my variable to store message in binary.

fgets(MESSAGE, 101, stdin);
char *pointer = MESSAGE; 
char result[256] = "";                  // variable used to store the result

int i=0;
int count = 0;
int numberc, countz, countone; /* numberc servers to represent the number of characters in the 
string(Excluded /n). countz counts the number of 0s in a row and countone counts the number of 1s in 
a row */

countz = 0;
countone = 0;
numberc = strlen(MESSAGE) - 1 ; 

for(i=0; i<=strlen(MESSAGE); i++) 
{
    bits[i] =0;
}

while(*pointer != '\n'){                    //cycle that goes through every char of the string until it encounters '\n'
    int temp=*pointer; 

    for(int j=0; j<7; j++){             // cycle the selected char into binary and stores it in the var 'bits'
        if(temp % 2 == 1)
          bits[count] = '1'; 
        else
          bits[count] = '0';
        temp = temp/2; 
        count++;
    }
    pointer++;

}
numberc = numberc * 7;

for(int j=numberc-1; j>=0; j--){        // cycle that goes through all the bits stored in reverse  
    if(bits[j] == '0'){ 
        countz++;                                   // counting zeros in a row
        if(countone != 0){                  // concatenating the string in case the previous bits were 1s in a row and the current one is 0
            strcat(result, "0 "); 
            for(i=0; i<countone; i++){
                strcat(result, "0");
                if (i == (countone -1)) strcat(result, " ");                //adding the space after concatenation
            }
            countone = 0;
        }
    }

    else if(bits[j] == '1'){
        countone++;                                  // counting ones in a row
        if(countz != 0){                         // concatenating the string in case the previous bits were 0s in a row and the current one is 1
            strcat(result, "00 ");
            for(i=0; i<countz; i++){
                strcat(result, "0");
                if (i == (countz -1)) strcat(result, " ");                  //adding the space after concatenation
            }
            countz = 0;
        }
    }
    // since the cycle above does not take into account the last row of 1s or 0s, i just repeat the process once again checking the counters and avoiding adding a space at the end.
}
 if(countone != 0){
            strcat(result, "0 ");
            for(i=0; i<countone; i++){
                strcat(result, "0");
                if (i == (countone -1)) strcat(result, " ");
            }
            countone = 0;
        }
if(countz != 0){
            strcat(result, "00 ");
            for(i=0; i<countz; i++){
                strcat(result, "0");
                if (i == (countz -1)) strcat(result, " ");
            }
        countz = 0;
}

printf("%s", result);

return 0;

}

Итак, мой вопрос: что я могу сделать лучше? Как я могу упростить мой код? Есть ли какая-то функция, которую я не знаю, которая может помочь мне в этом случае? Я признал, что часть моего кода плохая. Например:

  • объявление результата var неверно, так как я дал фиксированное число массивов символов. Хотя я и думал об этом, я не знаю, как программно дать измерение массива, которое имеет смысл.
  • Часть кода избыточна.
  • Управление памятью отсутствует (у меня есть пока не изучал)

Код отлично работает с одним или двумя символами ASCII, но когда я ставлю 3+ или пробел, он начинает выдавать странные выходные данные.

Извините для длинного поста я пытался объяснить себя как можно более четко. Кроме того, пожалуйста, будьте терпеливы, поскольку я новичок ie до C, а английский sh не мой родной язык.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...