Calculer les touches du téléphone portable

15

Votre tâche consiste à calculer le nombre total d'appuis sur les touches nécessaires pour saisir un texte donné sur un ancien téléphone portable.

Les keymaps sont:

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

Pour taper exaMPle TExt 01, vous devez appuyer 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 1sur un total de 37 touches.

La *touche fait apparaître une carte de caractères spéciaux:

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

avec le premier ( .) en surbrillance. Vous pouvez vous déplacer pour mettre en surbrillance le caractère requis à l'aide des touches de navigation rectangulaires et il faut appuyer sur une autre touche pour sélectionner.

Donc, pour insérer $, vous appuyez sur *↓↓↓↓→→→<select>soit un total de 9 touches.

  • L'entrée se fera à partir d'un fichier appelé sourceplacé dans le répertoire / répertoire courant de votre programme. EDIT: Par requêtes dans les commentaires, j'ajoute STDINcomme méthode d'entrée valide. Toutes mes excuses pour avoir modifié la spécification après avoir reçu des réponses.
  • Vous devez sortir Total key presses <total_keypresses>
  • Si le fichier d'entrée contient un caractère qui ne se trouve pas dans le clavier donné, votre programme doit sortir Invalid character <character> in sourceet quitter.

En bref, l'entrée et la sortie de votre programme doivent ressembler à celles de ce script python (non 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)

Il s'agit du code-golf, le programme le plus court en victoires d'octets.


Avertissement sans vergogne: j'ai fait ce défi d'avoir des traductions du script python ci-dessus dans différentes langues qui seront utilisées pour marquer ce défi dans le bac à sable .

user80551
la source
Faut-il commettre une erreur et quitter immédiatement ou lorsque le caractère non valide est rencontré?
nyuszika7h
@ nyuszika7h C'est à vous de décider, mais vous devez imprimer ce caractère invalide. Supposons qu'il y ait 10 caractères non valides dans la source, vous pouvez sélectionner l'un d'entre eux, imprimer que ce caractère n'est pas valide et quitter. Il n'est pas nécessaire que ce soit la première occurrence d'un caractère non valide.
user80551
7
L'exigence d'entrée est une honte. Les E / S sur fichiers sont extrêmement coûteuses dans certaines langues et totalement impossibles dans d'autres.
Dennis
1
Si vous deviez autoriser plus d'E / S de forme libre, j'ai une solution J de 171 caractères, qui est le hachage sha1 1ce5a2fdd0316e37c0a07d151d02db766a3adbb7.
ɐɔıʇǝɥʇuʎs
2
@Dennis autorisé STDIN
user80551

Réponses:

4

GolfScript, 219 caractères

Approche de base à l'aide d'une table de recherche:

"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\;+}/

Essayez ici .

Howard
la source
1
Bien fait :) Delphi suce à ce lol .. vient de terminer le mien et je suis à 459 xD besoin d'améliorer!
Teun Pronk
1
L'entrée doit provenir d'un fichier nommé source, pas de STDIN
user80551
Pour lire à partir d'un fichier, emprunter à ruby:"#{File.read('source')}"
Justin
1
@Quincunx Vous pouvez supprimer les parenthèses de cela:"#{File.read'source'}"
Ventero
Vous pouvez garder cela tel quel, j'ai autorisé STDIN maintenant.
user80551
3

Rubis 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 #$."

Schéma d'encodage très simple jusqu'à présent: plus de 75% des caractères sont utilisés pour les littéraux chaîne / tableau ...

Ventero
la source
2

CJam, 207 octets

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 "\}?

Ce programme contient 207 caractères. Avec l'encodage approprié (Windows-1252), il tient dans 207 octets.

Notez que Stack Exchange convertit les onglets (que j'utilise comme délimiteur dans la table de recherche) en espaces, vous ne pouvez donc pas copier et coller le code ci-dessus.

Usage

Encodage 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

Encodage 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
la source
2

PHP, 711 708 676 caractères (lecture depuis STDIN maintenant)

<?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";

Mon premier golf jusqu'à présent :)

Je voulais essayer une approche plutôt non conventionnelle. Au lieu d'avoir une liste de chaque caractère et le nombre de clics nécessaires pour le créer, j'utilise les valeurs ASCII du caractère et calcule les pressions de touches requises. Je pensais que cela m'épargnerait d'abord certains personnages, maintenant je pense que c'est encore plus long qu'une approche par tableau.

Mon problème principal est les touches 7 et 9, qui ont 4 lettres, au lieu de 3. Par conséquent, je devais créer quelques solutions de rechange, ce qui a fait exploser mon code de près de 200 caractères.

Version non golfée

<?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";

Je suppose qu'il y a encore beaucoup de place à l'amélioration, mais j'en suis assez content.

Une autre mauvaise chose est l'utilisation requise de iconv()pour la liste des caractères spéciaux. Certains d'entre eux ( ,, ¥...) ne sont pas supportés nativement par PHP.

Padarom
la source
€ ¥, etc. ne sont pas des caractères ascii, c'est pourquoi mon script python déclare l'encodage utf-8. C'est un commentaire spécial interprété par python.
user80551
utf8_decodefonctionnerait bien pour tous les caractères sauf de . C'est pourquoi j'ai dû utiliser à la iconvplace. Mon code ne calcule pas ces caractères spéciaux comme il le fait avec les caractères normaux, car ils ne sont pas en ordre et je ne peux pas travailler de manière fiable avec leurs valeurs ASCII respectives. Il utilise une liste normale pour eux.
Padarom
2

Python 3, 239 caractères

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
la source
1

JavaScript (E6) 291

Éditer

Version shell, utilisant le shell spydermonkey. Lire à partir d'un fichier «source», écrire sur 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)

Essayez d'abord, fonctionne dans la console FireFox en utilisant un popup pour l'entrée et la sortie

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()))

Lisible

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
la source
0

VBScript 435

Ne prend pas en charge les caractères non ASCII. J'étais assez loin avec mon code, donc j'ai pensé le poster pour référence. Je ne pense pas que quelqu'un d'autre ait utilisé cette approche.

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
comfortablydrei
la source