W czasach dziadków wybieranie numeru telefonu odbywało się za pomocą tarczy obrotowej w następujący sposób:
Aby wybrać każdą cyfrę, włóż palec do odpowiedniego otworu, pociągnij go do oporu i zwolnij. Mechanizm powoduje, że tarcza obraca się z powrotem do pozycji spoczynkowej, a telefon rozłącza i ponownie łączy obwód określoną liczbę razy, słyszalnie klikając.
Wybranie cyfry N wymaga N takich „impulsów”, z wyjątkiem N = 0, czyli dziesięciu impulsów.
Telefony obrotowe mają tę właściwość, że wybieranie dużych cyfr (8, 9, 0) trwa dłużej niż małe cyfry (1, 2, 3). Było to ważne przy opracowywaniu wczesnych map kierunkowych i dlaczego Nowy Jork z gęstą gęstością zaludnienia (i linii telefonicznej) otrzymał 212 (tylko 5 impulsów), podczas gdy 907 (26 impulsów) pojechało na rzadko zamieszkaną Alaskę. Oczywiście wszystko to stało się nieistotne, gdy popularne stało się wybieranie tonowe.
Wyzwanie
Napisz, w jak najmniejszej liczbie bajtów, program lub funkcję, która przyjmuje jako dane wejściowe ciąg znaków (lub sekwencję znaków) zawierający numer telefonu i wysyła liczbę impulsów wybierania obrotowego. Należy je liczyć w następujący sposób:
Cyfry
- Cyfry 1-9 liczą się jako liczba impulsów.
- Cyfra 0 liczy się jako 10 impulsów.
Listy
Zauważ, że cyfry 2-9 na tarczy mają przypisane litery alfabetu łacińskiego. Pierwotnie były one przeznaczone do wymiany nazwanych , ale później zostały ponownie wykorzystane w słowach telefonicznych i systemach wprowadzania wiadomości tekstowych.
Musisz obsługiwać litery w numerach telefonów, używając przypisania liter E.161 do cyfr:
- A, B, C = 2
- D, E, F = 3
- G, H, I = 4
- J, K, L = 5
- M, N, O = 6
- P, Q, R, S = 7
- T, U, V = 8
- W, X, Y, Z = 9
Możesz założyć, że dane wejściowe zostały już złożone na duże lub małe litery.
Inne postaci
Państwo musi umożliwić wykonanie wybranego wykorzystanie znaków ()+-./
i przestrzeń jako separatory formatowania. Państwo może wybrał, aby umożliwić dowolną postać niealfanumeryczny do tego celu, jeśli jest to łatwiejsze do wykonania.
Te postacie nie mają wpływu na liczbę impulsów.
Przykładowy kod
Tabela i funkcja wyszukiwania bez golfa w Pythonie:
PULSES = {
'1': 1,
'2': 2, 'A': 2, 'B': 2, 'C': 2,
'3': 3, 'D': 3, 'E': 3, 'F': 3,
'4': 4, 'G': 4, 'H': 4, 'I': 4,
'5': 5, 'J': 5, 'K': 5, 'L': 5,
'6': 6, 'M': 6, 'N': 6, 'O': 6,
'7': 7, 'P': 7, 'Q': 7, 'R': 7, 'S': 7,
'8': 8, 'T': 8, 'U': 8, 'V': 8,
'9': 9, 'W': 9, 'X': 9, 'Y': 9, 'Z': 9,
'0': 10
}
def pulse_count(phone_num):
return sum(PULSES.get(digit, 0) for digit in phone_num)
Przykładowe wejście i wyjście
911
→ 11867-5309
→ 48713 555 0123
→ 42+1 (212) PE6-5000
→ 571-800-FLOWERS
→ 69PUZZLES
→ 48
+- ()*#.
), podobnie jak litery są ograniczone do wielkich liter. Popraw mnie, jeśli się mylę.*
i#
, które mają specjalne znaczenie w telefonach z wybieraniem tonowym i nie można ich wybierać w telefonach obrotowych.Odpowiedzi:
05AB1E ,
19181715 bajtówWypróbuj online!
To jest pierwsza odpowiedź na użycie π. Po co używać π, możesz zapytać? Cóż, litery są powiązane z 22233344455566677778889999, w kolejności. Zauważ, że większość cyfr powtarza się 3 razy, ale 7 powtarza się 4 razy. Można powiedzieć, że każda cyfra powtarza się (średnio 3 + 1/7) razy. Zastanawiam się, czy jest jakaś liczba w przybliżeniu 3 + 1/7 i zajmuje mniej bajtów niż 22/7…
To daje tylko 4 7, a nie 4 9, więc nadal musimy traktować Z jako specjalny przypadek.
źródło
"abcdefghijklmnopqrstuvwxyz"
, ale nie dla"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
. Mógłbym konwertować alfabet na wielkie litery zamiast konwertować dane wejściowe na małe, ale to ta sama liczba bajtów.C # (interaktywny kompilator Visual C #) , 51 bajtów
Zapisano 1 bajt dzięki @recursive
Zaoszczędzono 10 bajtów dzięki obserwacji @ ExpiredData, że tylko
() +-/.
będzie na wejściuWypróbuj online!
źródło
-10
jest~9
, co powinno działać w kontekście.APL (Dyalog Unicode) , 27 bajtów SBCS
Anonimowa ukryta funkcja prefiksu.
Wypróbuj online!
(
...)∘⍳
znaleźć ɩ ndex * każdego znaku w następujący ciąg:* elementy, które nie zostały znalezione, uzyskać indeks 1 + indeks maksymalnej, czyli 11
⎕D
cyfr:"0123456789"
1⌽
cyklicznie obracaj o jeden krok w lewo;"1234567890"
11|
dzielenie pozostałej części po podzieleniu przez 11 ** daje to 0 dla wszystkich znaków innych niż cyfry
…
+
dodaj to do:'@ADGJMPTW'∘⍸
ɩ nterval ɩ ndex * dla każdego znaku* Więc [-∞, "@") daje 0 [ "@", "A") daje 1, [ "A", "D") daje 2, itd.
+/
Suma żeźródło
Python 2 , 74 bajty
Wypróbuj online!
Wykonuje pewną arytmetykę wartości ASCII dla każdego znaku. Pierwsza opcja sprawdza litery, a druga opcja sprawdza cyfry. Wyjaśnienie, że wszystkie znaki interpunkcyjne dozwolone w danych wejściowych są znakami o wartości ASCII mniejszej niż 48, pozwolę uprościć logikę, ale nowa metoda może być teraz lepsza.
Python 2 , 84 bajtów
Wypróbuj online!
Używa zakodowanego ciągu wyszukiwania, przy czym każdy blok 5 znaków odpowiada znakom podającym każdą wartość rozpoczynającą się od 1. Puste spacje są wypełniane
x
, których nie można wstawić dużymi literami. Na szczęście znaki, które nie pojawiają się w ciągu, dają-1
wynik,.find
który daje sumę zerową.źródło
JavaScript (Node.js) , ...
7669 bajtówWypróbuj online!
-7 dzięki @Arnauld!
Wyjaśnienie
Nie wszystkie
[space]().+-/
są przechwytywane przez/\w/g
, więc nie wpłyną na całość.źródło
Perl 5
-p
,5251 bajtów@Grimy dostaje kredyt za -1
Wypróbuj online!
źródło
/\d/g
powinno być/./g
na -1 (tak, nadal poprawnie interpunkcja).J , 39 bajtów
Wypróbuj online!
Port rozwiązania APL firmy Adám
źródło
Retina 0.8.2 , 34 bajty
Wypróbuj online! Link zawiera przypadki testowe. Wyjaśnienie:
Konwertuj litery
WTPMJGDA
na cyfry9..0
.Przetasuj wszystkie pozostałe litery o 1 i powtarzaj, aż wszystkie litery zostaną zamienione na cyfry.
Wymień
0
się55
jak oni mieć taką samą liczbę impulsów do tarczy.Weź cyfrową sumę.
źródło
K4 , 44 bajty
Rozwiązanie:
Przykłady:
Wyjaśnienie:
Naiwne podejście, prawdopodobnie dość grywalne. Indeks postaci, wynik wyszukiwania, suma.
źródło
Perl 6 , 53 bajtów
Wypróbuj online!
Mnoży kod ASCII przez 0,313 zamiast 1/3 i używa bitowego OR, który zaokrągla do zera, aby uzyskać prawidłowe odchylenie .
źródło
C (gcc) ,
94898680 bajtówPodziękowania dla pułapek, nwellnhof i Rogem za sugestie.
Wypróbuj online!
źródło
c<43U
zamiastc-17<26U
Grzmotnąć , 256 bajtów
Możesz zastąpić
(( … ))
konstrukcjelet
identyczną liczbą bajtów. Może istnieć dobry algorytm do zmniejszania instrukcji case, ale do tej pory go nie znaleziono. Przy odrobinie przeróbki możesz też uczynić ją funkcją (ale nie w takich samych lub mniejszych bajtach, chyba że możesz pominąćfunction fname { … }
górę i ogon).Wypróbuj online!
Lepsze rozwiązanie z wykorzystaniem techniki postaci z mapy korzysta z
tr
narzędzia:[Bash z tr], 173 bajtów
Wypróbuj online!
źródło
while((${#p}))
działa, oszczędzając trzy bajty.c=${p:0:1};case c in ([0-9]) ((d+=c?c:10));;
zapisuje kolejne 16. Potr -dc 0-9
dodaniu do potoku tr w ogóle nie potrzebujesz instrukcji case, a dodatek można złożyć dowhile
stanu za pomocą&&
.read p;p=$(echo $p|tr A-Z 22233344455566677778889999|tr -dc [0-9]);while ((${#p}));do c=${p:0:1}&&((d+=c?c:10));p=${p#?};done;echo $d
p=$(head -1|tr A-Z 22233344455566677778889|tr -dc 0-9);while((${#p}));do((d+=(c=${p:0:1})?c:10));p=${p#?};done;echo $d
.. ostatnie trzy 9 nie są potrzebne, ponieważ tr użyje ostatniego znaku zastępującego, jeśli drugi argument jest zbyt krótki.read p;while((${#p}>0));do case ${p:0:1} in ([1-9])((d+=${p:0:1}));;([0])((d+=10));;([ABC)((d+=2));;([P-S])((d+=7));;([W-Z])((d+=9));;([DEF])((d+=3));;([GHI])((d+=4));;([JKL])((d+=5));;([MNO])((d+=6));;(?)d=$d;esac;p=${p#?};done;echo $d
Galaretka ,
3324 bajtówWypróbuj online!
Łącze monadyczne przyjmujące ciąg za argument i zwracające liczbę impulsów. Przepisane na podstawie odpowiedzi 05AB1E @ Grimy'ego, więc pamiętajcie o ich głosowaniu!
źródło
PowerShell ,
10910287 bajtówWypróbuj online!
EDYCJA: Wykorzystano pomysł @ mazzy na zamianę wyrażenia regularnego z pewnym formatowaniem łańcucha, aby rzutować char -> int -> string i pobierać tylko pierwszą „cyfrę”
Oryginalny:
Miałem nadzieję, że otrzymam <100 bajtów, więc będę dalej na nie patrzeć, aby sprawdzić, czy jest coś jeszcze, co mogę zrobić. Prawdopodobnie istnieje sposób na usunięcie ciągu liczbowego
Przepraszam, jeśli jest to mylące, ponieważ zagnieżdżałem tablice za pomocą instrukcji indeksowania logicznego, ale -
Wyjaśnienie:
[char[]]"$args"|%{
odczytuje dane wejściowe lanego jako ciąg, a następnie eksploduje do tablicy char i rozpoczyna się za-każdej pętli z sprawdzenie()[$_-gt47]
, czy któryś()+-./
został wprowadzony (mają wartości znaków ASCII <48)Uwaga: PowerShell przyjmuje
$true
i$false
jak1
i0
odpowiednio indeksami macierzyNastępnie otrzymujemy albo
48
symbole, albo:('22233344455566677778889999'[$_-65],(58,$_)[$_-ne48])[$_-lt64]
Do
[$_-lt64]
sprawdza numeru lub listu (wszystkie Zakładana kapitału tutaj). Jeśli jest to litera,'22233344455566677778889999'[$_-65]
zmienia ją na 0-25, aby zindeksować tablicę i wyprowadzić wartość impulsu (jako znak). Jeśli znak jest liczbą, zamiast tego patrzymy na:(58,$_)[$_-ne48]
sprawdzanie0
i generowanie58
lub po prostu sam numeryczny znak.Wokół wszystkiego
$a+= ... -=48
inicjuje zmienną numeryczną $ a,0
a następnie dodaje wynik. Dane wyjściowe to wartość ascii char liczby, więc odejmij48
.Uwaga: jeśli wejście było symbolem, otrzymujemy
$a+=48-48
, skutecznie go ignorując. Jeśli tak0
, to rozumiemy$a+=58-48
naszą +10Na koniec
;$a
po prostu wyprowadza naszą końcową wartość po każdej pętliźródło
=
tam, resztki z moich poprzednich metod rozwiązywania tego, dzięki za haczyk! Chociaż nie widziałemt*y
wcześniej, czy możesz wyjaśnić, dlaczego to działa, aby rozbić ciąg znaków na tablicę znaków?-f
i[0]
.PowerShell ,
958579 bajtówzainspirowany odpowiedzią nwellnhof .
zainspirowany
[0]
z odpowiedzią sinusoidy za .Wypróbuj online!
Wersja rozwinięta:
źródło
Stax , 21 bajtów
Uruchom i debuguj
źródło
Kotlin , 113 bajtów
Wypróbuj online!
źródło
Python 3 ,
134123 bajtówWypróbuj online!
-11 bajtów dzięki @ dan04
źródło
'ADGJMPTWBEHKNQUXCFILNRVYSZ'
, możesz zmniejszyć ciąg cyfr do'23456789'*3+'79'
.