Masha
41 уровень

Гарвард CS50: задания первой недели (лекции 3 и 4)

Пост из группы Архив info.javarush.ru
3681 участников
CS50 задания Друзья, основные теоретические сведения вы можете почерпнуть из конспекта семинаров. Там, помимо основ С рассказано, как подключиться к специальной облачной IDE CS50 (это нужно сделать для выполнения и проверки заданий), описаны основные нужные команды Linux и структуры языка. Если вам будет недостаточно материала о C, изложенного в лекции и конспекте, обратитесь к другим источникам. Например, к тем, что указаны в конце данной статьи.
В топике "Дополнительные материалы"
  • Цели первой недели
  • IDE CS50
  • Командная строка и обновление рабочей среды
  • Работа в IDE
  • Hello, C!
  • Баги?
  • Проверка на правильность: тест check50
  • Основы С: сравнение со Scratch
  • Основные типы данных в C
  • Библиотеки С
  • И снова Hello C: разбор синтаксиса простейших программ
  • Еще немного о вводе/выводе в C
Материалы в этом топике:
Ввод данных с проверкой: специальные функции библиотеки cs50.h
Для более удобного прохождения этого курса, мы разработали специальную библиотеку CS50, в которой, в частности, есть очень полезные функции обработки введенных пользователем данных. GetString() считывает введенную пользователем строку GetInt() считывает введенную пользователем строку и проверяет, не записано ли в ней целое число GetFloat()считывает введенную пользователем строку и проверяет, не записано ли в ней число с плавающей точкой GetLongLong() считывает введенную пользователем строку и проверяет, не записано ли в ней длинное вещественное число.
Задание 1. Умный подсчет расхода воды
Логично: чем дольше вы принимаете душ, тем больше воды уходит на этот процесс. Давайте прикинем, сколько? Даже если ваш душ едва открыт, в минуту из него вытекает примерно 6 литров воды. А это 12 бутылочек воды, которые вы носите с собой для питья. Обычно человек принимает душ минут 10. Итого, чтобы помыться, нужно 120 полулитровых бутылок. Немало! Создайте файл water.c в вашей директории ~/workspace/pset1. Программа должна подсчитывать сколько бутылочек воды уходит на душ зависимости от времени. То есть:
  1. Программа запрашивает у пользователя количество минут, проведенных в душе
  2. Пользователь вводит положительное целое число
  3. Программа выводит на экран количество бутылочек, израсходованных пользователем.
