Задания 1-й недели курса CS50 (Hello, Mario, Cash, Credit)

4.9 (97.65%) 17 vote[s]

На первой неделе курса CS50 предлагается выполнить 5 оценочных заданий:

  1. Hello!
  2. Mario простой;
  3. Mario сложный;
  4. Credit;
  5. Cash.

В качестве первого задания предлагается написать код, который запрашивает у пользователя имя, а затем выводит в терминале «Hello, … !».

Подготовка для работы и проверки своих кодов

Вначале нужно получить доступ к среде разработки IDE. На курсах рекомендуют установить офлайн-версию докера и CS50 IDE. Но намного проще начать работать в онлайн редакторе CS50 IDE. Чтобы получить к нему доступ, нужно зарегистрироваться либо на на сайте edX, либо на GitHub. Регистрация на CS50 IDE выполняется через один из этих аккаунтов.

При регистрации на GitHub вы получите доступ и к
CS50 Lab, и к облачной среде CS50 Sandbox . В ней можно проверять реализацию своего кода.

Hello!

Это стандартное упражнение, с которого начинается учебный курс с нуля по программированию на любом языке.

Используются оператор get_string из библиотеки CS50.h , получения строчного аргумента, и оператор вывода printf. Форматирование вывода производится при помощи управляющего символа \n, который указывает на переход на строку ниже, и флага форматирования.

#include<cs50.h>; 
#include<stdio.h>; 

       int main(void) 
{ 
       string name = get_string("What is your name?\n"); 
              printf("hello, %s\n", name); 
}

Вот и все. В IDE нужно создать папку pset1, в ней папку hello. В папке hello создаем  файл hello с расширением .c и пишем в нем код.

Чтобы запустить код и проверить, как он работает в IDE, нужно выполнить в терминале такие команды:

      • Чтобы попасть в папку pset1, набираем cd pset1 (не забываем пробел).
      • Затем набираем команду сборки файла make hello.
      • Теперь запускаем код командой ./hello.

В терминале появится запрос ввести имя: What is your name?

Пишем свое имя, жмем ввод, и получаем персональное приветствие!

Mario легкий

