Листи в телефонних номерах


23

Проблема:

Ви створюєте новий телефон, де люди можуть вводити спеціалізовані телефонні номери, наприклад, 1-800-programі вони будуть автоматично перетворені на номер телефону, що використовується, наприклад 1-800-7764726(для попереднього прикладу).

Ваша програма отримає рядок, якщо будь-яка довжина з цифрами, літерами та тиреми, і перетворить усі літери у відповідні номери.

Ось клавіатура, для довідки:

клавіатура

Правила:

  • Ваша програма отримає рядок
  • Він обробить його та поверне / надрукує ще один рядок
  • Будь-яка мова приймається
  • Оскільки це , виграє найкоротший код

Чи повинна програма обробляти великі та малі літери на вході?
mattnewport

3
@mattnewport - ні, припустимо, що змінна була перетворена на малі регістри
TheDoctor

Відповіді:


8

GolfScript, 24 символи

{.96>{,91,'qx'+-,3/`}*}%

Тестовий вхід:

0123456789-abcdefghijklmnopqrstuvwxyz

Тестовий вихід:

0123456789-22233344455566677778889999

Пояснення:

  • { }% застосовує код між дужками до кожного символу вводу.

  • .96>{ }* виконує код між внутрішніми дужками тоді і тільки тоді, коли код ASCII символу перевищує 96 (тобто це мала літера).

  • Перший ,перетворює символ у список усіх символів із нижчими кодами ASCII та 91,'qx'+-відфільтровує всі символи з кодами ASCII менше 91, а також літери qта xзі списку. Так, наприклад, персонаж aперетворюється на 6-символьний список [\]^_`, тоді як zперетворюється на 29-символьний список [\]^_`abcdefghijklmnoprstuvwy.

  • Другий ,підраховує елементи, що залишаються у списку, і 3/ділить це число на три (округлення вниз). Нарешті, `перетворює отримане число (у діапазоні 2 - 9) у рядок.

Таким чином, відповідно до специфікації, дефіси та цифри залишаються без змін, а малі літери відображаються в цифри відповідно до діаграми опорної клавіатури. Код буде на самому ділі чисто пройти через всі друковані символи ASCII для малих літер (які , як відображені , як описано) і символів , за винятком {, |і }(які відображаються в рядку два-символу 10). 8-бітний вхід без ASCII дасть усілякі дивні числові дані.

Зрештою, це трохи розчаровує, що це лише три шість символів б'є банальне рішення .


50

Баш, 30

Редагувати: Дякую Дорнобі за усунення 3 знаків

tr a-z 22233344455566677778889

Приклад:


10
Не можете вийняти останні 3 9с?
Дверна ручка

16

С, 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


3
Гарна математика. Просто хочу сказати, що ви можете зменшити 1 char, припустивши, що EOF дорівнює -1, і do~(c=getchar())
user12205

Ви не можете використовувати getch()замість цього getchar()?
starsplusplus

Строго кажучи, getch()це не стандартний C, тому я думаю, що він не пов'язаний в ideone. Я протестував його в MSVC у будь-якому випадку, і це насправді не працює сумно - так як він безпосередньо споживає клавіатурний вхід, немає можливості вийти з програми, хоча це перекладає те, що ви набираєте на льоту, яке виглядає дуже акуратно.
mattnewport

4

Javascript - 103 символи

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

1
Я не знав, що ти можеш це зробити з .replace. Голосуйте за вас!
SuperJedi224

Ви можете замінити charCodeAt(0)з , charCodeAt()і ви можете використовувати функцію стрілки для , function(y)...щоб зберегти кілька байт і ~~(y/3)ви можете використовуватиy/3|0
Чау Жанг

3

Рубін, 75 годин

gets.chars{|c|$><<"22233344455566677778889999#{c}"[[*?a..?z].index(c)||-1]}

Використовує застаріле за charsдопомогою блоку та друкує кожну букву окремо $><<. Мені також подобається [[*?a..?z].index(c)||-1]; він захоплює символ, відповідний цій букві алфавіту, якщо це літера, і останній символ (який, як буває, тестовий символ незмінний), якщо ні.

Рубі, 43 (або 35) символів

Відверто крадуть з @ace;)

puts gets.tr'a-z','22233344455566677778889'

Поголіть 8 символів, якщо я можу працювати в IRB зі змінною sяк рядок:

s.tr'a-z','22233344455566677778889'

3

C ++ - 222 символів

Найдовше рішення поки що:

#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;}}

1
Lol, я не думаю, що найдовше рішення - це мета тут ...
Danny

@Danny C ++ не піддається коду-гольфу . Java та C # - це лише гірші мови, про які я знаю (усі класи, створення об’єктів та довгі назви для виведення ...).
Hosch250

Я знаю, я просто думав, що це смішно, що ви згадали про "Найдовше рішення".
Денні

3

Грінка, 92

Я знаю досить багатослівну мову. Це перевіряє 8 значень замість 26, не набираючи порівняння. Чи можна зменшити будь-який із перерахованих вище "222333444 .." рішень подібним чином?

Використовуючи вбудовані конструкції, 107

co=new OrderedList
co.insertAll[charList["cfilosv{"]]
println[input[""]=~%s/([a-z])/co.binarySearch[$1]+2/eg]

Використовуючи власну рекурсивну функцію, 92

fn[x,a]:=x<=(charList["cfilosv{"])@a?a+2:fn[x,a+1]
println[input[""]=~%s/([a-z])/fn[$1,0]/eg]

+1 для зменшення методу трансляції рядків до пошуку в 8 символів. Приємний дотик.
Джонатан Ван Матре

2

Малий розмову, 79 70

вхід s:

s collect:[:c|' 22233344455566677778889999'at:1put:c;at:(($ato:$z)indexOf:c)+1]

напевно, не є кандидатом на найкоротший термін - але це може зацікавити старий трюк, щоб уникнути тесту на не знайдений стан (indexOf: повертає 0 у цьому випадку). Тому спеціального тесту на букви не потрібно. Однак деякі Smalltalks мають незмінні рядки, і нам потрібні ще 4 символи ("копія").

О, краща версія, яка навіть стосується незмінних рядків у 70 символів:

s collect:[:c|c,'22233344455566677778889999'at:(($ato:$z)indexOf:c)+1]

2

Математика 90

Звідси випливає логіка рішення @ ace:

StringReplace[#,Thread[CharacterRange["A","Z"]->Characters@"22233344455566677778889999"]]&

Приклад

StringReplace[#1,Thread[CharacterRange["A","Z"]-> 
Characters@"22233344455566677778889999"]]&["VI37889"]

8437889


Ваше представлення символів стрілки не приймається Mma в копії / вставці
доктор belisarius,

Крім того , вам не потрібно 1в #1:)
Dr. Велізар

Велісарію, я змінив стрілку назад і вийняв 1. Ще 90 знаків, але вирізати та вставити буде добре. Звичайно, ви розумієте мотивацію використовувати одну стрілку char.
DavidC

Був там, зробив це :)
доктор belisarius

