Hitung penekanan tombol ponsel

15

Tugas Anda adalah menghitung jumlah total penekanan tombol yang diperlukan untuk memasukkan teks yang diberikan pada ponsel lama.

Intinya adalah:

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

Untuk mengetik exaMPle TExt 01, Anda akan menekan 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 1total 37 penekanan tombol.

The *key membawa peta karakter khusus:

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

dengan yang pertama ( .) disorot. Anda dapat bergerak untuk menyorot karakter yang diperlukan menggunakan tombol navigasi persegi panjang dan perlu penekanan tombol lain untuk memilih.

Jadi untuk memasukkan $, Anda akan menekan *↓↓↓↓→→→<select>yaitu total 9 penekanan tombol.

  • Input akan berasal dari file yang disebut sourceditempatkan di direktori / direktori program Anda saat ini. EDIT: Per permintaan dalam komentar, saya menambahkan STDINsebagai metode input yang valid. Permintaan maaf untuk mengubah spesifikasi setelah menerima jawaban.
  • Anda harus mengeluarkan Total key presses <total_keypresses>
  • Jika file input berisi karakter apa pun yang tidak ada dalam keymap yang diberikan, maka program Anda harus Invalid character <character> in sourcekeluar dan keluar.

Singkatnya, input dan output dari program Anda harus mirip dengan skrip python (ungolfed) ini:

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

Ini adalah kode-golf, program terpendek dalam byte yang menang.


Penafian tak tahu malu: Saya membuat tantangan ini untuk memiliki terjemahan skrip python di atas dalam berbagai bahasa yang akan digunakan untuk menilai tantangan ini di kotak pasir .

pengguna80551
sumber
Haruskah kita melakukan kesalahan dan segera keluar atau ketika karakter yang tidak valid ditemukan?
nyuszika7h
@ nyuszika7h Terserah Anda, tetapi Anda harus mencetak karakter apa yang tidak valid itu. Misalkan ada 10 karakter tidak valid dalam sumber, Anda dapat memilih salah satu dari mereka, cetak bahwa karakter itu tidak valid dan keluar. Itu tidak harus menjadi kejadian pertama dari karakter yang tidak valid.
user80551
7
Persyaratan input sangat memalukan. File I / O sangat mahal di beberapa bahasa dan sama sekali tidak mungkin dalam bahasa lain.
Dennis
1
Jika Anda mengizinkan lebih banyak IO bentuk bebas, saya punya solusi J dari 171 karakter, siapa yang harus hash 1ce5a2fdd0316e37c0a07d151d02db766a3adbb7.
ɐɔıʇǝɥʇuʎ
2
@Dennis

Jawaban:

4

GolfScript, 219 karakter

Pendekatan dasar menggunakan tabel pencarian:

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

Coba di sini .

Howard
sumber
1
Bagus sekali :) Delphi menyebalkan lol ini .. baru saja selesai tambang dan saya pada 459 xD perlu ditingkatkan!
Teun Pronk
1
Input harus dari file bernama source, bukan STDIN
user80551
Untuk membaca dari file, pinjam dari ruby:"#{File.read('source')}"
Justin
1
@ Quincunx Anda dapat melepaskan tanda kurung dari itu:"#{File.read'source'}"
Ventero
Anda dapat menyimpan ini apa adanya, saya mengizinkan STDIN sekarang.
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 #$."

Skema pengkodean yang sangat sederhana sejauh ini: lebih dari 75% karakter digunakan untuk string / array literal ...

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

Program ini memiliki 207 karakter. Dengan penyandian yang sesuai (Windows-1252), ini cocok dengan 207 byte.

Perhatikan bahwa Stack Exchange mengonversi tab (yang saya gunakan sebagai pembatas di tabel pencarian) menjadi spasi, jadi Anda tidak dapat menyalin dan menempelkan kode di atas.

Pemakaian

Pengkodean 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

Pengkodean 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
sumber
2

PHP, 711 708 676 karakter (membaca dari STDIN sekarang)

<?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 pertamaku sejauh ini :)

Ingin mencoba pendekatan yang agak tidak konvensional. Alih-alih memiliki daftar setiap karakter dan berapa banyak klik yang diperlukan untuk membuatnya, saya menggunakan nilai ASCII karakter dan menghitung penekanan tombol yang diperlukan. Saya pikir itu akan memberi saya beberapa karakter pertama, sekarang saya pikir itu bahkan lebih lama dari pendekatan array.

Masalah utama saya adalah tombol 7 dan 9, yang memiliki 4 huruf, bukan 3. Oleh karena itu saya perlu membuat beberapa fallback, yang meledakkan kode saya hingga hampir 200 karakter.

Versi tidak disatukan

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

Saya berasumsi masih ada banyak ruang untuk perbaikan, tapi saya cukup senang dengan ini.

Hal buruk lainnya adalah penggunaan yang diperlukan iconv()untuk daftar karakter khusus. Beberapa di antaranya ( ,, ¥...) tidak didukung oleh PHP.

Padarom
sumber
€ ¥, dll bukan karakter ascii, itu sebabnya skrip python saya mendeklarasikan pengkodean utf-8. Itu adalah komentar khusus yang ditafsirkan oleh python.
user80551
utf8_decodeakan bekerja dengan baik untuk setiap karakter kecuali dari . Itu sebabnya saya harus menggunakannya iconv. Kode saya tidak menghitung karakter khusus ini seperti halnya dengan karakter normal, karena tidak berurutan dan saya tidak dapat bekerja dengan andal dengan nilai ASCII masing-masing. Itu menggunakan daftar normal untuk mereka.
Padarom
2

Python 3, 239 karakter

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
sumber
1

JavaScript (E6) 291

Edit

Versi shell, menggunakan shell spydermonkey. Baca dari file 'sumber', tulis ke 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)

Coba pertama, berfungsi di konsol FireFox menggunakan popup untuk input dan output

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

Dapat dibaca

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
sumber
0

VBScript 435

Tidak mendukung karakter non-ASCII. Saya cukup jauh dengan kode saya jadi saya pikir saya akan mempostingnya untuk referensi. Saya tidak berpikir orang lain menggunakan pendekatan ini.

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
nyaman
sumber