Головоломка m3ph1st0s по программированию 3 (C): «Легкая ошибка» [закрыто]


11

Это третья из моей серии головоломок C / C ++; в случае, если вы пропустили первые 2, они здесь: (1) головоломка программирования m3ph1st0s 1 (C ++) (2) головоломка программирования m3ph1st0s 2 (C ++): "Call hard!"

Надо сказать, что мои головоломки на 100% оригинальны. Если нет, я всегда буду утверждать это в тексте. Моя третья головоломка состоит из 2 частей:

Головоломка 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 исправленных программах. Само собой разумеется, что письмо должно быть перед включением} main (я говорю это, потому что я не хочу слышать людей, которые просто помещают письмо после программы, и их компилятор был очень дружелюбен).

РЕДАКТИРОВАНИЕ (см. Ниже) - Для этих последних вопросов учтите, что счетчик i начинается с -1 вместо 0.

3.2.1.5: Повторите все предыдущие проблемы с условием, что на выходе должно быть не менее 19 знаков «+» (но все же конечный результат). Смена пробелов разрешена. Теперь вы могли бы найти больше решений, чем в первом случае. Некоторые из них наиболее точно подойдут для вопроса 3.2.2.

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

ПОСЛЕДНЕЕ РЕДАКТИРОВАНИЕ1 : изменение программы таким образом, чтобы она выводила 21 знак «+», все еще является хорошим решением, поскольку в исходном тексте не было «точно» 20 знаков. Однако бесконечный вывод запрещен. Очевидно, это не означает, что давайте все начнем выводить сотни знаков «+», поскольку это не запрещено. Но исключение прекрасного 21 результата не было бы в духе этого соревнования.

ПОСЛЕДНЯЯ РЕДАКТИРОВАТЬ2 : принимая во внимание ПОСЛЕДНЮЮ РЕДАКТИРОВАТЬ1 и принимая изменения пространства, кажется, что теперь у нас есть 5 возможных решений, четыре из которых уже были указаны в ответах. Последняя проблема, однако, не была затронута, и я должен прояснить это еще раз: n должно быть назначено другое значение , решения, которые назначают 20 на n с помощью некоторых приемов, не будут этого делать (например, n = 20L). Также я предпочитаю видеть 3-е решение, которое не меняет места.

ПОСЛЕДНИЕ РЕДАКТИРОВАТЬ3 : Я редактировал последние вопросы, пожалуйста, прочитайте!

Задача состоит в том, чтобы решить обе части головоломки. Первый, кто это сделает, побеждает.

Я надеюсь, что все ясно, если нет, пожалуйста, напишите какие-либо вопросы, и я буду редактировать как можно быстрее. Приветствия. выделенный текст


Я предполагаю, что изменение одного символа включает замену пробелов на непробельные символы? Если так, я думаю, что я нашел все 3 решения для части 1.
mellamokb

о ... извините .. Я имел в виду, что это явно отрицаю, но я забыл. Я сейчас отредактирую. Спасибо за вопрос.
Богдан Александру

О, хорошо. Потому что я не могу найти ответ для части 3.2.2 для моих текущих 3 решений ... Я думаю, это означает, что мне нужно искать еще одно :)
mellamokb

да :) удачи в этом
Богдан Александру

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

Вы проделали довольно хорошую работу здесь, но не завершены! Прежде всего, решение все еще хорошо! Требовалось выводить 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, почему количество символов? это не код-гольф
гордый хаскеллер

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