Układanka programistyczna m3ph1st0s 3 (C): „Łatwy błąd” [zamknięty]


11

To trzecia część mojej serii łamigłówek C / C ++; jeśli przegapiłeś pierwsze 2, są tutaj: (1) Programowanie puzzli m3ph1st0s 1 (C ++) (2) Programowanie puzzli m3ph1st0s 2 (C ++): „Zadzwoń mocno!”

Muszę powiedzieć, że moje puzzle są w 100% oryginalne. Jeśli nie, zawsze to stwierdzę w tekście. Moja trzecia łamigłówka składa się z 2 części:

Puzzle 3.1

Ta część (3.1) nie jest moją oryginalną łamigłówką, została zebrana z jakiejś strony internetowej, którą czytałem jakiś czas temu. Używam go tutaj jako punktu wyjścia i rozgrzewki dla ciebie. Rozwiąż ten problem, a następnie przejdź do drugiej części.

Ktoś próbował wydrukować znak „+” 20 razy i wymyślił następujący program:

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

Fakt, że nie przyniósł oczekiwanego rezultatu, jest oczywisty - program nigdy się nie kończy. Napraw to! Łatwy? Teraz napraw program, zmieniając TYLKO JEDEN ZNAK - oczywiście spacja! Dla tego wyzwania istnieją 3 rozwiązania. Znajdź wszystkie 3 z nich. Żeby było jasne: program musi wygenerować 20 znaków „+” i musi zakończyć się szybko. Zanim skrytykuję mnie, co oznacza „szybki”, powiem, że oznacza to najwyżej kilka sekund (co, nawiasem mówiąc, to za dużo, ale po prostu, żeby było jasne).

Puzzle 3.2

ZMIENIONO Wskazano mi wcześniej, że rozwiązanie łamigłówki 3.2.2 może zależeć od kompilatora. Aby wyeliminować wszelkie możliwe dyskusje na ten temat, zmodyfikuję ten pomysł i poprawię go na następnej łamigłówce, kiedy dołożę wszelkich starań, aby nie wywoływać kontrowersji. Jednak, aby utrzymać tę łamigłówkę, zrobię małą modyfikację do 3.2.2 (rozwiązanie będzie łatwiejsze, ale czystsze).

Kiedy po raz pierwszy zobaczyłem układankę, okazało się, że jest całkiem niesamowita. Udało mi się go rozwiązać, ale nie od razu, ponieważ wymaga to starannej uwagi. Jeśli tu jesteś, oznacza to, że ty też go rozwiązałeś. Jeśli to zrobiłeś, pisząc program, który zastąpi wszystkie możliwe znaki wszystkimi możliwymi wartościami i przetestujesz każde rozwiązanie, jesteś zgubiony. Ale ciężko pracujący facet. Po poprawieniu programu, który zapisuje 20 znaków „+”:

3.2.1: Wstaw jedną pojedynczą literę i nic więcej do kodu, aby wynik był prawidłowy i wyświetlał to samo we wszystkich 3 poprawionych programach. Nie trzeba dodawać, że list musi znajdować się przed załącznikiem} main (mówię to, ponieważ nie chcę słyszeć ludzi, którzy po prostu napisali list po programie i jakoś ich kompilator był bardzo przyjazny).

EDYTOWANE (patrz poniżej) - w przypadku tych ostatnich pytań należy wziąć pod uwagę, że licznik i zaczyna się od -1 zamiast 0.

3.2.1.5: Powtórz wszystkie poprzednie problemy z warunkiem, że wyjście ma co najmniej 19 znaków „+” (ale nadal jest wyjściem skończonym). Zmiana spacji jest dozwolona. Teraz mogłeś znaleźć więcej rozwiązań niż w pierwszym przypadku. Niektóre z nich z pewnością będą pasować do pytania 3.2.2.

3.2.2: Wybierz inną wartość, aby zainicjować zmienną n, tak aby wynikowy wynik pozostał taki sam dla co najmniej jednego poprawionego programu w 3.2.1.5 (niekoniecznie dla wszystkich).

OSTATNIA EDYCJA 1 : zmiana programu tak, aby wyświetlał 21 znaków „+”, jest nadal dobrym rozwiązaniem, ponieważ oryginalny tekst nie zawierał „dokładnie” 20 znaków. Jednak nieskończona moc wyjściowa jest zabroniona. Oczywiście nie oznacza to, że zacznijmy wypisywać setki znaków „+”, ponieważ nie jest to zabronione. Ale wyeliminowanie pięknego wyniku 21 nie byłoby w duchu tej konkurencji.

LAST EDIT2 : biorąc pod uwagę LAST EDIT1 i zaakceptowanie zmiany przestrzeni wydaje się, że teraz mamy 5 możliwych rozwiązań, z których cztery zostały już wskazane w odpowiedziach. Ostatnie wyzwanie nie zostało jednak dotknięte i muszę jeszcze raz wyjaśnić: n należy przypisać inną wartość , rozwiązania, które przypisują 20 do n przez niektóre lewy, nie zrobią tego (np. N = 20L). Wolę też zobaczyć trzecie rozwiązanie, które nie zmienia spacji.

LAST EDIT3 : Zredagowałem ostatnie pytania, proszę przeczytać!

Wyzwanie polega na rozwiązaniu obu części układanki. Wygrywa ten, kto pierwszy to zrobi.

Mam nadzieję, że wszystko będzie jasne, jeśli nie, proszę o zadawanie pytań, a ja dokonam edycji tak szybko, jak to możliwe. Twoje zdrowie. podkreślony tekst


Zakładam, że zmiana jednego znaku obejmuje zmianę spacji na znaki spacji? Jeśli tak, myślę, że znalazłem wszystkie 3 rozwiązania dla części 1.
mellamokb 1'12

