Загадка програмування m3ph1st0s 3 (C): "Легкий помилка" [закрито]


11

Це третя частина моєї серії загадок C / C ++; якщо ви пропустили перші 2, вони є тут: (1) головоломка програмування m3ph1st0s 1 (C ++) (2) головоломка програмування m3ph1st0s 2 (C ++): "Зателефонуйте важко!"

Треба сказати, що мої головоломки оригінальні на 100%. Якщо ні, то я завжди констатую це в тексті. Моя 3-та головоломка складається з двох частин:

Головоломка 3.1

Ця частина (3.1) не є моєю головоломкою, вона зібрана з якоїсь інтернет-сторінки, яку я читав деякий час тому. Я використовую це як вихідний пункт і розминку для вас. Розв’яжіть це, а потім перейдіть до другої частини.

Хтось намагався роздрукувати знак "+" 20 разів і придумав таку програму:

#include <stdio.h>
int main() {
   int i;
   int n = 20;
   for( i = 0; i < n; i-- )
      printf("+");
   return 0;
}

Те, що у нього не було очікуваного результату, очевидно - програма ніколи не закінчується. Полагодьте це! Легко? Тепер виправте програму, змінивши ТОЛЬКО ОДИН ХАРАКТЕР - звичайно непробільний символ! Для цього завдання є 3 рішення. Знайдіть усі 3 з них. Просто для того, щоб зрозуміти: програма повинна виводити 20 "+" знаків і повинна швидко закінчуватися. Перш ніж критикувати мене за те, що означає "швидкий", я скажу, що це означає максимум пару секунд (що, до речі, занадто багато, але просто для того, щоб зробити його кришталево чистим).

Головоломка 3.2

ВЕДЕНО Мені раніше вказувалося, що рішення головоломки 3.2.2 може залежати від компілятора. Для того, щоб усунути будь-яку можливу дискусію з цього приводу, я видозмінюю ідею та вдосконалюю її в наступній загадці, коли буду дотримуватися додаткової обережності, щоб не породжувати суперечки. Однак для того, щоб ця головоломка не працювала, я вніс невелику модифікацію для 3.2.2 (рішення буде простішим, але більш чистим).

Коли я вперше побачив головоломку, я вважав її досить приголомшливою. Мені це вдалося вирішити, але не відразу, оскільки це вимагає уважної уваги. Якщо ви тут, це означає, що ви теж вирішили це. Якщо ви зробили це, написавши програму для заміни всіх можливих символів на всі можливі значення та перевірку кожного рішення, ви втрачаєтесь. Хоча працьовитий хлопець. Тепер виправивши програму, яка записує 20 знаків "+":

3.2.1: В коді вставляйте одну літеру і більше нічого, щоб результат був дійсним і виводив те саме в усі 3 виправлені програми. Потрібно сказати, що лист повинен бути перед додаванням} основного (я говорю, що тому, що я не хочу чути людей, які просто клали лист після програми, і їх компілятор якось був дуже привітним).

ЗРЕШЕНО (див. Нижче) - Для цих остаточних питань врахуйте, що лічильник i починається від -1 замість 0.

3.2.1.5: Повторіть усі попередні проблеми з умовою, що вихід має принаймні 19 "+" знаків (але все ж кінцевий вихід). Допускається зміна пробілів. Тепер ви, можливо, знайшли більше рішень, ніж у першому випадку. Деякі з них, безумовно, підійдуть для питання 3.2.2.

