Cuente los pulsos de marcación giratoria en un número de teléfono (incluidas letras)

34

En los días de tus abuelos, marcar un número de teléfono se hacía con un dial giratorio como este:

Para marcar cada dígito, coloque el dedo en el orificio correspondiente, tírelo hasta el tope y suéltelo. Un mecanismo hará que el dial gire nuevamente a su posición de reposo, y el teléfono se desconectará y volverá a conectar un circuito un número específico de veces, haciendo clics audibles.

Marcar el dígito N requiere N de tales "pulsos", excepto por N = 0 que es diez pulsos.

Los teléfonos rotativos tienen la propiedad de que los dígitos grandes (8, 9, 0) tardan más en marcarse que los dígitos pequeños (1, 2, 3). Esta fue una consideración importante en la elaboración de mapas de códigos de área tempranos, y por qué la ciudad de Nueva York con su densidad de población (y línea telefónica) recibió 212 (solo 5 pulsos), mientras que 907 (26 pulsos) fueron a Alaska escasamente habitada. Por supuesto, todo esto se volvió irrelevante cuando la marcación por tonos se hizo popular.

El reto

Escriba, en la menor cantidad de bytes posible, un programa o función que tome como entrada una cadena (o secuencia de caracteres) que contenga un número de teléfono y genere su número de pulsos de marcación giratoria. Estos deben contarse de la siguiente manera:

Dígitos

  • Los dígitos 1-9 cuentan como ese número de pulsos.
  • El dígito 0 cuenta como 10 pulsos.

Letras

Tenga en cuenta que los dígitos 2-9 en el dial tienen letras del alfabeto latino asociado con ellos. Originalmente estaban destinados a intercambios con nombre , pero posteriormente se reapropiaron para palabras telefónicas y para sistemas de entrada de mensajes de texto.

Debe admitir tener letras en sus números de teléfono, utilizando la asignación E.161 de letras a 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

Puede suponer que la entrada ya se ha plegado a mayúsculas o minúsculas.

Otros personajes

Usted debe permitir el uso arbitrario de los personajes ()+-./y el espacio como separadores de formato. Usted puede elegir para permitir que cualquier carácter no alfanumérico para este propósito, si es más fácil de implementar.

Estos caracteres no contribuyen al conteo de pulsos.

Código de ejemplo

Una tabla y función de búsqueda sin golf en 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)

Ejemplo de entrada y salida

  • 911 → 11
  • 867-5309 → 48
  • 713 555 0123 → 42
  • +1 (212) PE6-5000 → 57
  • 1-800-FLOWERS → 69
  • PUZZLES → 48