2

Perl, 50

Ще одна очевидна копія відповіді туза Ейса

($_)=@ARGV;y/a-z/22233344455566677778889999/;print

1
Цей код працює правильно, але є можливість для вдосконалення. Давайте позбудемось $ ARGV [0] і скористаємося -pперемикачем, який дозволяє вам красиво пройти кожен рядок stdin. Поки ми перебуваємо на цьому, діапазон у y /// не потрібно ставити у квадратні дужки. Ми також можемо позбутися від трьох 9, залишивши лише одну та видаливши остаточну крапку з двокрапкою: -p y/a-z/22233344455566677778889/ Єдине, 30 + 1 за -p. Дякуємо, що користуєтесь Enterprise Chinese Perl Golfing і оптимізаційними послугами, і приємного дня.
китайський perl goth

2

R, дуже довго, але весело

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

2

k [32 символів]

{(.Q.a!|,/(4 3 4,5#3)#'|$2+!8)x}

Використання

{(.Q.a!|,/(4 3 4,5#3)#'|$2+!8)x}"stack exchange"
"78225 39242643"

2

JavaScript, 85

JavaScript ніколи не виграє війни у ​​гольфі, але мені це подобається, і я хотів зробити щось інше, ніж стрибати на прокладці @ace.

alert(prompt().replace(/[a-z]/g,function(a){for(i=7;a<"dgjmptw{"[i--];);return i+4}))

2

PHP, 141

Не найкоротший, але веселіший:

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

Більше читати:

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

OP сказав , що вхід вже в нижньому регістрі, так що ви можете видалитиstrtolower
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),

Я новачок у python, тож я впевнений, що повинен бути шлях до гольфу це ще більше , це інший підхід, сподіваюся, вам, хлопці, сподобається, мій боже, пітон досить!

Приклад запуску:

  • вхід: 01-800-abcdefghijklmnopqrstuvwxyz
  • вихід: 01-800-22233344455566677778889999

2

T-SQL, 216 байт

Я витратив досить багато часу протягом останніх кількох ночей, кропітко створюючи функцію математичної послідовності, яка б правильно кругла, щоб генерувати належні коди ASCII для чисел з алфавітних кодів ASCII. Це було смішне число десяткових знаків у коефіцієнтах, але воно спрацювало.

Однак раціональний підхід mattnewport працює і в SQL, набагато меншою вартістю байтів, тому я безсоромно перериваю власну математику на користь його. Ідіть, голосуйте за нього, це елегантне рішення!

Ось моя:

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

Для цього використовується рекурсивний CTE для створення імпровізованого стека символів у телефонному номері та перекладу букв на льоту, а потім трохи хитрості SQL (SELECT @ p = @ p ​​+ columnValue), щоб перекомпонувати рядок із CTE, не вимагаючи ще одна конструкція рекурсії.

Вихід:

DECLARE @s VARCHAR(MAX)='1-800-abcdefghijklmnopqrstuvwxyz'
--above code runs here
1-800-22233344455566677778889999

2

Пітон 2.7, 66 65


Анаката оригінал

for c in raw_input():print'\b'+(`(ord(c)-97)/3+2-(c in('svyz'))`if c>'`'else c),


Далі гольф

for c in input():print(ord(c)-91)/3-(c in('svyz'))if c>'`'else c,


У мене недостатньо репутації, щоб коментувати відповідь @ anakata, тому я зробив тут окремий пост. У мене була така ж ідея (з урахуванням модуля 3 постанови), але я не міг зрозуміти, як надрукувати правильні числа для s - z .

У будь-якому випадку, поліпшення гольфу я зробив:

  • змінено raw_inputнаinput

  • видалено сторонні '\b'і круглі дужки та одиничні лапки

  • зняв +2зміщення і помістив, що в початковому відніманні (97 - (3 * 2) = 91)

Тестували за допомогою інтерпретатора Python 2.7.6. За правилами передбачає введення рядка.


Ви також можете видалити пробіл між) і if
Віллем

Ти правий. good catch willem
zhehishei

1

PHP, 87

echo str_ireplace(range('a','z'),str_split('22233344455566677778889999'),fgets(STDIN));

1

q [38 символів]

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

Натхненний розчином @ ace

Приклад

{(.Q.a!"22233344455566677778889999")x}"stack exchange"
"78225 39242643"

1

XQuery, 71

BaseX використовувався як процесор XQuery. $iє вхідним.

translate($i,"abcdefghijklmnopqrstuvwxyz","22233344455566677778889999")

Не найкоротша відповідь, але досить коротка і дуже читабельна.


1

Пітон, дуже неозорий

Оскільки всі копіюють туз, я вирішив опублікувати код, який я створив, перш ніж я подав питання:

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

1

EcmaScript 6 (103 байти):

i.replace(/[a-z]/g,x=>keys(a='00abc0def0ghi0jkl0mno0pqrs0tuv0wxyz'.split(0)).find(X=>a[X].contains(x)))

Очікує, iщо містить рядок.

Спробуйте це в будь-якій останній версії Firefox. Я не пробував Google Chrome.


1

Пітон 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()))

1

Хаскелл, 93С

t[]_ a=a
t(b:c)(d:e)a
 |a==b=d
 |True=t c e a
y=map(t['a'..'z']"22233344455566677778889999")

Використання

y "1-800-program"

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

0

Пітон

import string          
trans = str.maketrans(string.ascii_lowercase,
                      '22233344455566677778889999')                                                                                         
print("1-800-ask-usps".translate(trans))

0

ECMASCRIPT, 101 (з входом)

"1-800-PROGRAM".replace(/./g,function(c){
return "22233344455566677778889999"[c.charCodeAt(0)-65]||c})

Новий рядок додано для наочності. 85 символів, якщо вхід є змінною.


0

Перл, 54

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

Стріляй, @RobHoare досі перебив мене на 4 символи. :)


0

QBasic, 155

Ах, спогади ...

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

Це повинно було бути коротшим, але я тестував за допомогою repl.it , який не дозволяє однорядкові IFоператори і веде себе дивно, якщо залишити змінну виключеною NEXT i. Він також не розпізнає ASCфункцію, тому для запуску коду потрібно додати це вирішення на початку:

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

(Вдруге запустивши його, перекладач поскаржиться, якщо ви не видалите DECLARE FUNCTIONрядок, перейдіть до рисунка.)


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="")

Приклад:

> 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.