12 / 24
Nov 2017

Jak w prosty sposób w kilku linijkach odwrócić cyfry w zmiennej typu liczbowego?

Samemu raczej się tego nie wymyśli [od zera]. Jeżeli jednak potrafisz [nauczysz się] samodzielnie “poruszac” pomiedzy reprezentacją liczby zapamiętanej w zmiennej liczbowej i zapamiętanej jako ciąg znaków [kolejnych cyfr liczby]. Tzn jeżeli samodzielnie potrafisz napisać funkcje itoa i atoi to na pewno ułatwi [pozwoli] Ci domyśleć się o czym mówi @j4rooo i tak napisać swój kod. Jeżeli jednak będziesz korzystał z dostępnych w bibliotece standartowej funkcji, to raczej będzie to chyba dla Ciebie czarna magia :wink:

Po zastanowieniu, jednak tak jak @j4rooo nie potrafię. Myślę, że potrafiłbym to zrobić w dwóch zmiennych typu int, [plus zmienna pomocnicza np int8] ale odwrócić [w miejscu] w jednej zmiennej? To dla mnie czarna magia, ale może się nauczę czegoś nowego :slight_smile:

A czy ja mówię, że nie można użyć dodatkowej zmiennej? :slight_smile:

Okej, przy zastąpieniu itoa -> sprintfem SPOJ zaakceptował, w VS mimo to i tak wystąpił C4996, który pominąłem pragmą. Ale mój program opierał się na wczytywaniu liczb jako intów, później w funkcji te inty musiałem konwertować na stringi do tablicy charów (w dodatku statycznych…), tworzyć drugą tablicę by wpisać tam odwróconą pierwszą, z powrotem funkcją atoi przekonwertować nową tablicę charów na inta i porównać ze sobą obydwa inty. Sposób mocno łopatologiczny, ale działa. Tak czy tak chciałbym dowiedzieć się właśnie jak można bazując na samych intach odwrócić kolejność liczb bo póki co wydaje mi się to abstrakcją, nie widzę też specjalnie żadnych praw czy twierdzeń matematycznych ze średniej których mógłbym użyć w takim algorytmie :slight_smile:

Poniżej coś spłodzonego w trybie ultrafast. Nie jest to cud programistyczny ani algorytmiczny, ale pokazuje ideę:

#include <bits/stdc++.h>

using namespace std;

int how_many_digits(int x)
{
	int ans = 0;
	
	while(x) {
		
		x /= 10;
		++ans;
		
	}
	
	return ans;
}

int reverse(int x)
{
	int digits = how_many_digits(x);
	int ans = 0;
	
	for(int i = 1; i <= digits; ++i) {
		
		ans += (x % 10) * (int)pow(10, digits - i);
		x /= 10;
		
	}
	
	return ans;
}

int main() {
	int x = 1264789;
	//int x = 100;
	//int x = 13;
	//int x = 0;
	//int x = 1;
	
	cout << reverse(x);
	
	return 0;
}

Ta potęga jest tam chyba zbędna? :slight_smile:

int get_backward(int a){
	int result = 0;
	while(a) {
		result *= 10;
		result += a % 10;
		a /= 10;
	}
	return result;
}

Tam wiele rzeczy jest zbędnych, co pokazałeś powyżej. Rozwiązanie na szybko i karkołomne, ale działa nie najgorzej więc je wstawiłem.

I tu objawia się słabość SPOJ’a. Dla SPOJ’a nie liczy się piękność, funkcjonalność, czytelność itd kodu tylko aby działał prawidłowo [na AC]. Gorzej, że i większość użytkowników się tym zadawala [AC] i nie dąży do “doskonałośći”. Z drugiej strony w programowaniu lepszy jest brzydki ale działający program niż piękny ale działający błędnie lub wcale. Jeżeli jednak już w tak małych i prostych problemach [kodach] nastawimy się wyłącznie na AC, to jak będą wyglądały większe programy? :wink:
Kod @j4rooo też nie jest doskonały i kiedyś w wolnej chwili wstawię [myślę] że odrobinę lepszy mój :wink:
.