username:~/workspace/pset1 $ ./water minutes: 10 bottles: 120 Для простоты в этот раз мы будем считать, что пользователь всегда вводит число минут верно, то есть, мы не проверяем, было ли введено положительное и целое число. Позднее мы научимся писать проверки, но пока достаточно и этого. Чтобы проверить правильность выполнения программы с помощью check50, нужно ввести следующую строку в терминале: check50 2015.fall.pset1.water water.c А если вы хотите посмотреть, как работает программа water, написанная сотрудниками курса выполните следующую команду: ~cs50/pset1/water
Задание 2. С нами Марио!
Знаете ли вы самого знаменитого водопроводчика в мире? С легкой руки компании Nintendo вымышленный усатый и немного полноватый дядечка в красной кепке стал героем для нескольких поколений геймеров. Если вы не знаете, о ком речь, вот вам ссылка на классическую игру 1985 года: поверьте, она всё ещё хороша и заслуживает внимания! Также можно найти вариант классического Super Mario для смартфонов или оффлайновых эмуляторов. Всё это нам нужно для общего развития, это еще, к сожалению, не задание;). А задание состоит вот в чем. В конце первого уровня Mario каждый игрок видел вот такую полупирамидку: Создайте файл mario.c в вашей директории ~/workspace/pset1. Наша рограммка будет рисовать полупирамиду, подобную той, что вы видите, но прямо в консоли, без графики: каждый из блоков будет состоять из значка хэша (#). Даже если вы еще не сообразили, как это сделать, поверьте: это просто. Чтобы сделать задачу более интересной, добавим в неё возможность задавать высоту полупирамидки с помощью неотрицательного целого числа от 0 до 23. Высота пирамидки на картинке считается в самом высоком месте, то есть равна 8. Если пользователь неправильно вводит число, нужно попросить его сделать это ещё раз. Затем сгенерировать (с помощью printf пирамидку. Озаботьтесь тем, чтобы выровнять нижний левый угол вашей полупирамиды по левому краю окна терминала, как в примере ниже. Подчеркнутый текст — это то, что пользователь вводит самостоятельно. username:~/workspace/pset1 $ ./mario height: 8 ## ### #### ##### ###### ####### ######## ######### Обратите внимание, что два крайних правых столбца имеют одинаковую высоту. Генерировать трубы, облака и самого Марио пока не стоит=). По крайней мере для этого задания. Если пользователь ввел неправильные данные (ввел не число, или число, которое меньше единицы или больше, чем 23), программа должна снова попросить его ввести данные, как в примере внизу, где подчеркнутый текст — то, что вводил пользователь с клавиатуры. Для считывания введенной строки используйте GetInt. Она может помочь проверить неправильный ввод, но не для всех случаев. username:~/workspace/pset1 $ ./mario Height: -2 Height: -1 Height: foo Retry: bar Retry: 1 ## Чтобы скомпилировать программу, введите строку в терминале: make mario или более прозрачный, но длинный вариант: clang -o mario mario.c -lcs50 после этого запустите программу на исполнение: ./mario Если вы хотите проверить правильность выполнения программы, запускайте check50: check50 2015.fall.pset1.mario mario.c А если вы хотите поиграться с версией mario, созданной ассистентами курса, mario набирайте следующую строку: ~cs50/pset1/mario
Задание 3. Время получать сдачу
В наших широтах мы такого не встречали, а в США, похоже, есть такая вот игрушка, изображенная на фото: цилиндры предназначены для монет разного диаметра (и номиналов), выдает их пружинный механизм, а сам агрегат можно закрепить на поясе ребенка-кассира. Однако что будет, если кто-то рассчитается с кассиром крупной купюрой? Представьте, сколько мороки будет с тем, чтобы посчитать монетки на сдачу. Для минимизации количества выдаваемых монет можно использовать так называемые «жадные» алгоритмы. Они, согласно определению Национального Института Стандартов и Технологии (NIST) всегда находят оптимальное решение на каждом шаге решения задачи, допуская, что конечное решение (полученное из совокупности таких шагов) также будет оптимальным. Что это значит? Представим, что кассир должен покупателю сдачу в 41 цент, а у него на поясе есть цилиндры с монетками для сдачи номиналом в 25, 10, 5 и 1 цент. Руководствующийся «жадным» алгоритмом кассир сразу же захочет выдать максимум, на первом же шаге. На этом шаге оптимальным или наилучшим решением будет выдать 25 пенсов. 41-25 = 16. Осталось выдать 16 пенсов. Очевидно, 25 пенсов слишком много, значит, остается 10. 16-10 = 6. Теперь выдаем по тому же принципу 5 пенсов, и затем — 1. Таким образом, покупатель получит всего четыре монеты номиналом 25, 10, 5 и 1 пенс. Оказывается, «жадная» пошаговая инструкция выдачи денег оптимальна не только для этого случая, но также для номиналов валюты США (и Евросоюза тоже). То есть, если у кассира достаточно монет любого номинала, алгоритм будет работать лучшим образом, то есть, выдаст минимальное количество монет из всех возможных случаев. Итак, какое минимальное количество монеток нам нужно, чтобы дать сдачу? Это и есть наша третья задачка. Создайте файл greedy.c в своей директории ~/workspace/pset1. Дано: монетки номиналом 25, 10, 5, 1 цент Программа должна:
  1. Спросить пользователя, сколько сдачи нужно выдать
  2. Посчитать минимальное количество монет, с помощью которых можно это сделать
Примечание: для ввода будем пользоваться функцией GetFloat из библиотеки CS50 и printf из стандартной библиотеки ввода/вывода для вывода. Кроме того, программа должна проверять корректность ввода. Мы попросили вас использовать GetFloat, чтобы пользователь мог вводить значение в долларах и центах через точку. Например, если мы должны $9.75, пользователь должен ввести 9.75, но не $9.75 или 975. Вы должны проследить, чтобы пользователь ввел число, которое имеет смысл. Скажем, неотрицательное, в этом функция GetFloat сама по себе не поможет. Если пользователь сделал неправильный ввод, нужно просить его повторить его и выполнять программу только с корректными данными. Остерегайтесь неточностей, свойственных числам с плавающей точкой. Например, 0.01 не может быть представлено непосредственно как float. Попробуйте использовать форматированный вывод, например, с 50 знаками после запятой, используя указанный ниже код: float f = 0.01; printf("%.50f\n", f); Кстати, перед тем, как что-либо считать, будет логично перевести всю сумму в центы, (и заодно преобразовать её из float в int), что поможет избежать массы ошибок и сложностей. Чтобы наш автоматический анализатор кода мог правильно проверить вашу задачу, убедитесь, что последняя строка вывода вашей программы не содержит никакой другой информации, кроме минимального количества монеток: целое число с символом \n после него (те, кто учится на JavaRush, прекрасно знают, о чём мы здесь говорим =)). Ниже — пример, как должен выглядеть результат работы вашей программы. username:~/workspace/pset1 $ ./greedy O hai! How much change is owed? 0.41 4 Учитывая особенность чисел с плавающей точкой, можно игнорировать нуль и вводить такое число в форме .41. Конечно, пользователи, которые захотят проверить программу на возможность ввода некорректных данных по полной, должны увидеть что-то вроде: username:~/workspace/pset1 $ ./greedy O hai! How much change is owed? -0.41 How much change is owed? -0.41 How much change is owed? foo Retry: 0.41 4 Исходя из этих требований и примера, который вы увидели выше, ваш код, скорее всего, должен содержать какой-то цикл. Если во время тестирования приложения вы поймете, что цикл не останавливается, вы можете прервать выполнение программы комбинацией ctrl-c (иногда — многократной). Как компилировать и выполнять программу вы уже знаете. Если вы хотите проверить правильность работы вашей программы, с помощью утилиты check50, в терминале введите следующую строку: check50 2015.fall.pset1.greedy greedy.c А если вам захочется поиграть с этой программой, выполненной ассистентами курса, пропишите следующую команду: ~cs50/pset1/greedy
Как подтвердить правильность кода и получить оценки
Вариант 1 Если вам важно проверить именно правильность кода, а не получить итоговую оценку, вы можете его проверять и исправлять с помощью команды check50 2015.fall.pset1.name name.c введенной в терминальной строке CS50 IDE. Где name — название файла вашей задачи. Вариант 2 Если же вы хотите получить оценки (по сути, тот же запуск check50, но с запоминанием результата и заполнением некоторых форм на английском, тогда проделайте следующие шаги: Шаг 1 из 2
  1. Когда приложения готовы, залогиньтесь в CS50 IDE.
  2. В левом верхнем углу CS50 IDE в пределах его файлового браузера, а не терминального окна, кликните левой клавишей мыши с удержанием ctrl или правой клавишей мыши по вашему файлу hello.c (тому, который лежит в директории pset1 ) и нажмите Download. Вы должны обнаружить, что браузер загрузил hello.c.
  3. Повторите для water.c.
  4. Повторите для mario.c.
  5. Повторите для greedy.c.
  6. В отдельной вкладке или окне залогиньтесь в CS50 Submit.
  7. Нажмите Submit в левом нижнем углу окна.
  8. Под Problem Set 1 на появившемся окне нажмите на Upload New Submission.
  9. На появившемся окне жмите Add files…. Должно появиться окно с именем Open Files.
  10. Пройдите путь к месту, куда загружен hello.c. Обычно он находится в папке Downloads или в той папке, которая назначена у вас по умолчанию для загрузки. Найдя hello.c, нажмите на него один раз чтобы отметить, затем нажмите Open.
  11. Кликните Add files… снова, и окно Open Files снова появится.
  12. Теперь найдите таким же образом файл water.c. Кликните по нему, затем кликните Open (или «Открыть»).
  13. Теперь находите mario.c. И тоже кликайте и открывайте таким же образом.
  14. Все то же самое с файлом greedy.c.
  15. Нажмите Start upload чтобы начать загрузку ваших файлов на серверы CS50.
  16. На появившемся экране вы увидите окно с надписью No File Selected. Если вы переместите курсор мыши в левую часть окра, вы увидите список файлов, которые вы загрузили. Нажмите на каждый, чтобы подтвердить содержание каждого из них. (Нет необходимости нажимать на другие кнопки или иконки). Если уверены, что готовы отослать файл на проверку, считайте, вы все сделали! Если хотите проверить свой код самостоятельно ещё раз или исправить что-либо, возвращайтесь в CS50 Submit и повторите эти шаги. Вы можете повторно отправить столько раз, сколько вы хотите; оцениваться будет только самое последнее представление.
Шаг 2 из 2 (он не обязателен для оценки, если что=)) Теперь перейдите по ссылке http://cs50.edx.org/2016/psets/1/ где вы обнаружите специальные формы. В них нужно ответить на несколько теоретических вопросов, и затем нажать Submit под ними. Вопросы со звездочками – обязательны:
  • Alright, should've seen this one coming! In just a few sentences, what's a library? * (Кратко опишите, что такое библиотека)
  • In just a few sentences, what role does #include play when you write it atop some program? *(какова роль строки #include , которая фигурирует в верхней части кода некоторых программ?)
  • About how many hours would you say you spent on Problem Set 0: Scratch?(сколько времени у вас заняли задачки нулевой недели (Scratch)
  • About how many hours would you say you spent on Problem Set 1: C?(как долго вы решали задачки первой недели по C?)
  • What's your opinion of CS50x thus far? *(Ваше мнение о CS50 в настоящий момент, выбрать вариант нравится-не нравится)
  • Have you asked for help from classmates or staff via CS50s Facebook Group at http://www.facebook.com/groups/cs50? *(обращались ли вы за помощью к другим студентам или ассистентам в группе facebook)
  • Have you asked for help from classmates or staff via CS50s Subreddit at http://www.reddit.com/r/cs50 *(обращались ли вы за помощью к другим студентам или ассистентам через Subreddit)
  • Have you asked for help from classmates or staff via Twitter using @cs50 or #cs50? *(просили ли вы помощи у других студентов или ассистентов в Twitter используя @cs50 или #cs50).
Друзья, если возникают какие-то вопросы, пишите их в комментариях под этим руководством. Если вы не достигли пятого уровня JavaRush, чтобы получить приглашение на info, рекомендуем это сделать. Это бесплатно, интересно и не очень сложно.
Ресурс кода:
Лекция три http://cdn.cs50.net/2015/fall/lectures/1/w/src1w.zip Лекция четыре http://cdn.cs50.net/2015/fall/lectures/1/f/src1f.zip http://cdn.cs50.net/2015/fall/lectures/1/f/src1f/
Дополнительная литература
http://cpp.com.ru/kr_cbook/ - русская версия классической книги по C от авторов языка — Брайана Кернигана и Дэнниса Ритчи. Широко известна в узких кругах как K&R. Перевод, правда, не самого нового издания. Почитайте первые три главы. Там будет несколько больше материала, чем вам нужно, но достаточно для решения задач. http://computer.howstuffworks.com/c.htm — ресурс, рекомендуемый авторами CS50. На английском языке. Стр. 1-7, 9 и 10.
Комментарии (51)
  • популярные
  • новые
  • старые
Для того, что бы оставить комментарий вы должны авторизироваться
Ohr 5 уровень
1 сентября 2016, 05:51
Всем привет!
Подскажите что за бред почему компилятор матюкая меня, говорит что это выражение
while (1 < h < 24);

может вернуть только
true
?
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
1 сентября 2016, 07:56
Как я понимаю, тебе стоит реализовывать вот так

while ((h>1)&&(h<24))


Опять же на уровне моего понимания, компилятор не может одновременно учитывать два условия, поэтому надо разбивать на шаги и объединять их логическими операциями типа И(&&) ИЛИ (||) НЕ(!). Пошукай в сети на эту тему
Ohr 5 уровень
1 сентября 2016, 08:09
Пробовал, не работает. При таких условиях он компилирует нормально, но принимает любые числа
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
1 сентября 2016, 08:27
Тебе надо чтобы h было в диапазоне от 1 до 24, так? Просто вопрос для чего эта проверка. При таком условии цикл будет отрабатываться пока твое h в этом диапозоне. Покажи сам цикл тут и для чего он тебе. Может смогу подсказать))
Ohr 5 уровень
1 сентября 2016, 08:47
Да именно так, от 1 до 24. Цикл выглядит так:
do {printf("Height: ");
       h = GetInt();
      }
    while ((24 > h) && (h > 0));

