Calcular las pulsaciones de teclas del teléfono celular

15

Su tarea es calcular el número total de pulsaciones de teclas necesarias para ingresar un texto dado en un teléfono celular antiguo.

Los mapas de teclas son:

1:1
2:abcABC2
3:defDEF3
4:ghiGHI4
5:jklJKL5
6:mnoMNO6
7:pqrsPQRS7
8:tuvTUV8
9:wxyzWXYZ9
0:<space><newline>0

Para escribir exaMPle TExt 01, presionaría 33 99 2 6666 77777 555 33 0 8888 33333 99 8 0 <a 1-sec pause here in real life but we'll ignore it>000 1un total de 37 pulsaciones de teclas.

La *clave muestra un mapa de caracteres especiales:

.,'?!
"-()@
/:_;+
&%*=<
>£€$¥
¤[]{}
\~^¡¿
§#|`

con el primero ( .) resaltado. Puede moverse para resaltar el carácter requerido usando las teclas de navegación rectangulares y se necesita presionar otra vez para seleccionar.

Para insertar $, presionaría, *↓↓↓↓→→→<select>es decir, un total de 9 pulsaciones de teclas.

  • La entrada será de un archivo llamado sourceubicado en el directorio / directorio actual de su programa. EDITAR: Por solicitudes en comentarios, estoy agregando STDINcomo un método de entrada válido. Disculpas por cambiar la especificación después de recibir respuestas.
  • Debe salida Total key presses <total_keypresses>
  • Si el archivo de entrada contiene algún carácter que no está en el mapa de teclas dado, entonces su programa debe salir Invalid character <character> in sourcey salir.

En resumen, la entrada y salida de su programa debe parecerse a la de esta secuencia de comandos de Python (sin golf):

# This Python file uses the following encoding: utf-8
from __future__ import print_function
import sys

general_dict = { '1':1,
                 'a':1, 'b':2, 'c':3, 'A':4, 'B':5, 'C':6, '2':7,
                 'd':1, 'e':2, 'f':3, 'D':4, 'E':5, 'F':6, '3':7,
                 'g':1, 'h':2, 'i':3, 'G':4, 'H':5, 'I':6, '4':7,
                 'j':1, 'k':2, 'l':3, 'J':4, 'K':5, 'L':6, '5':7,
                 'm':1, 'n':2, 'o':3, 'M':4, 'N':5, 'O':6, '6':7,
                 'p':1, 'q':2, 'r':3, 's':4, 'P':5, 'Q':6, 'R':7, 'S':8, '7':9,
                 't':1, 'u':2, 'v':3, 'T':4, 'U':5, 'V':6, '8':7,
                 'w':1, 'x':2, 'y':3, 'z':4, 'W':5, 'X':6, 'Y':7, 'Z':8, '9':9,
                 ' ':1, '\n':2, '0':3
                }

special_chars = ['.',',',"'",'?','!','"','-','(',')','@','/',':','_',';','+','&','%','*','=','<','>','£','€','$','¥','¤','[',']','{','}','\\','~','^','¡','¿','§','#','|','`']
for x in special_chars:
    general_dict[x]=(special_chars.index(x)/5) + (special_chars.index(x)%5) + 2

key_press_total = 0
with open('source') as f: # or # with sys.stdin as f:
    for line in f:
        for character in line:
            if character in general_dict:
                key_press_total+=general_dict[character]
            else:
                print('Invalid character',character,'in source')
                sys.exit(1)

print('Total key presses',key_press_total)

Este es el código de golf, el programa más corto en bytes gana.


Descargo de responsabilidad desvergonzado: hice este desafío para tener traducciones del script de python anterior en diferentes idiomas que se utilizarán para calificar este desafío en el sandbox .

usuario80551
fuente
¿Deberíamos error y salir inmediatamente o cuando se encuentra el carácter no válido?
nyuszika7h
@ nyuszika7h Depende de usted, pero debe imprimir el carácter inválido que era. Supongamos que hay 10 caracteres no válidos en la fuente, puede seleccionar cualquiera de ellos, imprimir que ese carácter no es válido y salir. No necesita ser la primera aparición de un carácter no válido.
user80551
77
El requisito de entrada es una pena. File I / O es increíblemente costoso en algunos idiomas y completamente imposible en otros.
Dennis
1
Si permitiera más IO de forma libre, tengo una solución J de 171 caracteres, quién es sha1 hash 1ce5a2fdd0316e37c0a07d151d02db766a3adbb7.
Julıʇǝɥʇuʎs
2
@Dennis permitió STDIN
user80551

