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
TheDoctor
fuente
¿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.

Ilmari Karonen
fuente
50

Bash, 30

Editar: Gracias Doorknob por eliminar 3 caracteres

tr a-z 22233344455566677778889

Ejemplo:

usuario12205
fuente
10
¿No puedes eliminar los últimos 3 9s?
Pomo de la puerta
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

Mattnewport
fuente
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)}))
Victor Stafusa
fuente
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'
Pomo de la puerta
fuente
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;}}
Hosch250
fuente
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]
Tal vez sea así
fuente
+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]
blabla999
fuente
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

DavidC
fuente
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
Rob Hoare
fuente
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)] ))
Carl Witthoft
fuente
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"
nyi
fuente
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}))
George Reith
fuente
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;}
}
Rob Hoare
fuente
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
jsedano
fuente
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
Jonathan Van Matre
fuente
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.

zheshishei
fuente
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));
ub3rst4r
fuente
1

q [38 caracteres]

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

Inspirado en la solución de @ ace

Ejemplo

{(.Q.a!"22233344455566677778889999")x}"stack exchange"
"78225 39242643"
nyi
fuente
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.

Reinstalar a Monica - dirkk
fuente
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
TheDoctor
fuente
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.

Cepillo de dientes
fuente
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()))
gcq
fuente
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"
bazzargh
fuente
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))));}}
RobIII
fuente
0

Pitón

import string          
trans = str.maketrans(string.ascii_lowercase,
                      '22233344455566677778889999')                                                                                         
print("1-800-ask-usps".translate(trans))
yegle
fuente
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.

Malvolio
fuente
0

Perl, 54

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

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

DLosc
fuente
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).

DLosc
fuente
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
Sven Hohenstein
fuente