В Mario нужно создать переменные, которые будут хранить высоту блоков, количество пробелов и хешей (#). Они будут использоваться для каждой строки.

Затем нужно вывести на экран запрос для пользователя с предложением указать высоту пирамидки. В этом году условиями задачи вводится ограничение — до 8 включительно. Поэтому мы проверяем корректность вводимого числа при помощи цикла do…while. Запрос будет выводиться до тех пор, пока пользователь не введет целое число от 1 до 8.

Дальше реализовывается цикл построения пирамидки for. Первый цикл for устанавливает строки. Так как высота будет определять и количество строк, то мы увеличиваем значение i до тех пор, пока оно не станет равным высоте. Второй цикл for вводит количество пробелов в строке. При этом количество пробелов уменьшается (в каждой новой строке пробел заменяется хешем).

Так мы получаем диагональный стек блоков. Третий цикл for увеличивает хэши, которые будут увеличиваться с каждой строкой. В первом ряду будет один хеш, во втором ряду два хэша и т. д.

#include <cs50.h>
#include <stdio.h>

int main(void)
{
   //Создаем переменные для высоты, пробелов и хэшей
    int height;
    int spaces;
    int hashes;

do
    {
        height = get_int("Height: ");
    }
    //Устанавливаем условия
    while (height < 1 || height > 8);
    //Создаем строки
    for (int i = 1; i <= height; i++)
    {
     //Создаем столбцы пробелов
       for (spaces = (height - i); spaces > 0; spaces--)
        {
            printf(" ");
        }
      //Создаем столбцы хешей
        for (hashes = 1; hashes <= (i); hashes++)
        {
            printf("#");
        }
        printf("\n");
    }
    return 0;
}

Точно так же в папке pset1 создаем папку mario1, в ней создаем пустой файл mario1.c, при помощи команды  make mario1 создаем исполняемый файл, запускаем (./mario) и смотрим, что получилось. При тестировании с вводом некорректных данных (8<i<1), программа будет вести себя таким образом:

$ ./mario
Height: -1
Height: 0 
Height: 42
Height: 50
Height: 4
   #
  ##
 ###
####  

 

Народная мудрость

Mario сложный, с зеркальной пирамидкой

Сложность в том, что нужно рядом с первой пирамидкой из предыдущего задания рядом построить такую же, но зеркально.

 $ ./mario
 Height: 8
        #  #
       ##  ##
      ###  ###
     ####  ####
    #####  #####
   ######  ######
  #######  #######
 ########  ########  

 Обратите внимание на двойной пробел между пирамидками!

#include<cs50.h> 
#include<stdio.h> 

int main(void)
{
    int height;
    int spaces;
    int hashes;
    int hashes2;

    do
    {
        height = get_int("Height: ");
    }

    while (height < 1 || height > 8);

    for (int i = 1; i <= height; i++)
    {

        for (spaces = (height - (i)); spaces > 0; spaces--)
        {
            printf(" ");
        }

        for (hashes = 1; hashes <= i; hashes++)
        {
            printf("#");
        }
        printf("  ");
        for (hashes2 = 1; hashes2 <= i; hashes2++)
        {
            printf("#");
        }
        printf("\n");
    }
    return 0;
}

 

Важно! Обратите внимание, что функция get_int есть в библиотеке CS50. В других IDE, в которых по умолчанию эта библиотека не установлена, эту функцию можно реализовать при помощи scanf.

Cash

Суть задачи — узнать, каким минимальным количеством монет можно дать человеку сдачи. Например, если для оплаты товара сумой 3,42 долл. кассиру дали 4,00 долл. При этом ему нужно дать 2×25, 1×5 и 3×1 центу (учитывая стандартные монеты США: 25, 10, 5, 1 цент). Общее количество монет — 6 шт.

В этом коде вначале нужно создать переменные для всех монет, которые наш кассир отдаст нашему клиенту. Затем создается переменная get_float. Это будет число с плавающей запятой.

Поэтому формат ввода — 0.37, или 0.42, но не 0,420.

Чтобы избежать проблем при работе с числом с плавающей запятой (из-за округления можно потерять пару центов), перед округлением нужно умножать ввод на 100, и затем преобразовывать в целое число.

При этом мы используем % (остаток деления на n). Подсчет монет мы производим в строке вывода printf, указывая формат вывода %d (целое десятичное число).

#include<stdio.h> 
#include<math.h> 
#include<cs50.h> 

int main()
{
    int cents_owed;

    do
    {
        float dollars_owed = get_float("Change owed: ");
        cents_owed = round(dollars_owed * 100);
    }
    while (cents_owed <= 0);

    int quarters = cents_owed / 25;
    int dimes = (cents_owed % 25) / 10;
    int nickels = ((cents_owed % 25) % 10) / 5;
    int pennies = ((cents_owed % 25) % 10) % 5;

    printf("%d\n", quarters + dimes + nickels + pennies);
}

Для краткости и элегантности кода, мы сразу объявляем монеты и проводим операции по вычислению их количества.

Вот как ведет себя программа:

$ ./cash 
Change owed: 0.41
4 

 
$ ./cash 
Change owed: -0.41 
Change owed: foo 
Change owed: 0.41 4 

Credit

Задача по проверке подлинности кредитной карты по ее номеру. Дело в том, что номера на картах ставятся не произвольно. Числовой ряд устанавливается по алгоритму Луна. Он заключается в следующем.

Алгоритм Луна

Умножаем каждое второе число карточки, начиная с предпоследней, на 2. Складываем разряды полученного числа.Например, карта 4003600000000014.

Вычисляем:
 
1•2 + 0•2 + 0•2 + 0•2 + 0•2 + 6•2 + 0•2 + 4•2 

В результате получаем:
 
2 + 0 + 0 + 0 + 0 + 12 + 0 + 8

Сумма разрядов - 2+0+0+0+0+3+8=13

Вычисляем сумму разрядов чисел, которые не умножались на 2:

4 + 0 + 0 + 0 + 0 + 0 + 3 + 0=7

Добавляем 13+7=20

Так вот, если последний разряд равен 0 (или число кратно 10), значит карточка действительная.

Вот такой алгоритм проверки предлагается воплотить в коде. Кроме того, номера карточек разных платежных систем начинаются с определенного диапазона цифр. Так,  Visa — с 4, MasterCard — с 51, 52, 53, 54 или 55. Другие платежные системы можно посмотреть тут.

Разные платежные системы используют разное количество разрядов: American Express — 15,  MasterCard — 16, Visa — 13 или 16. Все эти данные нужно учитывать при написании кода.

Архивировано:

#include 
#include 

int main()
{
    long long i = get_long_long("Number: ");
    int xadd = 0, x2 = 0, addsum = 0, x2prod = 0, sum = 0, digitstwo,  multiple;
	bool valide;

    while (i > 0)
    {
        x2 = xadd;
        xadd = i % 10;

        if (addsum % 2 == 0)
        {
            sum += xadd;
        }
        else
        {
            multiple = 2 * xadd;
            x2prod += (multiple / 10) + (multiple % 10);
        }

        i /= 10;
        addsum++;
    }

    valide = (sum + x2prod) % 10 == 0;
    digitstwo = (xadd * 10) + x2;

    if (xadd == 4 && addsum >= 13 && addsum <= 16 && valide)
    {
        printf("VISA\n");
    }
    else if (digitstwo >= 51 && digitstwo <= 55 && addsum == 16 && valide)
    {
        printf("MASTERCARD\n");
    }
    else if ((digitstwo == 34 || digitstwo == 37) && addsum == 15 && valide)
    {
        printf("AMEX\n");
    }
    else
    {
        printf("INVALID\n");
    }
}

Актуально:

  1. #include <stdio.h>
  2. #include <cs50.h>
  3.  
  4. int main()
  5. {
  6.     long long i = get_long_long("Number: ");
  7.     int xadd = 0, x2 = 0, addsum = 0, x2prod = 0, sum = 0, digitstwo,  multiple;
  8. 	bool valide;
  9.  
  10.     while (i > 0)
  11.     {
  12.         x2 = xadd;
  13.         xadd = i % 10;
  14.  
  15.         if (addsum % 2 == 0)
  16.         {
  17.             sum += xadd;
  18.         }
  19.         else
  20.         {
  21.             multiple = 2 * xadd;
  22.             x2prod += (multiple / 10) + (multiple % 10);
  23.         }
  24.  
  25.         i /= 10;
  26.         addsum++;
  27.     }
  28.  
  29.     valide = (sum + x2prod) % 10 == 0;
  30.     digitstwo = (xadd * 10) + x2;
  31.  
  32.     if (xadd == 4 && addsum >= 13 && addsum <= 16 && valide)
  33.     {
  34.         printf("VISA\n");
  35.     }
  36.     else if (digitstwo >= 51 && digitstwo <= 55 && addsum == 16 && valide)
  37.     {
  38.         printf("MASTERCARD\n");
  39.     }
  40.     else if ((digitstwo == 34 || digitstwo == 37) && addsum == 15 && valide)
  41.     {
  42.         printf("AMEX\n");
  43.     }
  44.     else
  45.     {
  46.         printf("INVALID\n");
  47.     }
  48. }

 Вот как должна себя вести программа:

$ ./credit
Number: 4003600000000014
VISA

А теперь, get_long откидывает самостоятельно дефисы:
$ ./credit Number: 4003-6000-0000-0014 Number: foo Number: 4003600000000014 VISA А если номер "липовый", программа показывает соответствующий вывод: $ ./credit Number: 6176292929 INVALID

Смотрите варианты реализации этих заданий на Python в шестой неделе курсов CS50.

Читайте больше по теме:

Подписаться
Уведомление о
guest
3 комментариев
старее
новее большинство голосов
Inline Feedbacks
View all comments
Алексей
Алексей
18.01.2020 12:14

Здравствуйте, у вас ошибка в решении задания «Mario легкий».
В 26-ой строке: for (hashes = 1; hashes <= (i+1); hashes++) здесь лишний знак равенства или переменная i.
Если прогонять программу с ошибкой то в каждой строке будет 1 лишняя "#".

Просмотры: 7453

Популярные записи