По условию задачи после введения числа его нужно проверить- оно должно быть от 0 до 23
З.Ы.(я знаю что до этого мы рассматривали от 2 до 23, это не важно)
EvIv 30 уровень
1 сентября 2016, 09:05
Первое число он тут примет любое. А второе и следующие будет спрашивать только при выполнении условия
EvIv 30 уровень
1 сентября 2016, 09:06
Используй while а не do while
Ohr 5 уровень
1 сентября 2016, 09:24
На сколько я понимаю, цикл while будет просто проверять введенные условия, и не выполняться в случае ошибки, а мне нужно что бы он сначала принял проверил, и в случае не верного ответа предложил ввести данные еще раз.
EvIv 30 уровень
1 сентября 2016, 09:37
do {
} while (условие)
по-русски это «сделай, проверь, продолжай делать если условие истинно»
while (условие) {
}
по-русски значит «делай пока условие истинно»

Вы на каком уровне JavaRush? Как выполняли задачи?
Ohr 5 уровень
1 сентября 2016, 09:49
Причем тут уровень?
Вы мне пытаетесь доказать то что я и так знаю, он должен СНАЧАЛА выполнить условие, потом проверить на правильность, (тут я конечно не много запутался) и в случае ВЫПОЛНЕНИЯ условия повторить, если же условие не выполнилось, закончить цикл.
Суть отсюда не меняется, Сначала условие, потом проверка!
EvIv 30 уровень
1 сентября 2016, 10:02
«выполнить условие» — условием здесь вы называете те действия что между {}? Если да, то верно (только терминология странная).
Давайте по шагам ваш код проверим:
Спросили высоту. Записали в h ответ пользователя. Например, 10.
Проверили: 24 > 10 — верно, 10 > 0 — тоже верно. Поэтому повторяем действия. Спросили высоту. Записали в h ответ, например, -5. Проверили: 24 > -5 — верно, -5 > 0 — не верно. Вышли из цикла.
Именно так работает ваша программа сейчас?
Ohr 5 уровень
1 сентября 2016, 10:48
Спасибо, я понял свою ошибку, правда чуть голова не лопнула)) Он не может проверить два не верных значения, после первого не верного значения он оканчивает цикл, и число присваивается переменной.
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
1 сентября 2016, 10:53
Позвольте попробовать мне.

