Tính toán nhấn phím điện thoại di động


15

Nhiệm vụ của bạn là tính toán tổng số lần nhấn phím cần thiết để nhập một văn bản đã cho trên một điện thoại di động cũ.

Các keymap là:

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

Để gõ exaMPle TExt 01, bạn sẽ nhấn 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 1tổng cộng 37 lần nhấn.

Các *chủ chốt sẽ trả về một bản đồ của các nhân vật đặc biệt:

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

với cái đầu tiên ( .) được tô sáng. Bạn có thể di chuyển để làm nổi bật ký tự được yêu cầu bằng các phím điều hướng hình chữ nhật và phải mất một phím nhấn khác để chọn.

Vì vậy, để chèn $, bạn sẽ nhấn *↓↓↓↓→→→<select>tức là tổng cộng 9 lần nhấn phím.

  • Đầu vào sẽ từ một tệp được gọi sourcetrong thư mục / thư mục hiện tại của chương trình của bạn. EDIT: Mỗi yêu cầu trong nhận xét, tôi đang thêm STDINdưới dạng phương thức nhập hợp lệ. Xin lỗi vì đã thay đổi thông số kỹ thuật sau khi nhận được câu trả lời.
  • Bạn phải xuất Total key presses <total_keypresses>
  • Nếu tệp đầu vào chứa bất kỳ ký tự nào không có trong sơ đồ phím đã cho, thì chương trình của bạn phải xuất Invalid character <character> in sourcevà thoát.

Nói tóm lại, đầu vào và đầu ra của chương trình của bạn phải giống với tập lệnh python (không được mã hóa) này:

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

Đây là mã golf, chương trình ngắn nhất tính bằng byte thắng.


Từ chối trách nhiệm không biết xấu hổ: Tôi đã thực hiện thử thách này để có các bản dịch của kịch bản python ở trên bằng các ngôn ngữ khác nhau sẽ được sử dụng để ghi điểm cho thử thách này trong hộp cát .


Chúng ta có nên lỗi và thoát ngay lập tức hay khi gặp phải ký tự không hợp lệ?
nyuszika7h

@ nyuszika7h Tùy bạn, nhưng bạn phải in ký tự không hợp lệ. Giả sử có 10 ký tự không hợp lệ trong nguồn, bạn có thể chọn bất kỳ một trong số chúng, in ký tự đó không hợp lệ và thoát. Nó không cần phải là sự xuất hiện đầu tiên của một nhân vật không hợp lệ.
user80551

7
Yêu cầu đầu vào là một sự xấu hổ. Tệp I / O cực kỳ tốn kém ở một số ngôn ngữ và hoàn toàn không thể ở những ngôn ngữ khác.
Dennis

1
Nếu bạn cho phép IO dạng tự do nhiều hơn, tôi có giải pháp J gồm 171 ký tự, đó là hàm băm sha1 1ce5a2fdd0316e37c0a07d151d02db766a3adbb7.
"

2

Câu trả lời:


4

GolfScript, 219 ký tự

Phương pháp cơ bản sử dụng bảng tra cứu:

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

Hãy thử ở đây .


1
Hoàn thành tốt :) Delphi hút vào lol này .. chỉ cần hoàn thành của tôi và tôi ở 459 xD cần phải cải thiện!
Teun Pronk

1
Đầu vào cần phải từ một tệp có tên source, không phải STDIN
user80551

Để đọc từ tập tin, mượn từ ruby:"#{File.read('source')}"
Justin

1
@Quincunx Bạn có thể bỏ dấu ngoặc đơn từ đó:"#{File.read'source'}"
Ventero

Bạn có thể giữ nó như hiện tại, tôi đã cho phép STDIN ngay bây giờ.
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 #$."

Lược đồ mã hóa rất đơn giản cho đến nay: hơn 75% các ký tự được sử dụng cho chuỗi ký tự / mảng ...


2

CJam, 207 byte

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

Chương trình này có 207 ký tự. Với mã hóa phù hợp (Windows-1252), nó phù hợp với 207 byte.

Lưu ý rằng Stack Exchange chuyển đổi các tab (mà tôi sử dụng làm dấu phân cách trong bảng tra cứu) thành khoảng trắng, vì vậy bạn không thể sao chép và dán mã ở trên.

Sử dụng

Mã hóa 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

Mã hóa 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

2

PHP, 711 708 676 ký tự (đọc từ STDIN ngay bây giờ)

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

Golf đầu tiên của tôi cho đến nay :)

Muốn thử một cách tiếp cận khá độc đáo. Thay vì có một danh sách mỗi ký tự và cần bao nhiêu lần nhấp để tạo nó, tôi đang sử dụng các giá trị ASCII của nhân vật và tính toán các phím bấm cần thiết của họ. Nghĩ rằng nó sẽ dành cho tôi một số nhân vật trước, bây giờ tôi nghĩ nó còn dài hơn cả cách tiếp cận mảng.

Vấn đề chính của tôi là các phím 7 và 9, có 4 chữ cái, thay vì 3. Do đó, tôi cần phải tạo ra một vài dự phòng, khiến mã của tôi tăng gần 200 ký tự.

Phiên bản ung dung

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

Tôi cho rằng vẫn còn nhiều cơ hội để cải thiện, nhưng tôi khá hài lòng với điều này.

Một điều tồi tệ khác là việc sử dụng cần thiết iconv()cho danh sách các ký tự đặc biệt. Một số trong số này ( ,, ¥...) không được PHP hỗ trợ.


€ ¥, v.v. không phải là ký tự ascii, đó là lý do tại sao tập lệnh python của tôi khai báo mã hóa utf-8. Đó là một nhận xét đặc biệt được giải thích bởi python.
user80551

utf8_decodesẽ làm việc tốt cho mọi nhân vật ngoại trừ của . Đó là lý do tại sao tôi phải sử dụng iconvthay thế. Mã của tôi không tính toán các ký tự đặc biệt này giống như với các ký tự bình thường, vì chúng không theo thứ tự và tôi không thể làm việc đáng tin cậy với các giá trị ASCII tương ứng của chúng. Đó là sử dụng một danh sách bình thường cho họ.
Padarom

2

Python 3, 239 ký tự

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

1

JavaScript (E6) 291

Biên tập

Phiên bản vỏ, sử dụng vỏ spydermonkey. Đọc từ tệp 'nguồn', ghi vào 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)

Lần thử đầu tiên, hoạt động trong bảng điều khiển FireFox bằng cách sử dụng cửa sổ bật lên cho đầu vào và đầu ra

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

Có thể đọc được

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

0

VBScript 435

Không hỗ trợ ký tự không ASCII. Tôi đã ở khá xa cùng với mã của mình nên tôi nghĩ tôi sẽ đăng nó để tham khảo. Tôi không nghĩ có ai khác sử dụng phương pháp này.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.