Napisz funkcję, która przy pierwszych 12 cyfrach kodu ISBN-13 obliczy cały ISBN poprzez obliczenie i dodanie odpowiedniej cyfry kontrolnej.
Dane wejściowe twojej funkcji to ciąg zawierający pierwsze 12 cyfr numeru ISBN. Jego wyjściem jest ciąg znaków zawierający wszystkie 13 cyfr.
Specyfikacja formalna
Napisz funkcję, która otrzyma ciąg s składający się w całości z dokładnie 12 cyfr dziesiętnych (i żadnych innych znaków), zwraca ciąg t o następujących właściwościach:
- t składa się z dokładnie 13 cyfr dziesiętnych (i żadnych innych znaków);
- s jest prefiksem t ;
- suma wszystkich cyfr w pozycjach nieparzystych wt (tj. pierwsza, trzecia, piąta itd.), plus trzykrotna suma wszystkich cyfr w pozycjach parzystych wt (tj. druga, czwarta, szósta itd.), jest liczbą wielokrotność 10.
Przykład / przypadek testowy
Wkład
978030640615
Wydajność
9780306406157
Warunek zwycięstwa
Jako wyzwanie do gry w golfa wygrywa najkrótsza odpowiedź.
Odpowiedzi:
Golfscript - 25 znaków
Cała wersja programu to tylko 19 znaków
Zajrzyj tu później do analizy później. Tymczasem sprawdź moją starą, nieinspirowaną odpowiedź
Golfscript - 32 znaki
Podobne do obliczania liczby Luhna
Analiza dla 978030640615
źródło
{
i ostatnich trzech znaków;}:f
. Zastanawiam się, czy to samo można zrobić dla pierwszego rozwiązania ...:f
(tak, wiem, że funkcje były wtedy powszechnie nazywane).Python - 44 znaki
Python - 53 znaki
źródło
Haskell - 54 znaki
Wymaga to obsługi równoległego przetwarzania list , która jest obsługiwana przez GHC (z
-XParallelListComp
flagą) i Uściski (z-98
flagą).źródło
[1,3]
przez[9,7]
i usunąć-
który oszczędza bajt :)APL (27 znaków)
Używam Dyalog APL jako mojego tłumacza. Oto krótkie wyjaśnienie, głównie od prawej do lewej (w ramach definicji funkcji
F←{ ... }
):⍎¨⍵
: Wykonaj / oceń (⍎
) każdy (¨
) znak podany we właściwym argumencie (⍵
).(12⍴1 3)
: Przekształć (⍴
) wektor1 3
w wektor12
-elementowy (powtarzając, aby wypełnić luki).+.×
: Weź iloczyn iloczynu (+.×
) jego lewego argumentu ((12⍴1 3)
) i prawego argumentu (⍎¨⍵
).10-
: Odejmij od 10.10|
: Znajdź resztę po podzieleniu według10
.⍕
: Sformatuj liczbę (tzn. Podaj reprezentację znaków).⍵,
: Dołącz (,
) naszą cyfrę obliczeniową do właściwego argumentu.źródło
PHP -
868582 znakówPonowne formatowanie i objaśnienie:
źródło
Windows PowerShell, 57
źródło
Haskell,
787166 znakówźródło
Ruby -
7365 znakówźródło
"\\1"
->'\1'
?f=->s{...}
. Zaoszczędź 6 znaków. Napisz takżes<<(...).to_s
zamiast dodawać 48 i użyjFixnum#chr
.C # (94 znaków)
Z podziałami / białymi znakami dla czytelności:
Testowane na kilku numerach ISBN z książek na mojej półce, więc wiem, że to działa!
źródło
Python -
91, 89źródło
for
(iin
trzecim) w interpretacji listy, o ile można je podzielić przez analizator składni (nie używając nazwy zmiennej). -2 znaki tam.Perl, 53 znaki
źródło
C # -
8977 znakówSformatowane dla czytelności:
Nie mnożymy przez jeden lub trzy, po prostu dodajemy wszystko, a dodatkowo dodajemy wszystkie znaki o równej pozycji jeszcze raz, pomnożone przez dwa.
9992 jest wystarczająco duży, aby suma wszystkich znaków ASCII była mniejsza (abyśmy mogli modyfikować o 10 i mieć pewność, że wynik jest dodatni, nie trzeba dwukrotnie modyfikować o 10), i nie można go podzielić przez zero, ponieważ dodajemy wszystkie te dodatkowe 2 * 12 * 48 (dwanaście cyfr ASCII, ważonych 1 i 3) == 1152, co pozwala nam zaoszczędzić jeden dodatkowy znak (zamiast dwukrotnego odejmowania 48, odejmujemy 0 tylko w celu konwersji z char na int, ale zamiast 990 musimy napisać 9992).
Ale z drugiej strony, choć znacznie mniej piękne ;-), to oldschoolowe rozwiązanie zapewnia nam 80 znaków (ale jest to prawie kompatybilne z C):
źródło
J -
554538na przykład
stara droga:
źródło
(i.12)(".@{)y
można zastąpić"."0 y
Ruby - 80 znaków
źródło
dc, 44 znaki
Wywołaj jako
lIx
np .:źródło
Q, 36 znaków
źródło
D - 97 znaków
Bardziej czytelnie sformatowany:
Szczegółowość operatora rzutowania D zdecydowanie utrudnia jednak pisanie obsesyjnie krótkiego kodu.
źródło
Java - 161 znaków :(
źródło
Q (44 znaki)
źródło
Scala 84
Testowanie:
Wynik:
źródło
C,
8079 znakówFunkcja modyfikuje ciąg w miejscu, ale zwraca oryginalny wskaźnik ciągu, aby spełnić wymagania dotyczące problemu.
Kilka wyjaśnień: Zamiast odejmować 48 (wartość cyfry ASCII
0
) od każdego znaku wejściowego, akumulators
jest inicjalizowany, tak że ma moduł 10 równy 48 + 3 * 48 + 48 + 3 * 48 ... + 48 + 3 * 48 = 24 * 48 = 1152. Kroku10-sum
można uniknąć, gromadzącs
przez odejmowanie zamiast dodawania. Jednak operator modułu%
w C nie dałby użytecznego wyniku, gdybys
był ujemny, więc zamiast używaćs-=
mnożników 3 i 1 są zastępowane odpowiednio przez -3 = 7 modulo 10 i -1 = 9 modulo 10.Uprząż testowa:
źródło
Groovy
75, 66 znakówposługiwać się:
źródło
APL (25)
źródło
Perl 6 , 29 bajtów
Wypróbuj online!
źródło
Python 2 ,
7876 bajtówWypróbuj online!
Bierze ciąg jako argument.
Wyjaśnienie:
Za pomocą notacji wycinka python konwertuje ciąg znaków na listę par znaków. („978030640615” -> [(„9”, „7”), („8”, „0”), („3”, „0”), („6”, „4”), („0 „,„ 6 ”), („ 1 ”,„ 5 ”)])
Dla tej listy par konwertuje każdy element na liczbę całkowitą i zwraca wartość + 3b.
Podsumowuje wszystkie wyniki.
Pobiera sumę modulo 10, LUB 10, jeśli reszta to 0. (Zapobiega to końcowej cyfrze równej 10 zamiast 0.)
Usuwa resztę z 10, aby uzyskać cyfrę kontrolną.
Konwertuje obliczoną cyfrę kontrolną na ciąg znaków za pomocą przestarzałego wyrażenia wstecznego.
Zwraca oryginalną liczbę plus obliczoną cyfrę kontrolną.
Edytować:
Zaoszczędzono 2 bajki, usuwając spacje (dzięki Jo King !).
źródło
for
ior
APL (Dyalog Unicode) , 18 bajtów SBCS
Anonimowa funkcja prefiksu ukrytego, przyjmująca ciąg znaków jako argument. Korzystanie z podejścia Bubblera .
Wypróbuj online!
≢
długość argumentu (12)9 7⍴⍨
cyklicznie przekształcaj się[9,7]
do tej długości+.×
iloczyn następujących produktów:⍎¨
`oceń każdą postać10|
mod-10 tego,∘⍕
poprzedzić następujące jego uszeregowanie:⊢
niezmodyfikowany argumentźródło
dc , 25 bajtów
Wypróbuj online!
Wiem, że jest tutaj odpowiedź dc, ale 25 <44, więc myślę, że czuję się z tym 19 bajtów. Ta wykorzystuje fakt, że
8+9^z
jest równoważna albo-3
czy-1
mod 10 w zależności od tego, czy z jest parzyste, czy nieparzyste. Używam więcA~
do dzielenia liczby na cyfry na stosie, ale gdy buduję stos, mnożę każdą cyfrę przez8+9^z
gdzie z oznacza bieżący rozmiar stosu. Następnie dodaję je wszystkie w miarę rozwijania się stosu funkcji i wypisuję ostatnią cyfrę.źródło
MATLAB - 82 znaki
źródło
R, 147 znaków
Stosowanie:
źródło
J, 25
źródło