1) Цикл типа
do
{
некоторые операции;
}
while (условие при котором повторяется цикл);

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

2) Цикл типа
while(условие)
{
некоторые операции;
}

Работает несколько иначе. В нем условие проверяется перед выполнением цикла. Если оно истинно, то выполняются операции внутри фигурных скобок (тело цикла). Если же при первой же проверке условие не будет соответствовать истине, то данный цикл вообще никогда не будет выполнять свое тело.
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
1 сентября 2016, 10:57
По условию задачи вы должны
1. получить некоторое число от пользователя
2. проверить находится ли оно в заданном диапазоне
3а. если да то продолжить выполнения задачи с этим числом
3б. если нет, то выдать ошибку/запросить новое число и проверить его.

Очень помогает в решении разбивать задачи на отдельные сегменты и делать все в строгом соответствии с поставленной задачей.

Надеюсь, что хоть в чем-то смог помочь))
Ohr 5 уровень
1 сентября 2016, 10:57
Все верно, по этому я и хотел запихнуть в do {} while, потому что мне нужен сначала цикл, а потом проверка.
Ohr 5 уровень
1 сентября 2016, 11:46
К стати, я не вижу задач из хакерского задачника, не подскажите где вы их нашли?
Ohr 5 уровень
1 сентября 2016, 11:49
В принципе, само решение не сложное, просто я не совсем разобрался с do while сначала, но теперь я надеюсь я его постиг в полном объеме))
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
1 сентября 2016, 12:28
Вот тут лежит официальный курс cs50