3.2.2: Виберіть інше значення для ініціалізації змінної n, щоб результат, що вийшов, залишився однаковим для щонайменше однієї виправленої програми в 3.2.1.5 (не обов'язково для всіх).

ОСТАНА EDIT1 : зміна програми, щоб вона виводила 21 "+" знаків, все ще є хорошим рішенням, оскільки в оригінальному тексті не було сказано "точно" 20 знаків. Однак нескінченний вихід заборонений. Очевидно, це не означає, що давайте всі почнемо виводити сотні знаків "+", оскільки це не заборонено. Але усунення прекрасного 21 результату не було б у дусі цього змагання.

ОСТАНА EDIT2 : з огляду на LAST EDIT1 та прийняття зміни простору, здається, що зараз у нас є 5 можливих рішень, чотири з яких уже вказано у відповідях. Останній виклик, однак, не торкнувся, і я повинен ще раз зрозуміти: n треба присвоїти інше значення , рішення, які присвоюють 20 до n деякими хитрощами, не зроблять це (наприклад, n = 20L). Також я вважаю за краще бачити 3-е рішення, яке не змінює пробіли.

ОСТАНА РЕДАКТ3 : Я редагував останні запитання, будь ласка, прочитайте!

Завдання полягає в тому, щоб вирішити обидві частини головоломки. Перший, хто це зробив, виграє.

Я сподіваюся, що все зрозуміло, якщо не будь-ласка, опублікуйте будь-які питання, і я редагую якнайшвидше. Ура. підкреслений текст


Я припускаю, що зміна одного символу включає зміну будь-яких пробілів на символи, що не містять пробілів? Якщо так, я думаю, що я знайшов усі 3 рішення для частини 1.
mellamokb

ой ... звичайно ... Я мав на увазі відвернути це відверто, але я забув. Я зараз редагую. Thx для запитання.
Богдан Олександру

О добре. Тому що я не можу знайти жодної відповіді на частину 3.2.2 для своїх
останніх

так :) удачі у цьому
Богдан Олександру

1
@ardnew: Я не вірю, що ОП колись змінила початковий намір питання. Я згоден є більш ефективні способи , щоб виправити це питання , ніж ущільнює купу редагувати «з в кінці ... але це все-таки в основі той же самий питання, з деякими речами з'ясовані.
mellamokb

Відповіді:


8

3.1

for( i = 0;-i < n; i-- )
for( i = 0; i < n; n-- )
for( i = 0; i + n; i-- )

Будь-яка з цих змін призведе до виведення програми знаками 20 '+'. Цей близько:

for( i = 0;~i < n; i-- )

Він виводить 21 знаки "+".

3.2.1

Я знайшов принаймні 112 способів вирішити цю проблему, вставивши одну букву. Не всі вони можуть працювати на всіх компіляторах.

int n = 20L;
int n = 20f;
int n = 20d;
uint n = 20;

for( i = 0L; ... )
for( i = 0f; ... )
for( i = 0d; ... )

iprintf("+");
printf("+x");
printf("x+");

Останні два замініть будь-яким листом, xщоб дати 104 можливі рішення. Використання будь-якого з двох останніх рядків змінить вихід, але результат буде все-таки однаковим для всіх 3 виправлених програм.

3.2.2

Все, що я придумав, - це деякі речі, які повертаються до числа 20 за призначенням int.

int n = 20L;
int n = 20.001;
int n = 20.999;
int n = 20 + 0x100000000L;

Так, у вас є точно такі ж відповіді, як і у мене (я їх раніше не публікував, тому що не відповів на все). Я думаю, що відповідь на 3.2.2 полягає в третьому рішенні 3.1, яке ніхто з нас не знайшов (і підкоряється правилу не дозволяти змінювати простір).
mellamokb

У розділі 3.2.1, я не впевнений , про fта dсуфіксах для intтипів (ну, dдля будь-якого типу з цього питання), але є і кілька інших ви залишили від: int n = 20l, int n = 20Uі int n = 20u. Крім того, я не вірю uint, що це стандартний ідентифікатор типу в C або C ++. Який компілятор ви все одно використовуєте для цього?
ardnew