Respuestas:

4

GolfScript, 219 caracteres

Enfoque básico utilizando una tabla de búsqueda:

"Total key presses "0@1/{"1adgjmptw °behknqux\n.°cfilorvy0,\"°ADGJMsTz'-/°BEHKNPUW?(:&°CFILOQVX!)_%>°23456R8Y@;*£¤°SZ+=€[~°79<$]^§°¥{¡#°}¿|°`°".2$?)\1$<"°"/,{"Invalid character  in source"18/*puts'"#{''exit}"'+~}if\;+}/

Tratar aquí .

Howard
fuente
1
Bien hecho :) Delphi apesta en este jajaja. Acabo de terminar el mío y estoy en 459 xD ¡Necesito mejorar!
Teun Pronk
1
La entrada debe ser de un archivo llamado source, no STDIN
user80551
Para leer del archivo, pida prestado a Ruby:"#{File.read('source')}"
Justin
1
@Quincunx Puedes quitar los paréntesis de eso:"#{File.read'source'}"
Ventero
Puedes mantener esto como está, permití STDIN ahora.
user80551
3

Ruby 2.0, 232

$.-=~(%W[1adgjmptw\s
behknqux.\n
cfilorvy0,"
ADGJMsTz-'/
BEHKNPUW?(:&
CFILOQVX!)_%>
23456R8Y@;*£¤
SZ+=€[\\
79<$]~§
¥{^{#
}¡|
¿`].index{|s|s[$c]}||$><<"Invalid character #$c in source"&exit)while$c=$<.getc
puts"Total key presses #$."

Esquema de codificación muy simple hasta ahora: más del 75% de los caracteres se utilizan para literales de cadena / matriz ...

Ventero
fuente
2

CJam, 207 bytes

q:Q{" dptgwj1am hxk
.bnequ  ,0flco\"rviy    DT'/GsJz-AM (HP?KW&:BNEU    LXCO_>FV!%)IQ   48@3;*26R¤£5Y   €\+S[Z= $<§7~9] #{^¥ |¡}    `¿"'    /{1$#W>\}%1#)}%_0#){"Invalid character "Q@0#=" in source"}{:+"Total key presses "\}?

Este programa tiene 207 caracteres. Con la codificación adecuada (Windows-1252), cabe en 207 bytes.

Tenga en cuenta que Stack Exchange convierte las pestañas (que uso como delimitador en la tabla de búsqueda) en espacios, por lo que no puede copiar y pegar el código anterior.

Uso

Codificación de Windows-1252

$ base64 -d > keys.cjam <<< cTpReyIgZHB0Z3dqMWFtCWh4awouYm5lcXUJLDBmbGNvXCJydml5CURUJy9Hc0p6LUFNCShIUD9LVyY6Qk5FVQlMWENPXz5GViElKUlRCTQ4QDM7KjI2UqSjNVkJgFwrU1taPQkkPKc3fjldCSN7XqUgfKF9CWC/IicJL3sxJCNXPlx9JTEjKX0lXzAjKXsiSW52YWxpZCBjaGFyYWN0ZXIgIlFAMCM9IiBpbiBzb3VyY2UifXs6KyJUb3RhbCBrZXkgcHJlc3NlcyAiXH0/
$ wc -c keys.cjam
207 keys.cjam
$ echo 'Hello, world!' | LANG=en_US.CP1252 cjam keys.cjam; echo
Total key presses 39
$ echo 'á' | LANG=en_US.CP1252 cjam keys.cjam; echo
Invalid character á in source

Codificación UTF-8

$ base64 -d > keys.cjam <<< cTpRezpDIiBkcHRnd2oxYW0JaHhrCi5ibmVxdQksMGZsY29cInJ2aXkJRFQnL0dzSnotQU0JKEhQP0tXJjpCTkVVCUxYQ09fPkZWISUpSVEJNDhAMzsqMjZSwqTCozVZCeKCrFwrU1taPQkkPMKnN345XQkje17CpSB8wqF9CWDCvyInCS97MSQjVz5cfSUxIyl9JV8wIyl7IkludmFsaWQgY2hhcmFjdGVyICJRQDAjPSIgaW4gc291cmNlIn17OisiVG90YWwga2V5IHByZXNzZXMgIlx9Pw==
$ wc -cm keys.cjam
209 217 keys.cjam
$ echo 'Hello, world!' | LANG=en_US.UTF8 cjam keys.cjam; echo
Total key presses 39
$ echo 'á' | LANG=en_US.UTF8 cjam keys.cjam; echo
Invalid character á in source
Dennis
fuente
2

PHP, 711 708 676 caracteres (lectura de STDIN ahora)

<?php $message=iconv("UTF-8","CP1252",fread(STDIN,1024));@$s=str_split;$special=iconv("UTF-8","CP1252",'.,\'?!"-()@/:_;+&%*=<>£€$¥¤[]{}\~^¡¿§#|`');$z=0;foreach($s($message)as$l){$a=ord($l);$b=$a;if($a==13)continue;($a>114||($a>82&&$a<91))&&$a--;$w=$a<58?($a-48):($a<91?($a-64):($a-96));$y=($a<58?1:($w%3?$w%3:3));$a<91&&$y+=3;$a<58&&$y=7;if($a==55||$a==57)$y=9;if($b==115||$b==122)$y=4;if($b==90||$b==83)$y=8;if(($b>79&&$b<83)||($a>85&&$a<89))$y++;($a==32||$a==49)&&$y=1;$a==10&&$y=2;$a==48&&$y=3;$u=array_search($l,$s($special));if($u!==false){$y=2+floor($u/5)+$u%5;}$z+=$y;if(($a<32||$a>127)&&$a!=10){echo"Invalid character $l in source";exit();}}echo"Total key presses $z";

Mi primer golf hasta ahora :)

Quería probar un enfoque poco convencional. En lugar de tener una lista de cada personaje y cuántos clics se necesitan para crearlo, estoy usando los valores ASCII del personaje y calculo las pulsaciones de teclas necesarias. Pensé que me ahorraría algunos personajes primero, ahora creo que es incluso más largo que un enfoque de matriz.

Mi principal problema son las teclas 7 y 9, que tienen 4 letras, en lugar de 3. Por lo tanto, necesitaba crear un par de fallos, que volaron mi código en casi 200 caracteres.

Versión sin golf

<?php
@$source = source;
$h = fopen($source, @r);
$message = iconv("UTF-8", "CP1252", fread($h, filesize($source)));
@$split = str_split;
$special = iconv("UTF-8", "CP1252", '.,\'?!"-()@/:_;+&%*=<>£€$¥¤[]{}\~^¡¿§#|`');
$count = 0;
foreach ($split ($message) as $character) {
    $ascii = ord($character);
    $helper = $ascii;
    if ($a == 13) continue;
    ($a > 114 || ($a > 82 && $a < 91)) && $ascii--;
    $key = $ascii < 58 ? ($a - 48) : ($a < 91 ? ($a - 64) : ($a - 96));

    $presses = ($a < 58 ? 1 : ($key % 3 ? $key % 3 : 3));

    // This part uses a lot of (probably unnecessary or still optimizable) fallbacks
    // for those characters, that are on "4-letter-keys"
    $ascii < 91 && $presses += 3;
    $ascii < 58 && $presses = 7;
    if ($a == 55 || $a == 57) $presses = 9;
    if ($helper == 115 || $helper == 122) $presses = 4;
    if ($helper == 90 || $helper == 83) $presses = 8;
    if (($helper > 79 && $helper < 83) || ($a > 85 && $a < 89)) $presses++;
    $ascii == 32 && $presses = 1;
    $ascii == 10 && $presses = 2;
    $ascii == 48 && $presses = 3;
    $ascii == 49 && $presses = 1;

    $key = array_search($l, $split($special));
    if ($key !== false){
        $presses = 2 + floor($key/5) + $key % 5;
    }

    $count += $presses;
    if ($a < 32 && $a > 127 && $a != 10) {
        echo "Invalid character $l in source";
        exit();
    }
}
echo "Total key presses $count";

Supongo que todavía hay mucho margen de mejora, pero estoy bastante contento con esto.

Otra cosa mala es el uso requerido de iconv()para la lista de caracteres especiales. Algunos de estos ( , ¥, ...) no son compatibles de forma nativa por PHP.

Padarom
fuente
€ ¥, etc. no son caracteres ascii, por eso mi script de Python declara la codificación utf-8. Ese es un comentario especial interpretado por python.
user80551
utf8_decodefuncionaría bien para todos los personajes , excepto de . Es por eso que tuve que usar iconven su lugar. Mi código no calcula estos caracteres especiales como lo hace con los caracteres normales, ya que no están en orden y no puedo trabajar de manera confiable con sus respectivos valores ASCII. Está usando una lista normal para ellos.
Padarom
2

Python 3, 239 caracteres

s='1adgjmptw 1behknqux\n.1cfilorvy0,"1ADGJMsTz\'-/1BEHKNPUW?(:&1CFILOQVX!)_%>123456R8Y@;*£¤1SZ+=€[\\179<$]~§1¥{^#1}¡|1¿`'
print('Total key presses',sum(s[:s.find(c)+1].count('1')or exit('Invalid character %c in source'%c)for c in input()))
grc
fuente
1

JavaScript (E6) 291

Editar

Versión de shell, utilizando el shell de spydermonkey. Leer desde un archivo 'fuente', escribir en sdtout

z=t=0,[...read('source')].map(c=>t-=~((i=".\"/&>¤\\§,-:%£[~#'(_*€]^|?);=${¡`!@+<¥}¿".indexOf(c))<0?(p="0\n 9ZYXWzyxw8VUTvut7SRQPsrqp6ONMonm5LKJlkj4IHGihg3FEDfed2CBAcba10".split(c)[1])?p.search(/\d/):z="Invalid character "+c+" in source":i%8-~(i>>3))),print(z||"Total key presses "+t)

Primer intento, funciona en la consola FireFox usando ventanas emergentes para entrada y salida

P=m=>(z=t=0,[...m].map(c=>t-=~((i=".\"/&>¤\\§,-:%£[~#'(_*€]^|?);=${¡`!@+<¥}¿".indexOf(c))<0
?(p="0\n 9ZYXWzyxw8VUTvut7SRQPsrqp6ONMonm5LKJlkj4IHGihg3FEDfed2CBAcba10".split(c)[1]) 
?p.search(/\d/):z="Invalid character "+c+" in source":i%8-~(i>>3))),z||"Total key presses "+t);
alert(P(prompt()))

Legible

P=m=>(
  z=t=0,
  [...m].map(
    c=>t-=~(
      (i = ".\"/&>¤\\§,-:%£[~#'(_*€]^|?);=${¡`!@+<¥}¿".indexOf(c)) < 0
      ? (p = "0\n 9ZYXWzyxw8VUTvut7SRQPsrqp6ONMonm5LKJlkj4IHGihg3FEDfed2CBAcba10".split(c)[1]) 
        ? p.search(/\d/)
        : z="Invalid character "+c+" in source"
      : i%8 - ~(i>>3)
    )
  ),  
  z||"Total key presses "+t
);
edc65
fuente
0

VBScript 435

No es compatible con caracteres no ASCII. Estaba bastante lejos de mi código, así que pensé en publicarlo como referencia. No creo que nadie más haya usado este enfoque.

i=inputbox(i)
a=SPLIT("1 abcABC2 defDEF3 ghiGHI4 jklJKL5 mnoMNO6 pqrsPQRS7 tuvTUV8 wxyzWXYZ9 0")
a(9)=" "+vbLf+"0"
b=SPLIT(".,'?! ""-()@ /:_;+ &%*=< >£€$¥ ¤[]{} \~^¡¿ §#|` x x")

for o=1 to len(i)
n=0
    for x=0 to 9
        for c=1 to 10
            d=mid(i,o,1)
            IF n=0 AND mid(b(x),c,1)=d THEN n=c+x
            IF mid(a(x),c,1)=d THEN n=c
        next
    next
    z=n+z  
    IF n=0 THEN EXIT FOR
next
o="Total key presses "+cstr(z)
IF n=0 THEN o="Invalid character "+d+" in source"
msgbox o
cómodamentedrei
fuente