Правда он полностью на английском. Я прохожу его. Там даже за отдельную плату можно получить сертификат, что прошли Гарвардский курс))
Ohr 5 уровень
1 сентября 2016, 14:48
Спасибо
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
31 августа 2016, 18:30
И снова всем привет!
Возвращаюсь к своим баранам. Моя проверка кредиток работает не правильно и я не могу понять где ошибка. Вернее я, по всей видимости, не правильно понимаю как должен работать алгоритм. Например 4111111111111111 должно определятся как VISA. Ок. Как это вижу я (и собственно как реализован мой алгоритм)
1) Берем все вторые числа и умножаем каждое на 2 ( 1*2=2, 1*2=2, 1*2=2, 1*2=2, 1*2=2, 1*2=2, 1*2=2, 1*2=2)
2) Складываем все полученные числа (если число бошьше 10 то его разбираем по разрядно и сначала складываем то чтополучилось (напр. 15 = 1 + 5 + 6)). Для нашего условия (2+2+2+2+2+2+2+2 = 16)
3) Складываем все нечетные элементы первоначального числа (4+1+1+1+1+1+1+1 = 11)
4) Складываем результаты двух сложений (16 + 11 = 27)
5) Если результат делится на 10 без остатка — значит это валидная VISA (в нашем примере)

