Letras en los números de teléfono


23

Problema:

Está creando un nuevo teléfono donde las personas pueden escribir números de teléfono especializados, por ejemplo 1-800-program, y se convertirían automáticamente en un número de teléfono utilizable, como 1-800-7764726(para el ejemplo anterior).

Su programa recibirá una cadena de cualquier longitud con números, letras y guiones, y convertirá todas las letras a sus números correspondientes.

Aquí hay un teclado, para referencia:

teclado

Reglas:

  • Su programa recibirá una cadena.
  • Lo procesará y devolverá / imprimirá otra cadena
  • Cualquier idioma es aceptado
  • Como es el , gana el código más corto

¿Debería el programa manejar letras mayúsculas y minúsculas en la entrada?
mattnewport

3
@mattnewport: no, suponga que la variable ya se ha convertido en minúsculas
TheDoctor

Respuestas:


8

GolfScript, 24 caracteres

{.96>{,91,'qx'+-,3/`}*}%

Prueba de entrada:

0123456789-abcdefghijklmnopqrstuvwxyz

Prueba de salida:

0123456789-22233344455566677778889999

Explicación:

  • { }% aplica el código entre llaves a cada carácter de la entrada.

  • .96>{ }* ejecuta el código entre las llaves internas si y solo si el código ASCII del carácter es mayor que 96 (es decir, es una letra minúscula).

  • El primero ,convierte el carácter en una lista de todos los caracteres con códigos ASCII más bajos y 91,'qx'+-filtra todos los caracteres con códigos ASCII inferiores a 91, así como las letras qy x, de la lista. Así, por ejemplo, el personaje ase convierte en la lista de 6 caracteres [\]^_`, mientras que zse convierte en la lista de 29 caracteres [\]^_`abcdefghijklmnoprstuvwy.

  • El segundo ,cuenta los elementos que quedan en la lista y 3/divide este recuento por tres (redondeando hacia abajo). Finalmente, `convierte el número resultante (en el rango de 2 a 9) en una cadena.

Por lo tanto, según las especificaciones, los guiones y los números no se modifican, mientras que las letras minúsculas se asignan a números de acuerdo con el diagrama del teclado de referencia. El código en realidad pasará limpiamente a través de todos los caracteres ASCII imprimibles, excepto las letras minúsculas (que se asignan como se describe) y los caracteres {, |y }(que se asignan a la cadena de dos caracteres 10). La entrada de 8 bits no ASCII producirá todo tipo de salidas numéricas extrañas.

Después de todo esto, es un poco decepcionante que solo supere la solución trivial bash en solo seis caracteres.



16

C, 83 78 77 65 63 62

main(c){for(;~(c=getchar());putchar(c>96?20-c/122+5*c/16:c));}

http://ideone.com/qMsIFQ


3
Buena matemática. Solo quiero decir que puedes reducir 1 char suponiendo que EOF es -1 y hacerlo~(c=getchar())
user12205

¿No podrías usar en getch()lugar de getchar()?
starsplusplus

Estrictamente hablando, getch()no es el estándar C, como resultado supongo que no se vincula en ideona. Sin embargo, lo probé en MSVC y realmente no funciona tristemente, ya que consume directamente la entrada del teclado, no hay forma de salir del programa, aunque traduce lo que escribes sobre la marcha, lo cual es bastante ordenado.
mattnewport

4

Javascript - 103 caracteres

alert(prompt().replace(/[a-z]/g,function(y){y=y.charCodeAt(0)-91;return y>27?9:y>24?8:y>20?7:~~(y/3)}))

1
No sabía que podías hacer eso con .replace. ¡Vota por ti!
SuperJedi224

Puede reemplazar charCodeAt(0)con charCodeAt()y puede usar la función de flecha para function(y)...guardar algunos bytes y ~~(y/3)puede usary/3|0
chau giang

3

Ruby, 75 caracteres

gets.chars{|c|$><<"22233344455566677778889999#{c}"[[*?a..?z].index(c)||-1]}

Utiliza el charsbloque obsoleto con, e imprime cada letra individualmente con $><<. También me gusta [[*?a..?z].index(c)||-1]; agarra el carácter correspondiente a esa letra del alfabeto si es una letra, y el último carácter (que resulta ser el carácter de prueba sin cambios) si no.

Ruby, 43 (o 35) caracteres

Robando descaradamente a @ace;)

puts gets.tr'a-z','22233344455566677778889'

Afeite 8 caracteres si puedo ejecutar en IRB con la variable scomo la cadena:

s.tr'a-z','22233344455566677778889'

3

C ++ - 222 caracteres

La solución más larga hasta ahora:

#include<iostream>
#include<string>
#define o std::cout<<
int main(){std::string s;std::cin>>s;for(int i=0;i<s.size();i++){int j=s[i]-97;if(j<0)o s[i];if(0<=j&j<15)o 2+j/3;if(14<j&j<19)o 7;if(18<j&j<22)o 8;if(21<j&j<26)o 9;}}

1
Lol, no creo que el objetivo sea la solución más larga aquí ...
Danny

@Danny C ++ no se presta bien a code-golf . Java y C # son los únicos lenguajes que son peores, que yo sepa (todas las clases, creación de objetos y nombres largos para la salida ...).
Hosch250

Lo sé, pensé que era divertido que mencionaras "La solución más larga".
Danny

3

Frink, 92

Un lenguaje bastante detallado, lo sé. Esto verifica 8 valores en lugar de 26 sin tener que escribir las comparaciones. ¿Puede alguna de las soluciones "222333444 .." anteriores reducirse de manera similar?

Utilizando estructuras incorporadas, 107

co=new OrderedList
co.insertAll[charList["cfilosv{"]]
println[input[""]=~%s/([a-z])/co.binarySearch[$1]+2/eg]

Usando una función recursiva personalizada, 92

fn[x,a]:=x<=(charList["cfilosv{"])@a?a+2:fn[x,a+1]
println[input[""]=~%s/([a-z])/fn[$1,0]/eg]

+1 para reducir el método de traducción de cadenas a una búsqueda de 8 caracteres. Buen toque.
Jonathan Van Matre

2

Smalltalk, 79 70

la entrada es s:

s collect:[:c|' 22233344455566677778889999'at:1put:c;at:(($ato:$z)indexOf:c)+1]

probablemente no sea un candidato para ser el más bajo, pero puede ser de interés para un viejo truco para evitar una prueba de una condición no encontrada (indexOf: devuelve 0 en este caso). Por lo tanto, no se necesita una prueba especial para las letras. Sin embargo, algunos Smalltalks tienen cadenas inmutables y necesitamos 4 caracteres más ("copia").

Oh, una versión mejor, que incluso trata con cadenas inmutables en 70 caracteres:

s collect:[:c|c,'22233344455566677778889999'at:(($ato:$z)indexOf:c)+1]

2

Mathematica 90

Esto sigue la lógica de la solución de @ ace:

StringReplace[#,Thread[CharacterRange["A","Z"]->Characters@"22233344455566677778889999"]]&

Ejemplo

StringReplace[#1,Thread[CharacterRange["A","Z"]-> 
Characters@"22233344455566677778889999"]]&["VI37889"]

8437889


Su representación de personaje de flecha no es aceptada por Mma en una copia / pegado
Dr. belisarius

Además, no es necesario el 1en #1:)
Dr. Belisario

Belisario, cambié la flecha hacia atrás y quité el 1. Todavía 90 caracteres pero cortar y pegar funcionarán. Por supuesto, comprende la motivación para usar la flecha de un solo carácter.
DavidC

He

2

Perl, 50

Otra copia obvia de la respuesta bash de Ace

($_)=@ARGV;y/a-z/22233344455566677778889999/;print

1
Este código funciona correctamente pero hay margen de mejora. Vamos a deshacernos de $ ARGV [0] y usar el -pinterruptor en su lugar, que le permite ir muy bien a través de cada línea de stdin. Mientras estamos en eso, el rango en y /// no necesita ponerse entre corchetes. También podemos deshacernos de tres 9 dejando solo uno y eliminar el punto y coma final: -p y/a-z/22233344455566677778889/ ya está, 30 + 1 para -p. Gracias por utilizar Enterprise Chinese Perl Golfing y los servicios de optimización y que tenga un buen día.
Perl chino gótico

2

R, muy largo pero divertido

foo <- '1-800-splurghazquieaobuer57'
oof <- unlist(strsplit(foo,''))
#don't count that part - it's input formatting :-) 
digout <- unlist(strsplit('22233344455566677778889999','')) 
oof[oof%in%letters[1:26]] <- unlist(sapply(oof[oof%in%letters[1:26]], function(j) digout[which(letters[1:26]==j)] ))

2

k [32 caracteres]

{(.Q.a!|,/(4 3 4,5#3)#'|$2+!8)x}

Uso

{(.Q.a!|,/(4 3 4,5#3)#'|$2+!8)x}"stack exchange"
"78225 39242643"

2

JavaScript, 85

JavaScript nunca va a ganar las guerras de golf, pero me gusta y quería hacer algo diferente a saltar en el carro de @ace.

alert(prompt().replace(/[a-z]/g,function(a){for(i=7;a<"dgjmptw{"[i--];);return i+4}))

2

PHP, 141

No es el más corto, pero sí más divertido:

<?php foreach(str_split($argv[1])as$c){$v=ord($c);if($v>114){$v--;}if($v==121){$v--;}if($v<123&$v>96){echo chr(ceil($v/3+17));}else{echo$c;}}

Más legible:

<?php 
foreach (str_split($argv[1]) as $c) {
  $v=ord($c);
  if ($v>114) {$v--;}
  if ($v==121){$v--;}
  if ($v<123 & $v>96){
    echo chr(ceil($v/3+17));
    } else {echo $c;}
}

OP dijo que la entrada ya está en minúsculas, por lo que puede eliminar elstrtolower
Einacio

2

Python 2.7, 80

for c in raw_input():print'\b'+(`(ord(c)-97)/3+2-(c in('svyz'))`if c>'`'else c),

Soy nuevo en Python, así que estoy seguro de que debe haber una forma de jugar al golf aún más , es un enfoque diferente, ¡espero que les guste, Dios mío, es Python bonito!

Ejecute el ejemplo:

  • entrada: 01-800-abcdefghijklmnopqrstuvwxyz
  • salida: 01-800-22233344455566677778889999

2

T-SQL, 216 bytes

Pasé bastante tiempo durante las últimas noches creando minuciosamente una función de secuencia matemática que se redondearía correctamente para generar los códigos ASCII adecuados para los números de los códigos ASCII alfabéticos. Tenía un número ridículo de decimales en los coeficientes, pero funcionó.

Sin embargo, el enfoque racional de mattnewport también funciona en SQL, a un costo mucho menor de bytes, por lo que descarto descaradamente mis propias matemáticas a favor de las suyas. Sube a votarlo, ¡es una solución elegante!

Aquí está el mío:

DECLARE @p VARCHAR(MAX)='';WITH t AS(SELECT ASCII(LEFT(@s,1))c,2 i UNION ALL SELECT ASCII(SUBSTRING(@s,i,1)),i+1FROM t WHERE i<=LEN(@s))SELECT @p=@p+CHAR(CASE WHEN c>96THEN 20-c/122+5*c/16 ELSE c END)FROM t;SELECT @p

Esto usa un CTE recursivo para hacer una pila improvisada de los caracteres en el número de teléfono y traducir las letras sobre la marcha, luego un poco de truco de SQL (SELECT @ p = @ p ​​+ columnValue) para recomponer la cadena del CTE sin requerir Otra construcción de recursión.

Salida:

DECLARE @s VARCHAR(MAX)='1-800-abcdefghijklmnopqrstuvwxyz'
--above code runs here
1-800-22233344455566677778889999

2

Python 2.7, 66 65


Original de Anakata

for c in raw_input():print'\b'+(`(ord(c)-97)/3+2-(c in('svyz'))`if c>'`'else c),


Más golf

for c in input():print(ord(c)-91)/3-(c in('svyz'))if c>'`'else c,


No tengo suficiente reputación para comentar sobre la respuesta de @ anakata, así que hice una publicación separada aquí. Tuve la misma idea (tomar el módulo de ordenanzas 3) pero no pude encontrar la forma de imprimir los números correctos para s - z .

De todos modos, las mejoras de golf que hice:

  • cambiado raw_inputainput

  • eliminado los extraños '\b'y paréntesis y comillas simples

  • eliminó el +2desplazamiento y lo colocó en la resta original (97 - (3 * 2) = 91)

Probado con el intérprete Python 2.7.6. Asume, según las reglas, una entrada de cadena.


también puede eliminar el espacio entre el) y el si
Willem

Tienes razón. buena captura
willem

1

PHP, 87

echo str_ireplace(range('a','z'),str_split('22233344455566677778889999'),fgets(STDIN));

1

q [38 caracteres]

{(.Q.a!"22233344455566677778889999")x}

Inspirado en la solución de @ ace

Ejemplo

{(.Q.a!"22233344455566677778889999")x}"stack exchange"
"78225 39242643"

1

XQuery, 71

BaseX se utilizó como procesador XQuery. $ies entrada.

translate($i,"abcdefghijklmnopqrstuvwxyz","22233344455566677778889999")

No es la respuesta más corta, pero es bastante corta y muy legible.


1

Pitón, muy poco golfista

Como todos están copiando as, decidí publicar el código que inventé antes de enviar la pregunta:

def phonekeypad(text):
    c = ['','','abc','def','ghi','jkl','mno','pqrs','tuv','wxyz']
    st = ""
    for i in list(text):
        a = False
        for t in range(len(c)):
            if i in c[t]:
                st += str(t)
                a=True
        if a == False:
            st += str(i)
    return st

1

EcmaScript 6 (103 bytes):

i.replace(/[a-z]/g,x=>keys(a='00abc0def0ghi0jkl0mno0pqrs0tuv0wxyz'.split(0)).find(X=>a[X].contains(x)))

Espera i contener la cadena.

Pruébelo en cualquier versión reciente de Firefox. No he probado Google Chrome.


1

Pitón 3, 121

print("".join((lambda x:"22233344455566677778889999"[ord(x)-97] if ord(x)>96 and ord(x)<123 else x)(i) for i in input()))

1

Haskell, 93C

t[]_ a=a
t(b:c)(d:e)a
 |a==b=d
 |True=t c e a
y=map(t['a'..'z']"22233344455566677778889999")

Uso

y "1-800-program"

1

C # 140

using System.Linq;class P{static void Main(string[]a){System.Console.Write(string.Concat(a[0].Select(d=>(char)(d>96?20-d/122+5*d/16:d))));}}

0

Pitón

import string          
trans = str.maketrans(string.ascii_lowercase,
                      '22233344455566677778889999')                                                                                         
print("1-800-ask-usps".translate(trans))

0

ECMASCRIPT, 101 (con entrada)

"1-800-PROGRAM".replace(/./g,function(c){
return "22233344455566677778889999"[c.charCodeAt(0)-65]||c})

Nueva línea agregada para mayor claridad. 85 caracteres si la entrada está en una variable.


0

Perl, 54

print map{/[a-y]/?int(5/16*ord)-28:/z/?9:$_}<>=~/./gs

Dispara, @RobHoare todavía me ganó por 4 personajes. :)


0

QBasic, 155

Ah, los recuerdos ...

INPUT n$
FOR i=1 TO LEN(n$)
c$=MID$(n$,i,1)
a=ASC(c$)
IF 97>a THEN
PRINT c$;
ELSE IF 122>a THEN
PRINT STR$(a\3.2-28);
ELSE
PRINT 9;
END IF
NEXT i

Esto debería haber sido más corto, pero estaba probando con repl.it , que no permite IFdeclaraciones de una sola línea y se comporta de manera extraña si deja la variable desactivada NEXT i. Tampoco reconoce la ASCfunción, por lo que para ejecutar el código deberá agregar esta solución al principio:

DECLARE FUNCTION ASC(s$)
FUNCTION ASC(s$)
FOR j=1 TO 255
IF CHR$(j)=LEFT$(s$,1) THEN
ASC=j
END IF
NEXT j
END FUNCTION

(La segunda vez que lo ejecute, el intérprete se quejará a menos que elimine la DECLARE FUNCTIONlínea, vaya a la figura).


0

R, 110

s=strsplit(scan(,""),"")[[1]];i=grep("[a-z]",s);s[i]=sort(c(1:24%%8+2,7,9))[match(s[i],letters)];cat(s,sep="")

Ejemplo:

> s=strsplit(scan(,""),"")[[1]];i=grep("[a-z]",s);s[i]=sort(c(1:24%%8+2,7,9))[match(s[i],letters)];cat(s,sep="")
1: 1-800-program
2: 
Read 1 item
1-800-7764726
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.