Wprowadzenie
W przeszłości mieliśmy tutaj kilka podstawowych wyzwań związanych z konwersją, ale niewiele z nich zaprojektowano tak, aby poradzić sobie z liczbami o dowolnej długości (to znaczy liczbami, które są na tyle długie, że przekraczają typ danych liczb całkowitych). skomplikowane. Jestem ciekawy, jak można uzyskać taką zmianę kodu podstawowego.
Wyzwanie
Napisz program lub funkcję w wybranym języku, który może przekonwertować ciąg jednej bazy na ciąg innej bazy. Dane wejściowe powinny być liczbą do konwersji (ciąg znaków), z bazy (liczba bazy 10), na bazę (liczba bazy 10) oraz zestaw znaków (łańcuch znaków). Dane wyjściowe powinny być konwertowaną liczbą (ciągiem).
Niektóre dalsze szczegóły i zasady są następujące:
- Liczba do konwersji będzie nieujemną liczbą całkowitą (ponieważ
-
i.
może znajdować się w zestawie znaków). Podobnie będzie wynik. - Zera wiodące (pierwszy znak w zestawie znaków) powinny zostać przycięte. Jeśli wynik wynosi zero, powinna pozostać pojedyncza cyfra zero.
- Minimalny obsługiwany zakres podstawowy wynosi od 2 do 95, składający się z drukowalnych znaków ascii.
- Dane wejściowe dla liczby do konwersji, zestaw znaków i dane wyjściowe muszą być typu danych ciągu. Podstawy muszą być typu danych liczb całkowitych typu base-10 (lub liczby całkowite zmiennoprzecinkowe).
- Długość ciągu liczb wejściowych może być bardzo duża. Trudno oszacować rozsądne minimum, ale spodziewaj się, że będzie w stanie obsłużyć co najmniej 1000 znaków i wypełnić 100 znaków w mniej niż 10 sekund na przyzwoitej maszynie (bardzo hojny dla tego rodzaju problemu, ale nie chcę prędkość, na której należy się skupić).
- Nie można używać wbudowanych funkcji zmiany bazy.
- Zestaw znaków może być wprowadzany w dowolnym układzie, nie tylko typowym 0-9a-z ... itd.
- Załóż, że zostaną użyte tylko prawidłowe dane wejściowe. Nie martw się obsługą błędów.
Zwycięzca zostanie określony na podstawie najkrótszego kodu spełniającego kryteria. Zostaną oni wybrani w ciągu co najmniej 7 dni bazowych-10, lub jeśli / kiedy będzie wystarczająco dużo zgłoszeń. W przypadku remisu zwycięży kod, który działa szybciej. Jeśli wystarczająco blisko prędkości / wydajności, odpowiedź, która nadeszła wcześniej, wygrywa.
Przykłady
Oto kilka przykładów danych wejściowych i wyjściowych, które Twój kod powinien obsługiwać:
F("1010101", 2, 10, "0123456789")
> 85
F("0001010101", 2, 10, "0123456789")
> 85
F("85", 10, 2, "0123456789")
> 1010101
F("1010101", 10, 2, "0123456789")
> 11110110100110110101
F("bababab", 2, 10, "abcdefghij")
> if
F("10", 3, 2, "0123456789")
> 11
F("<('.'<)(v'.'v)(>'.'>)(^'.'^)", 31, 2, "~!@#$%^v&*()_+-=`[]{}|';:,./<>? ")
> !!~~~~~~~!!!~!~~!!!!!!!!!~~!!~!!!!!!~~!~!~!!!~!~!~!!~~!!!~!~~!!~!!~~!~!!~~!!~!~!!!~~~~!!!!!!!!!!!!~!!~!~!~~~~!~~~~!~~~~~!~~!!~~~!~!~!!!~!~~
F("~~~~~~~~~~", 31, 2, "~!@#$%^v&*()_+-=`[]{}|';:,./<>? ")
> ~
F("9876543210123456789", 10, 36, "0123456789abcdefghijklmnopqrstuvwxyz")
> 231ceddo6msr9
F("ALLYOURBASEAREBELONGTOUS", 62, 10, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
> 6173180047113843154028210391227718305282902
F("howmuchwoodcouldawoodchuckchuckifawoodchuckcouldchuckwood", 36, 95, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+=[{]}\\|;:'\",<.>/? ")
> o3K9e(r_lgal0$;?w0[`<$n~</SUk(r#9W@."0&}_2?[n
F("1100111100011010101010101011001111011010101101001111101000000001010010100101111110000010001001111100000001011000000001001101110101", 2, 95, "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ~`!@#$%^&*()_-+=[{]}\\|;:'\",<.>/? ")
> this is much shorter
You cannot use built in change-of-base functions to convert the entire input string/number at once
? W szczególności, czy mogę użyć wbudowanego do konwersji danych wejściowych na bazę pośrednią? Czy mogę użyć wbudowanego programu do konwersji na bazę docelową? Czy coś podobnego convert input with canonical form for given base; convert to base 10; convert to target base; convert back to specified character set with string replacement
?