НО 27 никак не делится на 10 без остатка. То есть одно из двух: либо это не валидная ВИЗА, либо я не правильно понимаю алгоритм.

Подскажите кто поумнее, а?
sibkedr 9 уровень
2 сентября 2016, 13:25
Это из-за трудностей перевода. Сам напоролся на эти грабли. Часа 2 не мог понять что не так. Потом нашел описание алгоритма Луна на русском. Каждая вторая цифра с конца берется, т.е. отсчет справа на лево. В вашем примере 4 надо умножать на 2 (заменит одну 1 на 4 среди тех чисел которые умножаются, т.е. среди четных, и заменить 4 на 1 среди тех что не умножаются.
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
20 августа 2016, 22:43
Ку всем!) А кто-нить делал задачи из «хакерского» задачника? Конкретно интересует задача про номера кредиток. Задайте направление. Как для начала в ней реализовать вычленение каждой второй цифры? Ведь я так понимаю пользователь должен ввести все цифры разом и мы должны записать это в единую переменную long? Или я куда-то не туда смотрю?
EvIv 30 уровень
23 августа 2016, 19:02
Попробуй представить сперва в виде массива символов
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
23 августа 2016, 20:29
Я, признаться думал об этом. Но вот проблемма в том что по заданию советую использовать GetLongLong
But do not assume that the user’s input will fit in an int! Best to use GetLongLong from CS50’s library to get users' input.
То есть ввод осуществить в одну переменную типа лонг. И второй подводный камень для меня тут это возможность ввести последовательность чисел в массив, так, чтобы каждое из них стало отдельным его элементом, не используя при этом Enter. То есть что бы ввод выглядел как: 1948718473, а не как:
1
2
3
4

