Czołem,
Czy ktoś mógłby dać wskazówkę, dlaczego mój program nie przechodzi przez spoja.
Program sprawdza:
-występowanie liczb w kwadratach 3 x 3,
- występowanie liczb w każdym rzędzie, kolumnie,
- zlicza sumę liczb w każdym rzędzie.
- sprawdza czy liczby są spoza zakresu 1-9.
Na przykładach z zadania działa i na powyższych tutaj wymienionych.
Nie wiem czy jest to kwestia jakiegoś głupiego błędu czy coś poważniejszego…
Link do programu:
Twój kod jest tak długi, a noc tak krótka, że nie podejmuję się jego analizy, ale kilka uwag:
Więc powinieneś to pokazać właśnie na ideone, wklejając do okienka stdin [wejście] wszystkie testowane przykłady.
Sprawdzanie sumy moim zdaniem nie jest dobre, np 9 x 5 = 45, a także dowolnie wiele różnych kombinacji 9 liczb jednocyfrowych spełnia ten warunek [== 45]
Używasz C++, to nie używaj narzędzi z C. [narzędzi i/o]
Twoje wczytywanie jest mówiąc oględnie dziwne i skomplikowane. Przecież można w tym zadaniu w prosty sposób np tak:
for (int i = 0; i < 9; ++i)
for (int j = 0; j < 9; ++j)
cin >> sudokuArray[i][j];
Jeżeli używasz do testowania funkcji printSudoku(), to bardzo dobrze, ale jeżeli chcesz pomocy i pokazujesz swój kod, to “odchódź” go maksymalnie. Oszczędzisz w ten sposób chcącym pomóc kawałek nocy i łatwiej znajdziesz chętnych do pomocy. Ja na razie wymiękam. Jeżeli twój kod schudnie to może wtedy
Mój pierwszy program AC, pierwszą rzeczą jaką sprawdzał, to czy wszystkie liczby w sudoku są z zakresu 1…9, i dla kogoś, kto grał-rozwiązywał sudoku, jest to oczywiste ale tu w zadaniu tak nie jest. Liczby są z zakresu -1000 … 1000
Dzisiaj, pomyślałem, że może nie trzeba sprawdzać wszystkiego i praktycznie przetestowałem to.
https://ideone.com/pt002p8 - tutaj widać, że działa dla wszystkich 5 przypadków.
Początkowo miałem samo sprawdzanie sumy, ale zdałem sobie sprawę, że to łatwo można “obejść” żeby wyszło 45.
Dlatego napisałem funkcję sprawdzającą występowanie liczb w każdej linii, a następnie kolejną sprawdzającą w kwadratach 3x3.
Napisałem warunek, że liczby spoza zakresu 1-9 zwrócą false, ponieważ takie liczby nie występują w Sudoku. Natomiast użytkownik może wprowadzać liczby ujemne i dodatnie, co jest powiedziane w treści zadania.
Wczytuje linia po linii po 9 cyfr. Bo tak jest pokazane w zadaniu, aby wprawdzać liczby oddzielone spacją. Stąd używam getline z tablicą string, którą później konwertuje na int. Robiłem już kiedyś podobne zabiegi przy zadaniach na spoju i to działało.
to nie jest chyba ostateczna wersja?
- Pobawilem się trochę programem i wrzuciłem przypadek testowy.
Gdy w przypadku testowym jest liczba z większą iloscia cyfr robi sie coś, dla mnie niezrozumialego, z tablica arr w funkcji convertStringToInt.
Nastepny przypadek testowy wykazuje NIE, a powinien TAK.
Dla obserwacji tablicy mozna odkomentować w tej funkcji 2 linijki (tą drugą dodałem dla przejrzystości)
Co tam sie dzieje? Moze lepiej nie sprawdzac i użyc propozycji @narbej
Nic tutaj nie widać. Powinieneś wkleić testy w okienko stdin a nie w treść i tak już przydługiego swojego programu --> tutaj widać, że jednak nie działa: https://ideone.com/OsdBGh2, a te 5 przypadków, to dużo za mało. Musisz dodać więcej przypadków [np swoich].
int totalSum = 45; // Suma w linii od 1 do 9 zawsze wynosi 45 - kryterium prawdy ulozenia liczb w Sudoku
Nie jest to kryterium prawdy, już Ci o tym pisałem. Jedynym prawdziwym kryterium jest to, że w danym “kawałku” sudoku mają wystąpić wszystkie liczby z zakresu 1…9. I to jest prawda, tylko prawda i cała prawda i jedyne kryterium. To że zupełnie przez przypadek suma tych liczb wynosi 45 a iloczyn równa się 9! [dziewięć silnia] to już nie jest istotne i w swoim programie nie musisz tego faktu wykorzystywać, a najlepiej zapomnij. Sprawdzaj tylko czy są wszystkie liczby z zakresu [1.9].
Czemu nie, jak jest to dobrze zrobione to działą. Też tak robię/robiłem, ale tylko w tych zadaniach, kiedy nie wiadomo ile tych liczb będzie do wczytania w linii. Tutaj wiadomo, że będzie ich dokładnie 9 [w linii], a to czy są odzielone spacją czy enterem [czy tabulatorem czy innym dowolnym białym znakiem - są jeszcze jakieś inne białe? ] nie ma znaczenia. Funkcja cin [scanf] tutaj w tym zadaniu doskonale sobie z takim wczytaniem poradzi, na przykład w taki sposób jak podałem wyżej. Scanf/cin rfadzi sobie w takich wypadkach także doskonale, gdy dowolnych białych znaków jest dowolnie więcej niż jeden lecz jeden minimum.
Tak zupełnie na marginesie i na przyszłość: Moim zdaniem, funkcja nie powinna zajmować się drukowaniem wyniku “TAK/NIE”, a tylko zwracać wartość true/false. Dopiero program używający funkcji [tu main] decyduje, co zrobić z tą wartością [tutaj dopiero main powinien drukować TAK/NIE].
Moja propozycja. Napisz program zupełnie od zera i od nowa z dzisiejszą swoją wiedzą.
Nie, żeby Cię pognębić, ale abyś zdawał sobie sprawę o czym piszę i do czego powinieneś dążyć, odchudzając swój program - mój pierwszy AC program to 37 linijek [C] w tym 5 linii pustych, dwie zakomentowane i 3 tylko z ‘}’.
Używam formatu;
for (.....) {
.....
}
a jeżeli nawiasy są zbędne to ich nie używam.
Mój dzisiejszy program w C++ to 31 linijek kodu, w tym 2 puste i 4 z zamykającym ‘}’. Piszę o pustych liniach, bo wszystko można oczywiście upchać do jednej linii, ale przecież nie o to chodzi.
Mam też:
if (sprSudoku (sudokuArray)) cout << "TAK\n";
else cout << "NIE\n";
co może powinno być zapisane w 4 linijkach co dałoby 33 linijki kodu.
Zmieniłem metodę wczytywania danych z getline na dwie pętle for i cin zaproponowaną przez @narbej przeszło na ideone (/75Rtfx) oraz sędzia w końcu zaakceptował odpowiedź.
W tym przypadku moja metoda z getline nie działała poprawnie. Choć przy debuggowaniu nie było tego widać i program w konsoli wyświetlał dobrze wszystkie odpowiedzi. Stąd do końca nie wiem co się psuło.
TAK - zgadzam się z Wami w 100%, że program jest za długi i można go odchudzić.
Natomiast powstawał “drogą ewolucji”, gdyż stopniowo zacząłem dostrzegać, że samo zliczanie sumy nie załatwia sprawy (gdyż możemy mieć liczby spoza zakresu 1-9), następnie zacząłem sprawdzać występowanie liczb w wierszach, by ostatecznie napisać funkcję sprawdzająca liczby w kwadratach 3x3.
Przetestuje go na samej funkcji sprawdzającej kwadraty 3x3. Choć muszę przyznać, że krótszej metody działania tej funkcji nie byłem w stanie napisać, ponieważ miałem błędy przy “przeskakiwaniu” do kolejnych elementów tablicy przy porównywaniu. Funkcja jest trochę przydługawa, ale starałem się, aby była w miarę czytelna jak do tego wrócę za jakiś czas.
Podsumowując, dzięki za merytoryczną dyskusję i wskazówki, które pozwoliły mi w zaakceptowaniu programu przez sędziego!
Cześć czytałem już na forum że jest problem z wczytywaniem danych, tylko że ja piszę w Pythonie i nie wiem jak to rozwiązać, dostaję błąd NZEC, oto mój kod:
https://ideone.com/qWBAwB6
Uruchomiłem Twój kod uprzednio go kopiując i też mam błąd:
https://ideone.com/mZYcvU13
Sprawdź o co może chodzić bo to prawdopodobnie to.
Gdyby ktoś czytał ten wątek, będę wdzieczny za pomoc,
z tym kodem [już nie potrzebny]
sędzia nie akceptuje zadania, a ja mam wrażenie, że sprawdziłem wszystkie opcje. Moze ktoś rzucić okiem, albo podsunąć pomysł na skrajny przypadek?
Sprawdzam zakres, kolumnę, wiersz oraz podkwadraty. Czy jest może jeszcze jakieś kryterium na długość kodu czy inne haczyki?
Cześć, czy ktoś może pomóc mi z programem?
Uruchamiam program w CodeBlocks i wszystkie odpowiedzi mam poprawne - bez błędów: TAK NIE TAK NIE NIE
Uruchamiam program w Ideone i wyskakują mi błędne odpowiedzi dla tych samych danych co w CodeBlocks - 5xNIE
Szukałem przyczyny problemu, ale nie mogę znaleźć.
EDIT: usunięto kod
Włącz ostrzeżenia kompilatora. Dostaniesz kilka ostrzeżeń w rodzaju:
prog.cpp: In function ‘bool CzyCyfryOd1Do9WPoziomie(int*)’:
prog.cpp:85:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
W sytuacji takiej jak powyżej, w zależności od systemu, program zostanie skompilowany w różny sposób, w zależności od systemu, wersji kompilatora itd, a potem skompilowane programy będą działały inaczej. Jak to poprawisz i uzyskasz kompilacje bez warrningów, wtedy i na ideonie i u siebie [mało istotne] uzyskasz jednakowe rezultaty działania programu.
Bardzo pomocna w tym zadaniu jest umiejętność samodzielnego rozwiązywania łamigłówki sudoku lub przynajmniej dokładne “przestudiowanie” zasad “gry”.