oh..sorry .. Miałem na myśli, aby wyraźnie temu zaprzeczyć, ale zapomniałem. Będę teraz edytować. Dziękuję za pytanie.
Bogdan Alexandru

O Boże. Ponieważ nie mogę znaleźć odpowiedzi dla części 3.2.2 dla moich obecnych 3 rozwiązań ... Myślę, że to oznacza, że ​​muszę szukać jeszcze jednego :)
mellamokb 1'12

tak :) powodzenia
Bogdan Alexandru

1
@ardnew: Nie wierzę, że OP zmieniło kiedyś pierwotny cel pytania. Zgadzam się, że są lepsze sposoby na rozwiązanie tego pytania niż narzucenie kilku Edycji na końcu ... ale nadal jest to sedno tego samego pytania, z pewnymi wyjaśnieniami.
mellamokb

Odpowiedzi:


8

3.1

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

Każda z tych zmian spowoduje, że program wyświetli znaki 20 '+'. Ten jest blisko:

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

Wyprowadza znaki 21 '+'.

3.2.1

Znalazłem co najmniej 112 sposobów rozwiązania tego problemu, wstawiając jedną literę. Nie wszystkie z nich mogą działać na wszystkich kompilatorach.

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+");

W przypadku dwóch ostatnich podstaw dowolną literę, xaby uzyskać 104 możliwe rozwiązania. Użycie jednego z dwóch ostatnich wierszy zmieni dane wyjściowe, ale dane wyjściowe pozostaną takie same dla wszystkich 3 poprawionych programów.

3.2.2

Wymyśliłem tylko kilka rzeczy, które wracają do liczby 20 po przypisaniu do int.

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

Tak, masz dokładnie te same odpowiedzi, co ja (nie publikowałem ich wcześniej, ponieważ nie otrzymałem odpowiedzi na wszystkie pytania). Myślę, że odpowiedź na 3.2.2 leży w trzecim rozwiązaniu do 3.1, którego żaden z nas nie znalazł (i przestrzega zasady niedopuszczania do zmiany przestrzeni).
mellamokb

Na 3.2.1, nie jestem pewien co do fi dprzyrostków dla inttypów (dobrze, ddla dowolnego typu dla tej sprawy), ale istnieje kilka innych już zostało przerwane: int n = 20l, int n = 20U, i int n = 20u. Również nie wierzę, że uintjest standardowym identyfikatorem typu w C lub C ++. Jakiego kompilatora i tak używasz?
nowy

Wykonałeś tu całkiem niezłą robotę, ale jeszcze nie wszystko! Po pierwsze, rozwiązanie ~ i jest nadal dobre! Wymagano wypisania 20 znaków „+”, więc 21 jest nadal dobrym rozwiązaniem (jedynym złym rozwiązaniem jest nieskończona wydajność). Oznacza to, że znalazłeś 4 rozwiązania! I zabawne jest to, że wciąż mam jeszcze jedną :). O 3.2.2 jest źle, ponieważ specjalnie wymagałem zmiany WARTOŚCI n, a nie robienia kilku sztuczek, aby uzyskać 20 :)
Bogdan Alexandru

1
a także rozwiązania -i i ~ i zmieniają spacje, więc rozważę je jako rozwiązania „częściowe”. 3. kompletne rozwiązanie musi zmienić znak spacji zgodnie z tekstem quizu
Bogdan Alexandru

1
nie zrozumiałeś problemu. Powiedziałem, że modyfikacja wygeneruje takie same dane wyjściowe jak odpowiadający jej zmodyfikowany program. to znaczy mam poprawione programy C1, C2, C3. po wstawieniu znaku mam P1, P2, P3. Wymaganie jest następujące: P1 ma takie samo wyjście jak C1, P2 ma takie samo wyjście jak C2, P3 ma takie samo wyjście jak C3. To NIE P1, P2, P3 mają tę samą moc wyjściową
Bogdan Alexandru

2

3.1

Jeszcze jedna łamigłówka. Ale normalne rozwiązania są nudne, a może coś wyjątkowego?

Rozwiązanie pierwsze:

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

Postanowiłem zmienić TYLKO JEDEN CHARAKTER, czyli -. Żadne postacie inne niż -zostały zmienione.

Rozwiązanie drugie:

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

Zmienia to dokładnie jeden znak - średnik po int ina =printf("++++++++++++++++++++");exit(0);.

Rozwiązanie trzecie:

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

Spowoduje to załadowanie stdix.hnagłówka systemu. W systemie dołącz ścieżkę wstaw następujący plik o nazwie stdix.h. Musi zawierać następującą zawartość.

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

3.2

Teraz wstaw jedną literę. Dobrze, że to proste, wymienić int main()z int main(a). Nie jest to zgodne ze standardami, ale kogo to obchodzi?



0

3.1

  1. Zmień i--nan--
  2. i<n do -i<n
  3. (Niestety nieprawidłowa odpowiedź, ponieważ nie sprawdzałem przy użyciu kompilatora przed zobaczeniem innych odpowiedzi)

3.2.1

int n = 20 

do

uint n = 20

(Zależny od kompilatora ...)

3.2.2

int n =-20L;

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

drukuje 19 + znaków, tak samo jak z int n = 20L;. Jednak nie wymyśliłbym tego, gdybym nie widział innych odpowiedzi do 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
Dodaj do odpowiedzi język programu i liczbę znaków.
Timtech

1
@Timtech, dlaczego liczba znaków? to nie jest kod-golf
dumny haskeller

1
@ Timtech również dlaczego warto dołączyć język? jest to wyzwanie specyficzne dla języka.
dumny haskeller
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.