н
EvIv 30 уровень
23 августа 2016, 21:07
Можно еще разобрать длинное число по цифрам, деля число на десять. То есть в цикле делишь нацело на десять, берешь остаток, запоминаешь. Результат деления снова делишь на десять, остаток снова запоминаешь и так далее, пока цифры не кончатся. Так у тебя соберутся все цифры числа в обратном порядке.
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
24 августа 2016, 22:43
Отличная подсказка. Думаю Так и буду реализовыать. Кстати очень логичное решение в рамках курса, потому что подобный метод нужен и для вычисления количества монет в задачке про сдачу))
sibkedr 9 уровень
27 августа 2016, 21:26
Я сделал. Без использования массивов (а я пока и не умею), программа вышла на 100 строк.
zeffir4ik 8 уровень, Yuzhno-sakhalinsk
31 августа 2016, 18:32
Поверь, использование массивов не облегчает сильно жизнь((( У меня программа будет больше 150 строк ;) А как ты не используя массивы делал?
sibkedr 9 уровень
2 сентября 2016, 13:28
Ну как, все 16 переменных руками прописывал от n1 до n16.
Как решишь, оставь почту, могу поделиться решением
sibkedr 9 уровень
2 сентября 2016, 13:34
А, тут можно тоже в личку писать без почты
Антон Никифоров 1 уровень, Гомель
22 июля, 09:18
С массивом без комментариев 66 строк, 4 дня ворочал в голове мысли не приступая к исполнению. Мысли были разные: собрать массив, сделать его копию, разобрать первые цифры, разобрать вторые цифры из второго массива, проверка на валидность и т.д. Пока в голову не стукнуло, что после ввода лонга и введения его в массив, можно просто навсего работать с этим единственным массивом и обращаться к абсолютно любому его элементу. Подсказка для выполняющих для определения длинны массива (пригодится в дальнейшем): во время формирования массива в цикле путем деления на 10 добавить count.
skalapendro 10 уровень, Екатеринбург
2 августа 2016, 09:13
У этого курса на edx есть дедлайны? А то я с английским пока не очень…
Masha 41 уровень
2 августа 2016, 11:14
Вы можете смотреть переведенные лекции и делать задачи по переведенным задачникам. И проверь задания командой check50. Проверка на edx, по сути, делает то же самое (проводит тесты по основным параметрам, и пишет, все ли пройдены или какой-то провален), просто фиксирует все результаты. Так что если вам важно именно научиться, а не оценки получать, то у вас всё для этого есть, и английский нужен минимально=).

На edx дедлайн до декабря примерно. Потом будет тот же курс, но в редакции следующего года.
khayrulintd 5 уровень, Москва
23 августа 2016, 18:31
То есть после декабря возможно будут изменены задания и пропадет автопроверка на edx?
nyamkas 7 уровень
29 июля 2016, 04:45
Как получить оценки?, при попытке перейти на CS50 Submit пишет:
403 You don't have permission to do that!
Tigran 30 уровень, Москва
29 июля 2016, 09:35
Скорее всего, оценки можно получить, только буду студентом Гарварда, или закупив раз два и три
Есть кто-то на опыте, можете немного прояснить?
Tigran 30 уровень, Москва
29 июля 2016, 00:52
Фуф, доделал Марио) Правда, прежде чем начать делать пирамидку, убил минут 30 на ту самую игру :)
Сначала тоже делал с помощью 2 циклов, расставления пробелов и т.д., потом:
1. нашел интересную функцию, «не имеюющую аналогов в мире»™ — strncat(s1, s2, i) — это позволило избавиться от 1 цикла.
2. нашел классную фишку в printf — знак *
3. минут 20 промурыжился с ошибкой Segmentation fault. Оказалось, что в C нелья просто так взять и конкатенировать строки, как в джаве, злобный компилятор не даст ни грамма лишней памяти :) Решилось через объявление максимального размера при инициализации переменной — char string[40] = "##";