Zgadzam się.

Tutaj mogę Cię zaskoczyć :wink: Zadania łatwe na SPOJu rozwiązuję często bezmyślnie, np. mając wolną chwilę w pracy, albo zaraz po powrocie do domu. Moja strategia to pałowanie zadania aż wyjdzie AC. Z kolei gdy problem jest złożony, rytuał rozwiązywania problemu zaczynam od wyciągnięcia kartki i rozpisania treści i testów, wprowadzam komentarze do kodu itd :wink: W zadaniach łatwych też mi się to zdarza, ale raczej sporadycznie. Stąd częściej mam problemy z zadaniami łatwymi (bo nie testuję ich dokładnie i nie wnikam zbyt głęboko w treść) niż średnimi albo trudnymi - tam nie implementuję niczego nie mając pewności, że idę w dobrą stronę.

Tak to już jest, gdy poza limitem czasu w zadaniu dochodzi limit czasu w realu :wink:

Sorry, jeżeli to wziąłeś całkowicie do siebie. Miałem na myśli statystycznego, przeciętnego użytkownika, a więc i siebie z przed kilku lat [miesięcy]. Teraz już tak nie robię, bo zabrakło dla mnie łatwych zadań, może po fraktalu parę dojdzie ;-). AAle nadal widzę u siebie braki, np prawie całkowity brak komentarzy w moich kodach, a to że teraz moje kody są lepsze i może piękniejsze nie wynika, że się specjalnie staram, tylko wychodzi to automatycznie i wynika z mojej większej wiedzy od tej którą miałem kiedyś.
Możzzliwe, że ulepszeniem tego wszystkiego byłby system mentorski, ale że do tanga trzeba dwojga…

BTW
Dzisiaj o 20:00 idę na pierwszą, próbną lekcję tanga argentyńskiego, ale problem jest taki, że instruktor[s] jeszcze o tym nie wie[dzą]. Kochane Panie, przykro mi, już mam z kim iść.

Mi zostały 22 zadania. Część do spałowania jak Dziwny wirus, część trudniejsza jak Stonogi :wink: Ale gonię Cię, choć na razie 40 miejsce w rankingu :wink:

Co z tego, że dojdzie jak po fraktalu miał już wtedy gotowe rozwiązania do wysłania :smiley:

Musisz zrobić o jedno zadanie więcej. Właśnie dodałem. Czemu w łatwych? A czemu nie? :wink:

Mylisz się :slight_smile:

PS
Twoja wypowiedź brzmiała jak prawdziwa zachęta do pałowania pewnego łatwego zadania na SPOJu i to ścigając się z dopuszczalnym czasem przerwy w pracy :wink:

Oczywiście pomyliłem się. Nic nie musisz. Miałem tylko na myśli, że w tym momewncie przybyło Ci jedno nowe łatwe zadanie więcej w łatwych :wink: Ale oczywiście to już nieaktualne :wink:

A teraz na poważnie: gratuluję pomysłowego zadania. Treść jest ciekawa (choć to pewnie wiesz :wink: ), solucja dla osoby nie znającej kilku tricków nie będzie zbyt prosta :slight_smile:

8 days later

Aby ktoś coś kolwierk zobaczył powinieneś to ułatwić. Pisząc tylko dla siebie i kompilatora możesz cały kod napisać nawet w jednej linii [jeżeli się da] lub kilku. Prosząc o pomoc postaraj się jeszcze staranniej, dokładniej i konsekwentniej formatować swój kod. W tej chwili tak nie jest.

Na teraz jedyne uwagi to:

  1. short a,b=0,c,licznik=0;
    scanf("%hi",&a);
    while(b!=c)
    

c jest nieinitializowane, więc może przyjąć dowolną wartość. Co jeżeli będzie już na początku równe 0?

  1. Używanie typu short jest rzadko uzasadnione [np duże tablice stosunkowo małych liczb]. Najczęściej najbezpieczniej i najwygodniej jest zawsze używać [tutaj też] tylko typu int.
  2. Popraw formatowanie, może wtedy z przyjemnością “poczytam” twój kod.