C, int
: 138 123 bajtów long
: 152 131 bajtów
Stworzyłem dwie wersje tego, ponieważ limit wyzwań dla maksymalnego działania 0x100000000
wydawał się nieco dziwny. Jedna wersja działa z 32-bitowymi liczbami całkowitymi (która z oczywistych powodów nie spełnia limitu), druga wersja działa z 64 bitami (co znacznie wykracza poza podany limit, kosztem 14 8 dodatkowych bajtów).
Wersja 32-bitowa:
char b[22],*r=b;f(v,l)char*l;{v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
Wersja 64-bitowa:
char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
Jest to identyczne, z tą różnicą, że deklaruje zmienną całkowitą long
(która ma 64 bity w Linux).
Wersja bez golfa long
:
char buffer[22],*result=buffer;
f(long value,char*letter){
if(value%3>1){
*result++=*letter,value++;
}
if(value){
f(value/3,letter+1);
}
if(value%3){
*result++=*letter;
}
}
g(long value){
f(value,"139ABCDEFGHIJKLMNOPQR");
*result=0;
result=buffer;
}
Jak widać, działa to przez rekurencyjne przyzwoite: Jeśli reszta to 1, odpowiedni znak jest dołączany do ciągu wyjściowego po wywołaniu rekurencyjnym. Jeśli reszta to 2, dane wyjściowe są wykonywane przed powtórzeniem. W tym przypadku zwiększam również wartość o jeden, aby poprawnie obsługiwać cyfrę ujemną. Daje to dodatkową korzyść polegającą na zmianie reszty na zero, co pozwala mi korzystaćvalue%3
jako warunku dla rekursji po rekursji if.
Wynik konwersji jest umieszczany w buforze globalnym. Zadaniem g()
otoki jest prawidłowe zakończenie wynikowego łańcucha i zresetowanie result
wskaźnika do jego początku (tak też jestg()
„zwraca” wynik).
Przetestuj long
wersję za pomocą tego kodu:
#include <stdio.h>
char b[22],*r=b;f(long v,char*l){v%3>1?*r++=*l,v++:0;v&&f(v/3,l+1);v%3?*r++=*l:0;}g(long v){f(v,"139ABCDEFGHIJKLMNOPQR");*r=0;r=b;}
void printConversion(long value) {
g(value);
printf("%ld: %s\n", value, r);
}
int main() {
for(long i = 0; i <= 40; i++) {
printConversion(i);
}
printConversion(0x7fffffff);
printConversion(0xffffffffu);
printConversion(0x100000000);
}
Możliwe dalsze, ale destrukcyjne golfa:
-4 bajty: zmień funkcję na jedną, usuwając wskaźnik resetujący g()
.
-5 bajtów: zmusza program wywołujący do zakończenia łańcucha, zwracając ciąg bez zakończenia w buffer
, a koniec łańcucha w result
.