В общем, что-то мне все это напоминает… задачка на 5 строк, а времени 2 часа :) Где-то я все это уже видел…
Pex1k 24 уровень
27 июля 2016, 16:18
Здравствуйте. На счет третьего задания.
Сделал цикл, проверяю с помощью команды «check50 2015.fall.pset1.greedy greedy.c». Все верно, но для числа 4.2 выводится неточный ответ (должен быть 18, а у меня 22). Стал разбираться из-за чего. После того, как я из долларов (4.2) перевожу в центы, должно быть 420 центов, но почему-то именно данное число (я проверял) меняется на 419. Вот кусочек, где я меняю из долларов в центы. x — центы.
Pex1k 24 уровень
27 июля 2016, 18:48
Извините, не могу точно понять. Как до меня дошло, функция round округляет x до до ближайшего целого числа. В каком случае, вы имеете в виду, его использовать? Вы говорите, что умножив на 100 я не получаю целого, но я получаю, только в случае 4.2 оно почему становится 419. Если я использую round в момент того, как запрашиваю число от пользователя, то оно будет округляться (допустим, 4.2 округлится до 4; 0.41 до 0), а это ведь неверно.

P.S. Но благодаря вашему комментарию, заметил, что если вместо float использовать double, то программа работает точно. Но все равно тот момент мне непонятен.
mrserfr 33 уровень, Киев
27 июля 2016, 19:26
нельзя для подсчете денег использовать числа с плавающей точкой, никогда

я не знаю, что там по заданию, но старайтесь считать все в центах и пользоваться сдвигом
Masha 41 уровень
27 июля 2016, 23:14
Тот момент связан именно с реализацией float. Да, дабл здесь применять логичнее, но в курсе намерено ввели условие вводить доллары через float, чтобы дать понять его неточную структуру =). 32 бита мало таким числам, поэтому ошибки такого плана вкрадываются очень часто:
Мы вводим 1.24, а компилятор видит что-то вроде 1.249999946, и не округлив, мы теряем цент.
я делала так: int toCents (float amount)
{
return round(100*amount);
}
Masha 41 уровень
27 июля 2016, 23:16
В условии просили вводить в долларах, а затем переводить в целые числа. Специально, чтобы возникло это непонятное место с float.
Masha 41 уровень
27 июля 2016, 23:24
Это из-за особенностей float-чисел в Cи. Умножив на 100 вы надеетесь получить целое число, большее в 100 раз, а так не получается. Воспользуйтесь функцией округления round, чтобы получить нужно целое. Вот её описание: cs50.harvard.edu/resources/cppreference.com/stdmath/round.html.

по идее должно помочь. Если что-то неясно, пишите, я уточню.
clinch 18 уровень, Санкт-Петербург
2 августа 2016, 01:34
коллеги, ни к чему такие сложности, просто при переводе в центы умножайте значение не на 100 а на 1000, т.е. 4.2 * 1000 = 4200, учитывая, как бы еще тысячные доли, а потом разделите на 10, 4200 / 10 = 420. Так всегда получится перевести из доллоров в центы с учетом округления типа данных float. А далее уже переводите из float в int.
Masha 41 уровень
2 августа 2016, 11:16
Вы правы, просто в лекции рекомендуют воспользоваться round =).
Антон Никифоров 1 уровень, Гомель
19 июля, 00:18
Ну а можно ещё так: float f; int i = (int)(f * 100 * .5);
ggking 0 уровень, Челябинск
26 июля 2016, 20:52
я один только первую задачу решил? а во второй получил пирамиду, которая выравнивается по другому краю, да и то с помощью функции из 5 лекции взятой? мне кажится я что-то не так делаю в этой жизни
зы: опыта на с не было вообще
Jonah_Hex 9 уровень, Seattle
26 июля 2016, 23:00
Для mario.c, как вариант, попробуйте использовать один внешний цикл (для построение пирамиды в высоту), и дополнительно два отдельных вложенных в него цикла (для построения пирамиды в ширину). :)
Masha 41 уровень
27 июля 2016, 17:46
Если опыта нет вообще, это норм=).Не бойтесь поиграться с разными циклами, как и говорил Jonah_Hex. Уточню только, что в одном из вложенных циклов можно печатать не только "#", но символ пробела =).
В правильных местах он поможет поменять направление пирамидки.