Ви тут зробили досить гарну роботу, але не повну! Перш за все, рішення ~ i все ще добре! Вимога полягала в тому, щоб вивести знаки 20 "+", тому 21 все ще є хорошим рішенням (єдиним поганим рішенням є нескінченний вихід). Це означає, що ви зараз знайшли 4 рішення! І найсмішніше, що у мене є ще один :) Щодо 3.2.2, це погано, оскільки я спеціально вимагав змінити ЦІННОСТЬ на n, а не робити певних хитрощів, щоб зробити це 20 :)
Богдан Александру

1
а також рішення -i та ~ i змінюють пробіли, тому я вважаю їх "частковими" рішеннями. 3-е повне рішення має змінити непробільний персонаж, як зазначено в тексті вікторини
Богдан Александру

1
ви не зрозуміли проблему. Я сказав, що модифікація дасть той самий вихід, що і відповідна модифікована програма. тобто у мене виправлені програми C1, C2, C3. після вставки символів у мене є P1, P2, P3. вимога така: P1 має такий же вихід, як C1, P2 такий же вихід, як C2, P3 такий же вихід, як і C3. Це НЕ P1, P2, P3, які мають однаковий вихід
Богдан Олександру

2

3.1

Ще одна загадка. Але нормальні рішення нудні, а як щодо чогось особливого?

Рішення перше:

#include <stdio.h>
int main() {
   int i;
   int n = 20;
   for( i = 0; i < n; i++ )
      printf("+");
   return 0;
}

Я вирішив змінити ТІЛЬКИ ОДИН ХАРАКТЕР, тобто -. Не -було змінено жодних символів .

Рішення друге:

#include <stdio.h>
int main() {
   int i=printf("++++++++++++++++++++");exit(0);
   int n = 20;
   for( i = 0; i < n; i-- )
      printf("+");
   return 0;
}

Це змінює рівно один символ - крапку з комою після int iна =printf("++++++++++++++++++++");exit(0);.

Рішення третє:

#include <stdix.h>
int main() {
   int i;
   int n = 20;
   for( i = 0; i < n; i-- )
      printf("+");
   return 0;
}

Це завантажує stdix.hзаголовок системи. У систему, що включає шлях, вставити такий файл, який називається stdix.h. Він повинен містити наступний зміст.

static inline void printf(const char *string) {
    int i;
    for(i = 0; i < 20; i--)
        putchar('+');
    exit(0);
}

3.2

Тепер вставити одну букву. Ну, це просто, замініть int main()на int main(a). Це не відповідає стандартам, але кого це хвилює?


0

Головоломка 3.1 відповіді

  1. Змінити i--на n--(демо: http://ideone.com/l0Y10 )
  2. Змінити i < nна i + n(демо: http://ideone.com/CAqWO )
  3. Змінити [SPACE]i < nна -i < n. (демонстрація: http://ideone.com/s5Z2r )

Головоломка 3.2.1

Змінити int n = 20на int n = 20L(додати Lдо кінця).

Головоломка 3.2.2

Ще не знайшли відповіді ...


хороше, стандартне рішення для 3.1 та 3.2.1.
Богдан Олександру

0

3.1

  1. Змінити i--наn--
  2. i<n до -i<n
  3. (На жаль, невірна відповідь, оскільки я не перевіряв компілятора, перш ніж побачив інші відповіді)

3.2.1

int n = 20 

до

uint n = 20

(Компілятор залежить ...)

3.2.2

int n =-20L;

for(i = -1; i%n; i--)

відбитки 19 + знаків, те саме, що і з int n = 20L;. Однак я б не придумав цього, якби не бачив інших відповідей до пункту 3.2.1


0
#include <stdio.h>
int main() {
   int i;
   int n = 20;
   for( i = 0; i < n; i++  )
      printf("+");
        printf("\n");
   return 0;
}

1
Обов’язково додайте у свою відповідь мову програми та кількість символів.
Timtech

1
@Timtech, чому число символів? це не код-гольф
гордий haskeller

1
@Timtech також навіщо включати мову? це специфічна для мови проблема.
гордий haskeller
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.