Digitação do teclado do telefone celular
Esta pergunta foi feita há um tempo, mas foi encerrada devido a especificações ruins. Então, estou refazendo, com especificações melhores. Esta questão está relacionada, mas segue na direção oposta.
Antes da criação do T9, para digitar um caractere em uma mensagem de texto, era necessário pressionar uma das teclas numéricas várias vezes para obter o caractere desejado. Para referência, aqui está o mapeamento padrão:
+-------+-------+-------+
| 1 | 2 | 3 |
| .?!1 | ABC2 | DEF3 |
+-------+-------+-------+
| 4 | 5 | 6 |
| GHI4 | JKL5 | MNO6 |
+-------+-------+-------+
| 7 | 8 | 9 |
| PQRS7 | TUV8 | WXYZ9 |
+-------+-------+-------+
| * | 0 | # |
| ← |SPACE 0| → |
+-------+-------+-------+
*
é backspace, 0
é um espaço ( ' '
) ou o número 0
e #
confirma o caractere atual. Por uma questão de simplicidade, todos os caracteres estão em maiúsculas.
Quando você pressionar uma tecla várias vezes, os ciclos de caracteres selecionados através dos caracteres possíveis para essa chave: 2 -> A
, 22 -> B
, 222 -> C
, 2222 -> 2
, 22222 -> A
, e assim por diante. Observe que, como *
só há uma opção, pressionar repetidamente faz com que vários backspaces sejam inseridos. Pressionar #
várias vezes seguidas não tem efeito. Um final #
é desnecessário.
Além disso, se uma tecla diferente for pressionada imediatamente após pressionar uma tecla, o pressionamento anterior é confirmado automaticamente. Assim, 223
é funcionalmente idêntico a 22#3
.
Seu desafio é traduzir uma série de pressionamentos de teclas na sequência correspondente que um telefone celular exibirá.
Exemplos
8#99999#055#33#999#22#666#2#777#3#1 -> T9 KEYBOARD
4433555#55566609666666677755533*3111 -> HELLO WORLD!
7##222#222**7#222#4 -> PPCG
00#0#00 -> 0 0
Regras
- Isso é código-golfe , então a solução correta mais curta (em bytes) vence
- A resposta vencedora será escolhida em uma semana
- As brechas padrão são proibidas
- Sua resposta pode estar na forma de um programa completo, uma função nomeada ou anônima, recebendo entrada e produzindo saída em um dos métodos padrão
Entre os melhores
O snippet de pilha na parte inferior desta postagem gera o cabeçalho das respostas a) como uma lista da solução mais curta por idioma eb) como um cabeçalho geral.
Para garantir que sua resposta seja exibida, inicie-a com um título, usando o seguinte modelo de remarcação:
## Language Name, N bytes
onde N
está o tamanho do seu envio. Se você melhorar sua pontuação, poderá manter as pontuações antigas no título, identificando-as. Por exemplo:
## Ruby, <s>104</s> <s>101</s> 96 bytes
Se você quiser incluir vários números em seu cabeçalho (por exemplo, porque sua pontuação é a soma de dois arquivos ou deseja listar as penalidades de sinalizador de intérprete separadamente), verifique se a pontuação real é o último número no cabeçalho:
## Perl, 43 + 2 (-p flag) = 45 bytes
Você também pode transformar o nome do idioma em um link que será exibido no snippet:
## [><>](http://esolangs.org/wiki/Fish), 121 bytes
<style>body { text-align: left !important} #answer-list { padding: 10px; width: 290px; float: left; } #language-list { padding: 10px; width: 290px; float: left; } table thead { font-weight: bold; } table td { padding: 5px; }</style><script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="language-list"> <h2>Shortest Solution by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr> </thead> <tbody id="languages"> </tbody> </table> </div> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr> </thead> <tbody id="answers"> </tbody> </table> </div> <table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr> </tbody> </table><script>var QUESTION_ID = 61545; var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe"; var COMMENT_FILTER = "!)Q2B_A2kjfAiU78X(md6BoYk"; var OVERRIDE_USER = 45941; var answers = [], answers_hash, answer_ids, answer_page = 1, more_answers = true, comment_page; function answersUrl(index) { return "https://api.stackexchange.com/2.2/questions/" + QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER; } function commentUrl(index, answers) { return "https://api.stackexchange.com/2.2/answers/" + answers.join(';') + "/comments?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + COMMENT_FILTER; } function getAnswers() { jQuery.ajax({ url: answersUrl(answer_page++), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { answers.push.apply(answers, data.items); answers_hash = []; answer_ids = []; data.items.forEach(function(a) { a.comments = []; var id = +a.share_link.match(/\d+/); answer_ids.push(id); answers_hash[id] = a; }); if (!data.has_more) more_answers = false; comment_page = 1; getComments(); } }); } function getComments() { jQuery.ajax({ url: commentUrl(comment_page++, answer_ids), method: "get", dataType: "jsonp", crossDomain: true, success: function (data) { data.items.forEach(function(c) { if (c.owner.user_id === OVERRIDE_USER) answers_hash[c.post_id].comments.push(c); }); if (data.has_more) getComments(); else if (more_answers) getAnswers(); else process(); } }); } getAnswers(); var SCORE_REG = /<h\d>\s*([^\n,<]*(?:<(?:[^\n>]*>[^\n<]*<\/[^\n>]*>)[^\n,<]*)*),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/; var OVERRIDE_REG = /^Override\s*header:\s*/i; function getAuthorName(a) { return a.owner.display_name; } function process() { var valid = []; answers.forEach(function(a) { var body = a.body; a.comments.forEach(function(c) { if(OVERRIDE_REG.test(c.body)) body = '<h1>' + c.body.replace(OVERRIDE_REG, '') + '</h1>'; }); var match = body.match(SCORE_REG); if (match) valid.push({ user: getAuthorName(a), size: +match[2], language: match[1], link: a.share_link, }); else console.log(body); }); valid.sort(function (a, b) { var aB = a.size, bB = b.size; return aB - bB }); var languages = {}; var place = 1; var lastSize = null; var lastPlace = 1; valid.forEach(function (a) { if (a.size != lastSize) lastPlace = place; lastSize = a.size; ++place; var answer = jQuery("#answer-template").html(); answer = answer.replace("{{PLACE}}", lastPlace + ".") .replace("{{NAME}}", a.user) .replace("{{LANGUAGE}}", a.language) .replace("{{SIZE}}", a.size) .replace("{{LINK}}", a.link); answer = jQuery(answer); jQuery("#answers").append(answer); var lang = a.language; lang = jQuery('<a>'+lang+'</a>').text(); languages[lang] = languages[lang] || {lang: a.language, lang_raw: lang.toLowerCase(), user: a.user, size: a.size, link: a.link}; }); var langs = []; for (var lang in languages) if (languages.hasOwnProperty(lang)) langs.push(languages[lang]); langs.sort(function (a, b) { if (a.lang_raw > b.lang_raw) return 1; if (a.lang_raw < b.lang_raw) return -1; return 0; }); for (var i = 0; i < langs.length; ++i) { var language = jQuery("#language-template").html(); var lang = langs[i]; language = language.replace("{{LANGUAGE}}", lang.lang) .replace("{{NAME}}", lang.user) .replace("{{SIZE}}", lang.size) .replace("{{LINK}}", lang.link); language = jQuery(language); jQuery("#languages").append(language); } }</script>
2 -> A
,22 -> B
...,2222 -> A
....) não permite que nenhum número seja produzido.Respostas:
K5, 112 bytes
Este é realmente uma bagunça, mas acho que há uma boa quantidade de espaço para jogar golfe.
Primeiro, precisamos construir uma tabela de pesquisa para o mapa de teclas. Existem chaves com 2, 4 e 5 caracteres mapeados para elas, portanto, preencher cada entrada até 20 simplifica o processo de indexar ciclicamente esta tabela posteriormente:
Em seguida, divido a entrada em execuções:
Solte todas as # corridas e descasque as corridas sempre que encontrar um *:
E então eu estou pronto para simplesmente indexar nessa tabela de pesquisa com base no comprimento e no primeiro elemento de cada execução.
Todos juntos:
Editar:
Economize 5 bytes:
fonte
(20#'((" ";".?!"),0 3 6 9 12 15 19 22_`c$65+!26),'$!10)
para(20#'((" ";".?!"),((3*!6),19 22)_`c$65+!26),'$!10)
.Python 2,
230206 bytesEssa cria uma função f que usa uma sequência de teclas pressionadas como argumento e retorna a sequência correspondente que um telefone celular exibia. Também ocorre com um segundo argumento opcional como um mapeamento de dicionário para os caracteres correspondentes, por exemplo, {"0": "0", "1": ".?! 1", ...} .
Primeiro, a sequência de pressionamentos de teclas é agrupada por caracteres repetidos, por exemplo, ["8", "#", "99999", "#", ...] . Em seguida, o primeiro caractere de cada grupo é mapeado no dicionário passado como segundo argumento, por exemplo, 9 mapeia para o WXYZ9 . Por fim, o comprimento do grupo é usado como deslocamento no valor do dicionário.
Observe que o deslocamento deve usar o módulo no comprimento do grupo de caracteres repetidos, porque as teclas pressionadas podem alternar. Observe também que o caractere # é mapeado para \ 0 e removido apenas no final porque 99 # 99 não é o mesmo que 9999 .
Aqui está a saída da função para cada um dos exemplos na pergunta:
fonte
JavaScript,
214184168162 bytesProvavelmente isso pode ser um pouco menor, mas estou muito feliz com o resultado. Divide os caracteres em grupos repetidos de um ou mais e, em seguida, percorre a matriz, mapeando cada caractere para seu valor no hash e adicionando-o à sequência final. Se encontrar qualquer número de '#', ele será ignorado. Se encontrar algum '*', ele removerá esse número do final da sequência final.
fonte
Python 2, 237 bytes
Usando o dicionário de cr3, mas sem re.
fonte
Python 2, 265 bytes
É muito longo. IO: stdin, stdout.
fonte