Salt And Pepper
//Здравейте. Опитвам се от число [0 – 18,446,744,073,709,551,615] да извадя бинарния вариант... До "long" е ОК с този код.
//long n = long.Parse(Console.ReadLine());
//string binary = Convert.ToString(n, 2).PadLeft(32, '0');
//Но "ulong" не работи.
Разбрах, че нямам достъчно знания ( побитовите операции не са ми ясни явно :( ) Но освен, тях си написах нещата. Надявам се да ми обясните тези няколко реда които ми обягват, както и защо в решеието което имам за 100/100 ( не моето за жалост ) се използва "if"
и резолтата е 100/100 в моето решение исползвам "switch" и резолтата е 90/100 :(
Това са редовте които ми обягваха и не разбирам на 100% :
if (((dishes >> j) & 1) == 1)
{
ulong mask = ~((ulong)1 << j);
dishes = dishes & mask;
}
Ето го решението за 100/100: http://pastebin.com/EKXMjrYb
А това е моето 90/100: http://pastebin.com/6hW7RXc5
Благодаря предварително.
Не съм сигурен, че одговора ми помага. Най-вероятно понеже не съм задал правелният въпрос.
Цяла работа е, че сега съм на курса "Programming Basics" и то само след първата лекция :). Но решавам задачите от минал изпит. В момента се опитвам да реша задачата " Programming Basics Exam - 21 February 2016 -->> Problem 05 - Salt And Pepper.
Измислил съм някаква "програмна логика" имам структура която да ми стартира самата програма приема и разделя командите. Имам формули за манипулация на бинарния код на числото което трябва да променя. На кратко трябва да променя всеки Н-ти бит на някъква "ulong" число според зависи команда която получавам. Та идеята ми беше да си направя числото на стринг да го манипулирам като стринг и накрая да го конвертирам в "ulong" отново. Сега като се замисля би трябвало да мога да го направя без цялата хамалогия с обръщане в бинарен код, а просто като така или иначе знам, че са 64-бита да си направя 1 цикъл който да итерира толкова на брой пъти колкото е 64-бита / на Н-тите числа които трябва да обърна от 0 в 1 или обратното.
В случая начина за конвертиране от ulong към двоичен код, който показах в пост-а по-горе работи. Но идеята на тези задачи е да се решат с побитови операции. Ако искаш да опитваш с конвертиране, Convert.ToString((long)number, 2); и Convert.ToUInt64(binary, 2); работят за ulong. Ако си измислил нещо друго или си решил да се пробваш с побитови операции - супер!
И надявам се знаеш, че този тип задачи вече не се включват в приемния изпит. Ако се подготвяш за него - другите четири задачи ще са ти по-полезни. Ако ги решаваш за обща култура и знания - поздравления от мен и продължавай в същия дух!
Предните 4 са готови. С малко помощ от форума и лекторката ми 100/100. Иначе за жалост разбрах, че сега изпита ще е по-лесен.
А тази задача се опитвам с побитови операции да я реша, но не искам да питам направо за одговор понеже искам да я реша до колкото мога сам само с насочващи въпроси които задавам за да си зглоя логиката на това което мъча :)
П.С. Гледах един стар лаб днес и попаднах нан ещо много полезно за тази задача.
http://www.catonmat.net/blog/low-level-bit-hacks-you-absolutely-must-know/
Редактирах темичката да е по-точна. Ако погледнеш ще съм благодарен.
Нека да се опитам да ти обясня този код. Операцията >> означава изместване вдясно с определен брой позиции (съответно << е изместване вляво). Ще го илюстрирам с прост пример:
Тоест, ако 8 в двоична система е: 1000, то с >>3 става на 0001, защото изместваме битовете надясно с 3 позиции.
Побитовото "и" (&) ни връща 1, ако и двата бита са единици или 0 във всички останали случаи. Това означава, че ако използваш &1, крайният резултат може да бъде само 1 или 0, защото се отчита дали последния бит от числото е единица/нула, а другите битове нямат никакво значение (тъй като при числото 1 в двоична система само последният бит е 1).
Така се проверява дали даден бит в числото е 1 или 0 (изместваме го до последна позиция и добавяме &1 - така ако е 1 се получава резултат 1, ако е 0 - резултат 0). В задачата, ако този бит е 1, тогава трябва да се смени на 0. Как става това?
Първо, създаваме число, което да има бит със стойност 1 на желната позиция. Ако искаме 1 на 3-та позиция ще използваме 1<<3. Така ще имаме стойност 1 на 3-ти бит (броим от 0), а всички други ще са 0. След като сме създали числото, обръщаме битовете с побитово отрицание ~.
Защо? По този начин всички битове ще бъдат 1, освен този на позицията, която сме избрали. Съответно, при използване на побитово "и" (&) с числото, чийто бит искаме да променим се получава следното: всички битове, които са били 0, ще си останат 0 ( 0 & 1 = 0 ), всички битове, които са били 1, ще си останат 1 ( 1 & 1 = 1 ). Само бита на желаната от нас позиция, ще стане от 1 на 0 ( тъй като 1 & 0 = 0 ). Пример: 10101 & 11011 = 10001. Надявам се, че си разбрал логиката.
Относно твоето решение: при case "salt", цикъла си го направил for (int j = 0; j < 63; j += step), а трябва да е for (int j = 0; j <= 63; j += step).
Успех!
Много благодаря.