dan04
fuente
Supongo que la puntuación y los espacios ASCII arbitrarios están restringidos a los que se usan normalmente para los números de teléfono ( +- ()*#.) al igual que las letras están en mayúsculas. Corrígeme si me equivoco.
Adám
1
@ Adám: he restringido los signos de puntuación requeridos a unos pocos separadores comunes. Deliberadamente no incluye *y #, que tienen significados especiales en los teléfonos de tonos y no se pueden marcar en los rotativos.
dan04
1
¿Podemos usar entradas en minúsculas en lugar de mayúsculas? ¿Podemos tomar una serie de caracteres en lugar de una cadena?
Grimmy
1
Soy un viajero del tiempo! Soy un viajero del tiempo! Soy un viajero del tiempo! Ya que definitivamente usé teléfonos como este cuando era un niño, ¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡MÍ ES MI PROPIO ABUELO !!!!!!! Lo que en realidad es bastante asqueroso cuando lo pienso. Bleah !!!
Bob Jarvis - Restablece a Monica
3
Soy el abuelo. He utilizado los teléfonos de este tipo en la década de 1950. Y cuando me mudé a una ciudad en una zona rural, descubrí que la compañía telefónica no ofrece el servicio de marcación por tonos. Esto fue en 1985! ¡En serio! Mi abuela tenía un teléfono en la sala que tenía un gancho y una manivela. Usted tomó el auricular descolgado, y giró la manivela para obtener una telefonista. Ella tuvo que sustituirlo cuando la marcación directa a distancia se creó.
Walter Mitty

Respuestas:

25

05AB1E , 19 18 17 15 bytes

AÁ0ªā6+žq÷9š‡þO

Pruébalo en línea!

Esta es la primera respuesta para usar π. ¿Por qué usar π, podrías preguntar? Bueno, las cartas están asociados con 22233344455566677778889999, en orden. Observe cómo la mayoría de los dígitos se repiten 3 veces, sino hasta 7 repeticiones 4 veces. Se puede decir que cada uno repite dígito (3 + 1/7) veces, en promedio. Me pregunto si hay cualquier cantidad que es aproximadamente un 3 + 1/7 y tiene un menor número de bytes de 22/7 ...

Esto sólo da 4 7s, no es un 4 9s, por lo que todavía necesita manejar Z como un caso especial.

A               # alphabet (abcdefghijklmnopqrstuvwxyz)
 Á              # rotate right (zabcdefghijklmnopqrstuvwxy)
  0ª            # append 0 (zabcdefghijklmnopqrstuvwxy0)

ā6+             # range [7..33]
   žq÷          # divide by π (22233344455566677778889991010)
      9š        # prepend 9 (922233344455566677778889991010)

‡               # transliterate the implicit input with the two lists above
                # this replaces z → 9, a → 2, … y → 9, 0 → 10
 þ              # remove all non-digits
  O             # sum
Mugriento
fuente
¿Por qué minúsculas en lugar de mayúsculas?
dan04
1
@ dan04 porque 05AB1E tiene una función integrada para empujar "abcdefghijklmnopqrstuvwxyz", pero no para "ABCDEFGHIJKLMNOPQRSTUVWXYZ". Podría convertir el alfabeto a mayúsculas en lugar de convertir la entrada a minúsculas, pero ese es el mismo bytecount.
Grimmy
1
He editado la pregunta para que tus dos primeros comandos sean innecesarios.
dan04
3
@Jonah Comencé con la idea de dividir un rango por una constante para obtener la secuencia deseada, luego, mientras buscaba la mejor manera de expresar "un poco más de 3" en 05AB1E, recordé que pi era una función incorporada.
Grimmy
2
+1 por uso de pi
Draconis
9

C # (compilador interactivo de Visual C #) , 51 bytes

n=>n.Sum(x=>x>64?(x-59-x/83-x/90)/3:x>47?1-~x%~9:0)

Guardado 1 byte gracias a @recursive

Se guardaron 10 bytes gracias a la observación de @ ExpiredData que solo () +-/.estará en la entrada

Pruébalo en línea!

n =>                     // Function taking input as string
  n.Sum(x =>             // Map each value 'x' through the following
    x>64 ?               //   If 'x' is an uppercase letter
      (x-59-x/83-x/90)/3 //     Take each char's ASCII value subtracted by 59, and subtract
                         //     one if the char is 'S' and one if the char is 'Z'
    : x>47 ?             //   Else if the char is a digit
      1-~x%~9            //   Take 1 - (-x - 1) % -10 (Maps 0 to 10, and 1-9 to themselves
    : 0                  //   Else, 0
  )                      // And sum it all up, then return it
Encarnación de la ignorancia
fuente
44
-10es decir ~9, que debería funcionar en contexto.
recursivo
@recursive Eso es inteligente, gracias
Encarnación de la ignorancia
1
La comprobación x <91 es redundante ya que la entrada solo consistirá en () + -. / la tecla de espacio y los números que son todos <64, por lo tanto, podemos determinar si el carácter está en mayúscula simplemente comprobando x> 64 (entonces -5 bytes)
Datos vencidos
Lo mismo ocurre con la verificación x <58, ya que nada en el rango 58-64 estará en la entrada
Datos
51 bytes
Datos vencidos
5

APL (Dyalog Unicode) , 27 bytes SBCS de

Función de prefijo tácito anónimo.

+/'@ADGJMPTW'∘⍸+11|(1⌽⎕D)∘⍳

Pruébalo en línea!

()∘⍳ Encuentre el ɩ ndex * de cada carácter en la siguiente cadena:
  * elementos que no se encuentran, obtenga el índice 1 + el índice máximo, es decir, 11
⎕D  dígitos:"0123456789"

1⌽ gire cíclicamente un paso hacia la izquierda; "1234567890"

11| resto de la división cuando se divide por 11 *
  * esto da 0 para todos los no-dígitos
...+  agregue eso a lo siguiente:

'@ADGJMPTW'∘⍸ el ter nterval ɩ ndex * para cada carácter
  * Entonces [−∞, "@") da 0, ["@", "A") da 1, ["A", "D") da 2, etc.
+/  suma que

Adán
fuente
5

Python 2 , 74 bytes

lambda s:sum([(n-59-n/83-n/90)/3,1-~n%~9][n<58]for n in map(ord,s)if n>47)

Pruébalo en línea!

Hace algo de aritmética en el valor ASCII para cada carácter. La primera opción busca letras y la segunda opción busca números. La aclaración de que todos los caracteres de puntuación permitidos en la entrada son aquellos con valores ASCII inferiores a 48 me permite simplificar la lógica, pero un nuevo método podría ser mejor.

Python 2 , 84 bytes

lambda s:sum(1+'1xxxx2ABCx3DEFx4GHIx5JKLx6MNOx7PQRS8TUVx9WXYZ0'.find(c)/5for c in s)

Pruébalo en línea!

Utiliza una cadena de búsqueda codificada, con cada bloque de 5 caracteres correspondiente a los caracteres que dan cada valor comenzando con 1. Los espacios en blanco se rellenan con x, que no pueden estar en la entrada que está en mayúscula. Afortunadamente, los caracteres que no aparecen en la cadena producen -1el .findque da un sumando de cero.

xnor
fuente
5

JavaScript (Node.js) , ... 76 69 bytes

s=>s.replace(/\w/g,q=>w+=1/q?+q||10:parseInt(q,35)*.32-1|0||9,w=0)&&w

Pruébalo en línea!

-7 gracias @Arnauld!

Explicación

 q |     1/q     |  +q  | parseInt(q,35)*.32 | parseInt(q,35)*.32-1|0 | Output
---+-------------+------+--------------------+------------------------+--------
 0 | Infinity(T) | 0(F) |         N/A        |           N/A          |   10
 1 |  1.0000(T)  | 1(T) |         N/A        |           N/A          |    1
 2 |  0.5000(T)  | 2(T) |         N/A        |           N/A          |    2
 3 |  0.3333(T)  | 3(T) |         N/A        |           N/A          |    3
 4 |  0.2500(T)  | 4(T) |         N/A        |           N/A          |    4
 5 |  0.2000(T)  | 5(T) |         N/A        |           N/A          |    5
 6 |  0.1666(T)  | 6(T) |         N/A        |           N/A          |    6
 7 |  0.1428(T)  | 7(T) |         N/A        |           N/A          |    7
 8 |  0.1250(T)  | 8(T) |         N/A        |           N/A          |    8
 9 |  0.1111(T)  | 9(T) |         N/A        |           N/A          |    9
 A |    NaN(F)   |  N/A |        3.20        |          2(T)          |    2
 B |    NaN(F)   |  N/A |        3.52        |          2(T)          |    2
 C |    NaN(F)   |  N/A |        3.84        |          2(T)          |    2
 D |    NaN(F)   |  N/A |        4.16        |          3(T)          |    3
 E |    NaN(F)   |  N/A |        4.48        |          3(T)          |    3
 F |    NaN(F)   |  N/A |        4.80        |          3(T)          |    3
 G |    NaN(F)   |  N/A |        5.12        |          4(T)          |    4
 H |    NaN(F)   |  N/A |        5.44        |          4(T)          |    4
 I |    NaN(F)   |  N/A |        5.76        |          4(T)          |    4
 J |    NaN(F)   |  N/A |        6.08        |          5(T)          |    5
 K |    NaN(F)   |  N/A |        6.40        |          5(T)          |    5
 L |    NaN(F)   |  N/A |        6.72        |          5(T)          |    5
 M |    NaN(F)   |  N/A |        7.04        |          6(T)          |    6
 N |    NaN(F)   |  N/A |        7.36        |          6(T)          |    6
 O |    NaN(F)   |  N/A |        7.68        |          6(T)          |    6
 P |    NaN(F)   |  N/A |        8.00        |          7(T)          |    7
 Q |    NaN(F)   |  N/A |        8.32        |          7(T)          |    7
 R |    NaN(F)   |  N/A |        8.64        |          7(T)          |    7
 S |    NaN(F)   |  N/A |        8.96        |          7(T)          |    7
 T |    NaN(F)   |  N/A |        9.28        |          8(T)          |    8
 U |    NaN(F)   |  N/A |        9.60        |          8(T)          |    8
 V |    NaN(F)   |  N/A |        9.92        |          8(T)          |    8
 W |    NaN(F)   |  N/A |       10.24        |          9(T)          |    9
 X |    NaN(F)   |  N/A |       10.56        |          9(T)          |    9
 Y |    NaN(F)   |  N/A |       10.88        |          9(T)          |    9
 Z |    NaN(F)   |  N/A |         NaN        |          0(F)          |    9

Todos [space]().+-/no son capturados por /\w/g, por lo que no afectarán el total.

Shieru Asakoto
fuente
5

Perl 5 -p , 52 51 bytes

@Grimy obtiene crédito por -1

y/A-Z/22233344455566677778889/;map$\+=$_||10,/./g}{

Pruébalo en línea!

Xcali
fuente
/\d/gdebe ser /./gpara -1 (sí, todavía maneja la puntuación correctamente).
Grimmy
4

Retina 0.8.2 , 34 bytes

T`WTPMJGDA`Rd
}T`L`2L
0
55
\d
$*
1

