Bulbs
Começando
Abra o VS Code.
Comece clicando dentro da janela do seu terminal e execute cd
sozinho. Você deve encontrar que seu "prompt" se parece
com o abaixo.
$
Clique dentro da janela do terminal e execute
wget https://cdn.cs50.net/2022/fall/psets/2/bulbs.zip
seguido de Enter para baixar um arquivo ZIP chamado bulbs.zip
em seu espaço de código. Tenha cuidado para
não ignorar o espaço entre o wget
e a URL a seguir, ou
qualquer outro caractere!
Agora execute
unzip bulbs.zip
para criar uma pasta chamada bulbs
. Você não
precisa mais do arquivo ZIP, então pode executar
rm bulbs.zip
e responda com "y" seguido por Enter no prompt para remover o arquivo ZIP que você baixou.
Agora digite
cd bulbs
seguido de Enter para mover-se para o diretório (ou seja, abrir) esse diretório. Seu prompt agora deve se parecer com o abaixo.
bulbs/ $
Se tudo ocorreu bem, você deve executar
ls
e ver um arquivo chamado bulbs.c
. Executar code bulbs.c
deve abrir o arquivo onde você digitará o
seu
código para este problema. Se não, refaça seus passos e veja se consegue determinar onde errou!
Detalhes de Implementação
Para escrever nosso programa, primeiro precisamos pensar em bases.
Os Fundamentos
O mais simples base é a base-1, ou unária; para escrever um número, N, em base-1,
simplesmente escreveríamos N consecutivas 1
s.
Assim, o número 4
em base-1 seria escrito como 1111
, e o número 12
como 111111111111
. Pense em contar nos dedos ou em marcar pontos
em um quadro.
Você pode ver por que a base-1 não é muito usada hoje em dia. (Os números ficam muito longos!) Em vez disso, uma convenção comum é a base-10, ou decimal. Na base-10, cada dígito é multiplicado por alguma potência de 10, a fim de representar números maiores. Por exemplo, 123 é uma forma curta de escrever 123 = 1 ⋅ 10^2 + 2 ⋅ 10^1 + 3 ⋅ 10^0.
Mudar a base é tão simples quanto mudar o 10 acima para um número diferente. Por exemplo, se você escreveu
123
na base-4, o número que você realmente estaria
escrevendo é 123 = 1 ⋅ 4^2 + 2 ⋅ 4^1 + 3 ⋅ 4^0, que é igual ao número decimal 27.
Computadores, no entanto, usam a base-2, ou binária. Em binário, escrever 123
seria um erro, uma vez que números binários só podem ter
0
s e 1
s. Mas o processo de descobrir exatamente que número
decimal um número binário representa é exatamente o mesmo. Por exemplo, o número 10101
na base-2 representa 1 ⋅ 2^4 + 0 ⋅ 2^3 + 1
⋅ 2^2 + 0 ⋅ 2^1 + 1 ⋅ 2^0, que é igual ao número decimal 21.
Codificando uma mensagem
Lâmpadas podem estar apenas ligadas ou desligadas. Em outras palavras, lâmpadas representam dois estados possíveis; ou a lâmpada está ligada, ou a lâmpada está desligada, assim como números binários são 1 ou 0. Teremos que encontrar uma maneira de codificar texto como uma sequência de números binários.
Vamos escrever um programa chamado bulbs
que recebe uma mensagem e a converte em um conjunto de lâmpadas que poderíamos mostrar a uma plateia desprevenida. Faremos isso em duas etapas:
- A primeira etapa consiste em transformar o texto em números decimais. Digamos que queremos codificar a mensagem
HI!
. Felizmente, já temos uma convenção em vigor para fazer isso, ASCII. Observe queH
é representado pelo número decimal79
,I
é representado por73
, e!
é representado por33
. - A próxima etapa envolve pegar nossos números decimais (como
79
,73
e33
) e convertê-los em números binários equivalentes, que usam apenas 0s e 1s. Para ter um número consistente de bits em cada um dos nossos números binários, vamos assumir que cada decimal é representado com 8 bits.79
é01001111
,73
é01001001
, e33
é00100001
.
Por último, interpretaremos esses números binários como instruções para as lâmpadas no palco; 0 é desligado e 1 é ligado. (Você verá que o arquivo bulbs.c
inclui uma função print_bulb
que foi implementada para você, que recebe um 0
ou 1
e produz emojis representando lâmpadas.)
Aqui está um exemplo de como o programa concluído pode funcionar. Ao contrário do palco Sanders, imprimiremos um byte por linha para maior clareza.
# ./bulbs
Message: HI!
⚫🟡⚫⚫🟡⚫⚫⚫
⚫🟡⚫⚫🟡⚫⚫🟡
⚫⚫🟡⚫⚫⚫⚫🟡
Para verificar nosso trabalho, podemos ler uma lâmpada que está acesa (🟡) como um 1
e uma lâmpada que está apagada (⚫) como um 0
. Então HI!
tornou-se
01001000
01001001
00100001
que é exatamente o que esperamos.
Outro exemplo:
# ./bulbs
Message: HI MOM
⚫🟡⚫⚫🟡⚫⚫⚫
⚫🟡⚫⚫🟡⚫⚫🟡
⚫⚫🟡⚫⚫⚫⚫⚫
⚫🟡⚫⚫🟡🟡⚫🟡
⚫🟡⚫⚫🟡🟡🟡🟡
⚫🟡⚫⚫🟡🟡⚫🟡
Observe que todos os caracteres estão incluídos nas instruções da lâmpada, incluindo caracteres não alfabéticos como espaços (00100000
).
Especificação
Projete e implemente um programa, bulbs
, que converte texto em instruções para a faixa de lâmpadas no palco do CS50 da seguinte maneira:
- Implemente seu programa em um arquivo chamado
bulbs.c
. - Seu programa deve primeiro solicitar ao usuário uma mensagem usando
get_string
. - Seu programa deve, em seguida, converter a
string
dada em uma série de números binários de 8 bits, um para cada caractere da string. - Você pode usar a função
print_bulb
fornecida para imprimir uma série de0
s e1
s como uma série de emojis amarelos e pretos, que representam lâmpadas acesas e apagadas. - Cada "byte" de 8 símbolos deve ser impresso em sua própria linha ao ser exibido; deve haver um
\n
após o último "byte" de 8 símbolos também.
Dicas para Decimal-to-Binary
Vamos caminhar através de um exemplo com o número 4. Como você converteria 4 em binário? Comece considerando o bit mais à direita, que - se estiver ligado - adiciona 1 ao número que estamos representando. Você precisa que esse bit esteja ligado? Divida 4 por 2 para descobrir:
4 / 2 = 22 divide-se uniformemente em 4, o que nos diz que não há nenhum resto de 1 com o qual se preocupar. Podemos deixar com segurança este bit à direita de fora, então:
0
E quanto ao bit precedente, agora, o que está exatamente à esquerda deste bit que descobrimos? Para verificar, vamos seguir um processo semelhante, mas pegar onde paramos. No passo anterior, dividimos 4 por 2 e obtivemos 2. Agora, 2 divide-se uniformemente em 2? Sim, então não há nenhum resto de 2 com o qual se preocupar:
00
Vamos continuar ainda mais. Depois de dividir 2 por 2, sobra 1. Dividir 1 por 2 deixa um resto de 1. Isso significa que precisaremos ativar este bit:
100
E agora que dividimos nosso número até 0, não precisamos de mais bits para representá-lo. Note que descobrimos os bits para representar 4 na ordem oposta à qual precisamos imprimi-los: provavelmente precisaremos de uma estrutura que nos permita armazenar esses bits, para que possamos imprimi-los para a frente mais tarde. E, claro, em seu código real, você estará trabalhando com char
s de 8 bits, então você vai querer adicionar quaisquer 0's necessários antecipadamente.
Ao verificar restos, o operador de módulo (%
) pode ser útil! 4 % 2
, por exemplo, retorna 0, o que significa que 2 se divide uniformemente em 4 sem nenhum resto.
Como Testar o Seu Código
Seu programa deve se comportar conforme os exemplos acima. Você pode verificar seu código usando o check50
, um programa que o CS50 usará para testar seu código quando você enviar, digitando o seguinte no prompt $
. Mas certifique-se de testá-lo por conta própria também!
check50 cs50/problems/2023/x/bulbs
Para avaliar o estilo do seu código, digite o seguinte no prompt $
.
style50 bulbs.c
Como Enviar
No seu terminal, execute abaixo para enviar seu trabalho.
submit50 cs50/problems/2023/x/bulbs