No dia dos seus avós, a discagem de um número de telefone era feita com um seletor rotativo como este:
Para discar cada dígito, coloque o dedo no orifício correspondente, puxe-o até a parada do dedo e solte-o. Um mecanismo fará com que o mostrador volte à sua posição de repouso, e o telefone desconectará e reconectará um circuito um número especificado de vezes, fazendo cliques audíveis.
A discagem do dígito N requer N desses "pulsos", exceto N = 0, que é dez pulsos.
Os telefones rotários têm a propriedade de que dígitos grandes (8, 9, 0) demoram mais para discar do que dígitos pequenos (1, 2, 3). Essa foi uma consideração importante na elaboração de mapas antigos de códigos de área, e por que a cidade de Nova York, com sua densidade populacional (e linha telefônica) pesada, obteve 212 (apenas 5 pulsos), enquanto que 907 (26 pulsos) foram para o Alasca, pouco habitada. Obviamente, tudo isso se tornou irrelevante quando a discagem por tom se tornou popular.
O desafio
Escreva, no menor número de bytes possível, um programa ou função que tenha como entrada uma sequência (ou sequência de caracteres) contendo um número de telefone e emita seu número de pulsos de discagem rotativa. Estes devem ser contados da seguinte forma:
Dígitos
- Os dígitos 1 a 9 contam como esse número de pulsos.
- O dígito 0 conta como 10 pulsos.
Cartas
Observe que os dígitos de 2 a 9 no mostrador têm letras do alfabeto latino associadas a eles. Originalmente, eles eram destinados a trocas nomeadas , mas foram reapropriados para palavras de telefone e para sistemas de entrada de mensagens de texto.
Você deve ter letras nos seus números de telefone, usando a atribuição E.161 de letras para dígitos:
- 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
Você pode assumir que a entrada já foi dobrada em maiúsculas e minúsculas.
Outros personagens
Você deve permitir o uso arbitrário dos caracteres ()+-./
e do espaço como separadores de formatação. Você pode optar por permitir qualquer caractere não alfanumérico para esse fim, se for mais fácil de implementar.
Esses caracteres não contribuem para a contagem de pulsos.
Código de exemplo
Uma tabela e função de pesquisa sem golf no Python:
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)
Exemplo de entrada e saída
911
→ 11867-5309
→ 48713 555 0123
→ 42+1 (212) PE6-5000
→ 571-800-FLOWERS
→ 69PUZZLES
→ 48
+- ()*#.
), assim como as letras são restritas a maiúsculas. Corrija-me se eu estiver errado.*
e#
, que possuem significados especiais em telefones com tom de toque e não podem ser discados em rotativos.Respostas:
05AB1E ,
19181715 bytesExperimente online!
Esta é a primeira resposta para usar π. Por que usar π, você pode perguntar? Bem, as letras estão associadas a 22233344455566677778889999, em ordem. Observe como a maioria dos dígitos se repete 3 vezes, mas 7 se repete 4 vezes. Você poderia dizer que cada dígito se repete (3 + 1/7) vezes, em média. Gostaria de saber se existe algum número que é aproximadamente 3 + 1/7 e leva menos bytes que 22/7…
Isso fornece apenas 4 7s, não 4 9s, portanto ainda precisamos lidar com Z como um caso especial.
fonte
"abcdefghijklmnopqrstuvwxyz"
, mas não para"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
. Eu poderia converter o alfabeto em maiúsculas em vez de converter a entrada em minúscula, mas é o mesmo bytecount.C # (compilador interativo do Visual C #) , 51 bytes
Guardado 1 byte graças a @recursive
Economizou 10 bytes graças à observação de @ ExpiredData que só
() +-/.
estará na entradaExperimente online!
fonte
-10
é~9
, o que deve funcionar em contexto.APL (Dyalog Unicode) , SBCS de 27 bytes
Função de prefixo tácito anônimo.
Experimente online!
(
…)∘⍳
Encontre o ndex * de cada caractere na seguinte string:* elementos que não foram encontrados, obtenha o índice 1 + o índice máximo, ou seja, 11
⎕D
os dígitos:"0123456789"
1⌽
gire ciclicamente um passo para a esquerda;"1234567890"
11|
o restante da divisão, quando dividido por 11 **, fornece 0 para todos os que não sejam dígitos
...
+
adicione isso ao seguinte:'@ADGJMPTW'∘⍸
o ter nterval ɩ ndex * para cada caractere* Portanto, [−∞, "@") fornece 0, ["@", "A") fornece 1, ["A", "D") fornece 2, etc.
+/
soma quefonte
Python 2 , 74 bytes
Experimente online!
Faz alguma aritmética no valor ASCII para cada caractere. A primeira opção verifica letras e a segunda opção verifica números. O esclarecimento de que todos os caracteres de pontuação permitidos na entrada são aqueles com valores ASCII menores que 48 permitem-me simplificar a lógica, mas agora um novo método pode ser melhor.
Python 2 , 84 bytes
Experimente online!
Usa uma string de pesquisa codificada, com cada bloco de 5 caracteres correspondente aos caracteres, fornecendo cada valor começando com 1. Os espaços em branco são preenchidos
x
, o que não pode estar na entrada que está em maiúscula. Felizmente, os caracteres que não aparecem na cadeia produzem-1
o.find
que fornece uma soma de zero.fonte
JavaScript (Node.js) , ...
7669 bytesExperimente online!
-7 obrigado @Arnauld!
Explicação
Todos
[space]().+-/
não são capturados por/\w/g
, portanto, eles não afetarão o total.fonte
Perl 5
-p
,5251 bytes@Grimy recebe crédito por -1
Experimente online!
fonte
/\d/g
deve ser/./g
-1 (sim, ele ainda lida com pontuação corretamente).J , 39 bytes
Experimente online!
Um porto da solução APL da Adám
fonte
Retina 0.8.2 , 34 bytes
Experimente online! O link inclui casos de teste. Explicação:
Converta as letras
WTPMJGDA
nos dígitos9..0
.Embaralhe todas as letras restantes em 1 e repita até que todas as letras tenham sido convertidas em dígitos.
Substitua
0
por,55
pois eles recebem o mesmo número de pulsos para discar.Pegue a soma digital.
fonte
K4 , 44 bytes
Solução:
Exemplos:
Explicação:
Abordagem ingênua, provavelmente bastante jogável. Índice de pesquisa de caracteres, pontuação de pesquisa, soma.
fonte
Perl 6 , 53 bytes
Experimente online!
Multiplica o código ASCII com 0,313 em vez de 1/3 e usa OR bit a bit que arredonda para zero para obter o viés correto .
fonte
C (gcc) ,
94898680 bytesObrigado a roofcat, nwellnhof e Rogem pelas sugestões.
Experimente online!
fonte
c<43U
vez dec-17<26U
Bash , 256 bytes
Você pode substituir as
(( … ))
construçõeslet
por uma contagem de bytes idêntica. Pode haver um bom algoritmo para reduzir as instruções de caso, mas não o encontrou até o momento. Com um pouco de retrabalho, você também pode torná-lo uma função (mas não com o mesmo ou menos bytes, a menos que você possa descontar ofunction fname { … }
topo e a cauda).Experimente online!
Uma solução melhor usando a técnica de caractere de mapa faz uso da
tr
ferramenta:[Bash com tr], 173 bytes
Experimente online!
fonte
while((${#p}))
funciona, economizando três bytes.c=${p:0:1};case c in ([0-9]) ((d+=c?c:10));;
salva outro 16. Comtr -dc 0-9
adicionado ao pipeline tr, você não precisa de uma declaração de caso e a adição pode ser dobrada nawhile
condição com&&
.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
.. os três últimos 9s não são necessários porque tr reutilizará o último caractere de substituição se o segundo argumento for muito curto.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
Geléia ,
3324 bytesExperimente online!
Um link monádico usando uma string como argumento e retornando o número de pulsos. Reescrito inspirado na resposta 05AB1E do @ Grimy, certifique-se de votar neles!
fonte
PowerShell ,
10910287 bytesExperimente online!
EDIT: Usada a idéia do @ mazzy para um comutador regex com alguma formatação de string para converter char -> int -> string e pegar apenas o primeiro 'dígito'
Original:
Eu esperava obter <100 bytes, então continuarei olhando para ver se há mais alguma coisa que eu possa fazer. Provavelmente existe uma maneira de remover a sequência numérica
Desculpe se isso é confuso, pois aninhei matrizes com instruções de indexação booleana, mas -
Explicação:
[char[]]"$args"|%{
lê a entrada convertida como uma seqüência de caracteres e a explode em uma matriz char e inicia um loop for-each, verificando()[$_-gt47]
se alguma()+-./
foi inserida (todas possuem valores de caracteres ascii <48)Nota: O PowerShell aceita
$true
e$false
como1
e0
respectivamente para índices de matrizEntão obtemos
48
os símbolos ou:('22233344455566677778889999'[$_-65],(58,$_)[$_-ne48])[$_-lt64]
As
[$_-lt64]
verificações de um número ou uma letra (todas assumidas em maiúsculas aqui). Se for uma letra,'22233344455566677778889999'[$_-65]
altere para 0-25 para indexar na matriz e gerar o valor do pulso (como um caractere). Se o caractere for um número, veremos:(58,$_)[$_-ne48]
verificando0
e emitindo58
ou apenas o caractere numérico.Em torno de tudo
$a+= ... -=48
inicializa uma variável numérica $ a at0
e adiciona a saída. A saída é o valor ascii char de um número, portanto subtraia48
.Nota: se a entrada era um símbolo, obtemos
$a+=48-48
, efetivamente ignorando-a. Se fosse0
, conseguimos$a+=58-48
obter nossos +10Por fim,
;$a
apenas gera nosso post de valor final para cada loopfonte
=
que sobraram dos meus métodos anteriores de resolver isso, obrigado pela captura! Porém, eu não vi ot*y
antes, você poderia explicar por que isso funciona para explodir a string em uma matriz de caracteres?-f
e[0]
.PowerShell ,
958579 bytesinspirado pela resposta de nwellnhof .
inspirado pela resposta
[0]
de Sinusoid .Experimente online!
Versão desenrolada:
fonte
Stax , 21 bytes
Execute e depure
fonte
Kotlin , 113 bytes
Experimente online!
fonte
Python 3 ,
134123 bytesExperimente online!
-11 bytes graças a @ dan04
fonte
'ADGJMPTWBEHKNQUXCFILNRVYSZ'
, você pode reduzir a sequência de números para'23456789'*3+'79'
.