Pruébalo en línea! El enlace incluye casos de prueba. Explicación:

T`WTPMJGDA`Rd

Convierte las letras WTPMJGDAa los dígitos 9..0.

}T`L`2L

Mezcle todas las letras restantes hacia abajo en 1 y repita hasta que todas las letras se hayan convertido a dígitos.

0
55

Reemplace 0con 55ya que toman el mismo número de pulsos para marcar.

\d
$*
1

Toma la suma digital.

Neil
fuente
3

K4 , 44 bytes

Solución:

+/(1+(1+&(5#3),4 3 4),!10)(.Q.A,1_.Q.n,"0")?

Ejemplos:

q)k)+/(1+(1+&(5#3),4 3 4),!10)(.Q.A,1_.Q.n,"0")?"911"
11
q)k)+/(1+(1+&(5#3),4 3 4),!10)(.Q.A,1_.Q.n,"0")?"867-5309"
48
q)k)+/(1+(1+&(5#3),4 3 4),!10)(.Q.A,1_.Q.n,"0")?"+1 (212) PE6-5000"
57
q)k)+/(1+(1+&(5#3),4 3 4),!10)(.Q.A,1_.Q.n,"0")?"1-800-FLOWERS"
69

Explicación:

Enfoque ingenuo, probablemente bastante golfable. Índice de búsqueda del personaje, puntaje de búsqueda, suma.

+/(1+(1+&(5#3),4 3 4),!10)(.Q.A,1_.Q.n,"0")? / the solution
                                           ? / lookup
                          (               )  / do this together
                                       "0"   / string "0"
                                      ,      / join with
                                  .Q.n       / string "0123456789"
                                1_           / drop first
                               ,             / join with
                           .Q.A              / "A..Z"
  (                      )                   / do this together
                      !10                    / range 0..9
                     ,                       / join with
     (              )                        / do this together
               4 3 4                         / list (4;3;4)
              ,                              / join with
         (5#3)                               / list (3;3;3;3;3)
        &                                    / where, creates list 0 0 0 1 1 1 2 2 etc
      1+                                     / add 1
   1+                                        / add 1
+/                                           / sum up
callejero
fuente
3

C (gcc) , 94 89 86 80 bytes

Gracias a ceilingcat, nwellnhof y Rogem por las sugerencias.

c;f(char*s){c=*s-48;s=*s?(c<10U?c?c:10:c-17<26U?(c-11-c/35-c/42)/3:0)+f(s+1):0;}

Pruébalo en línea!

ErikF
fuente
80 bytes utilizando recursividad en lugar de un bucle.
Sugerir en c<43Ulugar dec-17<26U
ceilingcat
2

Bash , 256 bytes

Puede reemplazar las (( … ))construcciones con letun conteo de bytes idéntico. Puede haber un buen algoritmo para reducir las declaraciones de casos, pero no lo hemos encontrado hasta ahora. Con un poco de trabajo adicional, también podría convertirlo en una función (pero no en los mismos bytes o menos, a menos que pueda descontar elfunction fname { … } parte superior y la cola).

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

Pruébalo en línea!

Una mejor solución usando la técnica del mapa de caracteres hace uso del tr herramienta:

[Bash con tr], 173 bytes

read p;p=$(echo $p|tr A-Z 22233344455566677778889999);while ((${#p}>0));do case ${p:0:1} in ([1-9]) ((d+=${p:0:1}));; ([0]) ((d+=10));; (?) d=$d; esac;p=${p#?}; done;echo $d

Pruébalo en línea!

PJF
fuente
Un algoritmo que me perdí, por supuesto, es hacer un reemplazo de cadena / traducción en AZ. Esto seria bueno. Enmendaré lo anterior para adaptarlo.
PJF
while((${#p}))funciona, ahorrando tres bytes. c=${p:0:1};case c in ([0-9]) ((d+=c?c:10));;ahorra otros 16. Con el tr -dc 0-9agregado a la tubería tr no necesita una declaración de caso en absoluto y la adición se puede plegar en la whilecondición con &&.
Oh Dios mío,
Gracias OMG No suelo usar asignaciones ternarias, así que me perdí eso. El uso interesante de eliminar complemento también (pero eso supone que mi solución ignora cualquier otro personaje). He logrado reducirlo a 133 bytes como en: 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
PJF
1
118: 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.. los últimos tres 9 no son necesarios porque tr reutilizará el último carácter de reemplazo si el segundo argumento es demasiado corto.
Oh Dios mío
1
El primer ejemplo se puede reducir de 256 a 236 eliminando algunos espacios innecesarios. 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
Steve
2

PowerShell , 109 102 87 bytes

$(switch -r($args|% t*y){\d{$_}[A-Y]{("{0}"-f(.313*$_-18))[0]}[Z]{9}0{10}})-join'+'|iex

Pruébalo en línea!

EDITAR: Usé la idea de @ mazzy para un cambio de expresiones regulares con algún formato de cadena para emitir char -> int -> cadena y tomar solo el primer 'dígito'

Original:

[char[]]"$args"|%{$a+=(48,(('22233344455566677778889999')[$_-65],(58,$_)[$_-ne48])[$_-lt64])[$_-gt47]-=48};$a

Esperaba obtener <100 bytes, así que lo seguiré viendo para ver si hay algo más que pueda hacer. Probablemente hay una manera de eliminar la cadena de números

Lo siento si esto es confuso ya que anidé matrices con sentencias de indexación booleanas pero -

Explicación:

[char[]]"$args"|%{lee la entrada convertida como una cadena y luego la explota en una matriz de caracteres y comienza un bucle for-each con la comprobación ()[$_-gt47]para ver si ()+-./se ingresó (todos tienen valores de caracteres ascii <48)
Nota: Powershell acepta $truey $falsecomo1 y0 respectivamente para los índices de matriz

Luego obtenemos 48los símbolos o:
('22233344455566677778889999'[$_-65],(58,$_)[$_-ne48])[$_-lt64]

Los [$_-lt64]cheques para un número o una letra (todo el capital asumido aquí). Si es una letra, '22233344455566677778889999'[$_-65]cámbiela a 0-25 para indexarla en la matriz y generar el valor del pulso (como un carácter). Si el carácter es un número, en cambio miramos: (58,$_)[$_-ne48]verificar 0y generar58 o solo el carácter numérico en sí.

Alrededor de todo, se $a+= ... -=48inicializa una variable numérica $ a at 0y luego se agrega la salida. La salida es el valor ascii char de un número, así que reste48 .

Nota: si la entrada fue un símbolo, obtenemos $a+=48-48, ignorándolo efectivamente. Si fuera así 0, obtenemos$a+=58-48 obtendremos nuestro +10

Por último, ;$asolo muestra nuestro valor final para cada ciclo

Sinusoide
fuente
podrías ahorrar algunos bytes. ¡ Pruébalo en línea!
mazzy
Ah, sí, tenía algunos paréntesis adicionales y los =restos de mis métodos anteriores para resolver esto, ¡gracias por la captura! Sin embargo, no he visto lo t*yanterior, ¿podría explicar por qué funciona explotar la cadena en una matriz de caracteres?
Sinusoide
para obtener '<100 bytes': ¡ Pruébelo en línea! :)
mazzy
buena idea con -fy [0].
mazzy
2

PowerShell , 95 85 79 bytes

inspirado en la respuesta de nwellnhof .

inspirado en la respuesta[0] de Sinusoid .

$(switch -r($args|% t*y){\d{$_}0{10}[A-Y]{"$(.313*$_-18)"[0]}Z{9}})-join'+'|iex

Pruébalo en línea!

Versión desenrollada:

$(
    switch -r($args|% toCharArray){
        \d    {$_}
        0     {10}
        [A-Y] {"$(.313*$_-18)"[0]}
        Z     {9}
    }
)-join '+'|Invoke-Expression
key .313*$_-18 "$(...)"[0]
--- ---------- -----------
  A      2.345 2
  B      2.658 2
  C      2.971 2
  D      3.284 3
  E      3.597 3
  F      3.910 3
  G      4.223 4
  H      4.536 4
  I      4.849 4
  J      5.162 5
  K      5.475 5
  L      5.788 5
  M      6.101 6
  N      6.414 6
  O      6.727 6
  P      7.040 7
  Q      7.353 7
  R      7.666 7
  S      7.979 7
  T      8.292 8
  U      8.605 8
  V      8.918 8
  W      9.231 9
  X      9.544 9
  Y      9.857 9
mazzy
fuente
1
¡Esfuerzo de equipo! : D
Sinusoide
1

Kotlin , 113 bytes

{s:String->var t=0
for(c in s){val v=c-'0'
t+=when(v){0->10
in 1..9->v
in 17..42->(v-11-v/35-v/42)/3
else->0}}
t}

Pruébalo en línea!

JohnWells
fuente
0

Python 3 , 134 123 bytes

f=lambda n:sum(map(int,n.translate(n.maketrans('ADGJMPTWBEHKNQUXCFILORVYSZ','23456789'*3+'79','()+-./ '))))+10*n.count('0')

Pruébalo en línea!

-11 bytes gracias a @ dan04

Artemisa apoya a Mónica
fuente
1
Al reorganizar las letras a 'ADGJMPTWBEHKNQUXCFILNRVYSZ', puede reducir la cadena de números a '23456789'*3+'79'.
dan04