5318008 - Diversão com calculadoras

32

Nas escolas de todo o mundo, as crianças digitam um número em sua calculadora de LCD, viram-no de cabeça para baixo e caem na gargalhada depois de criar a palavra 'Boobies'. Obviamente, essa é a palavra mais popular, mas há muitas outras que podem ser produzidas.

No entanto, todas as palavras devem ter menos de 10 letras (no entanto, o dicionário contém palavras maiores que isso, portanto, você deve executar um filtro no seu programa). Neste dicionário, existem algumas palavras em maiúsculas, portanto, converta todas as palavras em minúsculas.

Usando um dicionário do idioma inglês, crie uma lista de números que podem ser digitados em uma calculadora LCD e faça uma palavra. Como em todas as perguntas sobre código de golfe, o programa mais curto para concluir esta tarefa vence.

Para meus testes, usei a lista de palavras UNIX, reunida digitando:

ln -s /usr/dict/words w.txt

Ou, alternativamente, obtenha-o aqui .

Por exemplo, a imagem acima foi criada digitando o número 35007na calculadora e virando-o de cabeça para baixo.

As letras e seus respectivos números:

  • b :8
  • g :6
  • l :7
  • i :1
  • o :0
  • s :5
  • z :2
  • h :4
  • e :3

Observe que, se o número começar com zero, será necessário um ponto decimal depois desse zero. O número não deve começar com um ponto decimal.

Eu acho que esse é o código da MartinBüttner, só queria creditar você por ele :)

/* Configuration */

var QUESTION_ID = 51871; // Obtain this from the url
// It will be like http://XYZ.stackexchange.com/questions/QUESTION_ID/... on any question page
var ANSWER_FILTER = "!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";

/* App */

var answers = [], page = 1;

function answersUrl(index) {
  return "http://api.stackexchange.com/2.2/questions/" +  QUESTION_ID + "/answers?page=" + index + "&pagesize=100&order=desc&sort=creation&site=codegolf&filter=" + ANSWER_FILTER;
}

function getAnswers() {
  jQuery.ajax({
    url: answersUrl(page++),
    method: "get",
    dataType: "jsonp",
    crossDomain: true,
    success: function (data) {
      answers.push.apply(answers, data.items);
      if (data.has_more) getAnswers();
      else process();
    }
  });
}

getAnswers();

var SIZE_REG = /\d+(?=[^\d&]*(?:<(?:s>[^&]*<\/s>|[^&]+>)[^\d&]*)*$)/;
var NUMBER_REG = /\d+/;
var LANGUAGE_REG = /^#*\s*([^,]+)/;

function shouldHaveHeading(a) {
  var pass = false;
  var lines = a.body_markdown.split("\n");
  try {
    pass |= /^#/.test(a.body_markdown);
    pass |= ["-", "="]
              .indexOf(lines[1][0]) > -1;
    pass &= LANGUAGE_REG.test(a.body_markdown);
  } catch (ex) {}
  return pass;
}

function shouldHaveScore(a) {
  var pass = false;
  try {
    pass |= SIZE_REG.test(a.body_markdown.split("\n")[0]);
  } catch (ex) {}
  return pass;
}

function getAuthorName(a) {
  return a.owner.display_name;
}

function process() {
  answers = answers.filter(shouldHaveScore)
                   .filter(shouldHaveHeading);
  answers.sort(function (a, b) {
    var aB = +(a.body_markdown.split("\n")[0].match(SIZE_REG) || [Infinity])[0],
        bB = +(b.body_markdown.split("\n")[0].match(SIZE_REG) || [Infinity])[0];
    return aB - bB
  });

  var languages = {};
  var place = 1;
  var lastSize = null;
  var lastPlace = 1;
  answers.forEach(function (a) {
    var headline = a.body_markdown.split("\n")[0];
    //console.log(a);
    var answer = jQuery("#answer-template").html();
    var num = headline.match(NUMBER_REG)[0];
    var size = (headline.match(SIZE_REG)||[0])[0];
    var language = headline.match(LANGUAGE_REG)[1];
    var user = getAuthorName(a);
    if (size != lastSize)
      lastPlace = place;
    lastSize = size;
    ++place;
    answer = answer.replace("{{PLACE}}", lastPlace + ".")
                   .replace("{{NAME}}", user)
                   .replace("{{LANGUAGE}}", language)
                   .replace("{{SIZE}}", size)
                   .replace("{{LINK}}", a.share_link);
    answer = jQuery(answer)
    jQuery("#answers").append(answer);

    languages[language] = languages[language] || {lang: language, user: user, size: size, link: a.share_link};
  });

  var langs = [];
  for (var lang in languages)
    if (languages.hasOwnProperty(lang))
      langs.push(languages[lang]);

  langs.sort(function (a, b) {
    if (a.lang > b.lang) return 1;
    if (a.lang < b.lang) 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);
  }

}
body { text-align: left !important}

#answer-list {
  padding: 10px;
  width: 50%;
  float: left;
}

#language-list {
  padding: 10px;
  width: 50%px;
  float: left;
}

table thead {
  font-weight: bold;
}

table td {
  padding: 5px;
}
<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="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>
<div id="language-list">
  <h2>Winners 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>
<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>

Beta Decay
fonte
4
Pode usar um ponto decimal após o primeiro número, mesmo que não seja obrigatório?
Dennis
11
Nós temos que digitar 0.7734para Olá ou iria .7734ser aceitável?
Dennis
3
Qual é o comportamento correto se o dicionário contiver palavras com maiúsculas, pontuação, etc?
Peter Taylor
11
@Dennis 0.7734é obrigatório
Decay Beta
4
E as palavras que exigem um zero à direita após o decimal? Por exemplo, oligorequer um zero à direita após o decimal:0.6170
Sr. Llama

Respostas:

7

CJam, 44 42 bytes

r{el"oizehsglb"f#W%"0."a.e|N+_,B<*_W&!*r}h

Experimente online no intérprete CJam .

Para executar o programa na linha de comando, faça o download do interpretador Java e execute:

java -jar cjam-0.6.5.jar 5318008.cjam < /usr/share/dict/words

Como funciona

r            e# Read a whitespace-separated token from STDIN.
{            e# While loop:
 el          e#   Convert to lowercase.
 "oizehsglb" e#   Push that string.
 f#          e#   Get the index of each character from the input in that string.
             e#   This pushes -1 for "not found".
 W%          e#   Reverse the resulting array.
 "0."a       e#   Push ["0."].
 .e|         e#   Vectorized logical NOT. This replaces an initial 0 with "0.".
 N+          e#   Append a linefeed.
 _,B<*       e#   Repeat the array (array.length < 11) times.
 _W&!*       e#   Repeat the array !(array.intersection(-1)) times.
 r           e#   Read a whitespace-separated token from STDIN.
}h           e# If the token is not empty, repeat the loop.
Dennis
fonte
9

Bash + coreutils, 54

Mais uma vez, obrigado a @TobySpeight pela ajuda no golfe.

rev|tr oizehsglb 0-8|sed '/.\{11\}\|[^0-9]/d;s/^0/&./'

A lista de palavras de entrada é retirada de STDIN:

$ ./5318008.sh < /usr/share/dict/words | head
8
38
338
5338
638
5638
36138
31738
531738
7738
$ 
Trauma Digital
fonte
"Belie" e "Belies" são palavras? Quanto mais você sabe ...
clismique 16/03/16
6

Python 2, 271 216 211 205 bytes

Esta é a única idéia que tive até agora. Atualizarei isso assim que pensar em outra coisa! Presumi que precisávamos ler de um arquivo, mas, se não, deixe-me saber para que eu possa atualizar :)

Muito obrigado a Dennis por me salvar 55 bytes :)

Também obrigado ao Sp3000 por salvar 6 bytes :)

d,f,g='oizehsglb',[x.lower()for x in open('w.txt').read().split('\n')if len(x)<10],[]
for x in f:
 c=x[::-1]
 for b in d:c=c.replace(b,`d.find(b)`)
 g=[g,g+[['0.'+c[1:],c][c[0]!='0']]][c.isdigit()]
print g
Kade
fonte
Eu não conheço muito Python, mas não seria algo "oizehsglb".index(b)mais curto?
21715 Dennis
3
d[b] == "oizehsglb".index(b). Possivelmente sem elenco para string / personagem.
217 Dennis
11
Oh, uau, nunca me ocorreu que os números que pudéssemos substituir tinham valores numéricos em ordem .. Sim, isso definitivamente funcionará! Obrigado!
Kade
11
Não foram testados, mas: 1) .findé menor que .index, 2) Dependendo da versão que você possui, pelo menos no 2.7.10 opensem um argumento de modo padrão r, 3) Não for x in open(...)funciona? (pode ser necessário remover uma nova linha à direita) Se não o fizer, .split('\n')será menor que.splitlines()
Sp3000 20/15/15
11
Além disso g+=[['0.'+c[1:],c][c[0]!='0']]*c.isdigit(), você pode economizar um pouco mais, revertendo fe fazendo, em for c in fvez de ter c=x[::-1]. Além disso, você só usa fuma vez, para que você não precisa salvá-lo como uma variável
SP3000
6

JavaScript (ES7), 73 bytes

Isso pode ser feito no ES7 apenas 73 bytes:

s=>[for(w of s)'oizehsglb'.search(w)].reverse().join``.replace(/^0/,'0.')

Ungolfed:

var b = function b(s) {
    return s.length < 10 && /^[bglioszhe]*$/.test(s) ? s.replace(/./g, function (w) {
        return 'oizehsglb'.search(w);
    }).reverse().join('').replace(/^0/, '0.') : '';
};

Uso:

t('hello'); // 0.7734
t('loose'); // 35007
t('impossible'); //

Função:

t=s=>                       // Create a function 't' with an argument named 's' 
   [                        // Return this array  comprehension
     for(i of s)            // Loops through each letter in the string
     'oizehsglb'.search(w)  // Converts it to it's corresponding number
   ]
  .reverse().join``         // Reverse the array and make it a string
  .replace(/^0/,'0.')       // If the first character is a 0, add a decimal after it

Eu executei isso na lista de palavras UNIX e coloquei os resultados em uma lixeira:

Resultados

O código usado para obter os resultados no Firefox :

document.querySelector('pre').innerHTML.split('\n').map(i => t(i.toLowerCase())).join('\n').replace(/^\s*[\r\n]/gm, '');
Downgoat
fonte
O que acontece com t('Impossible')?
Arturo Torres Sánchez
@ ArturoTorresSánchez Você está certo, eu fixo que
Downgoat
é join`` ES2015 ou é pré-ES2015?
21315 WallyWest
@WallyWest Esse é um recurso do ES6. É suportado na maioria dos navegadores principais.
Downgoat
O que é específico do ES7 nisso?
Arjun
5

Python 2, 121 bytes

for s in open("w.txt"):
 L=map("oizehsglb".find,s[-2::-1].lower())
 if-min(L)<1>len(L)-9:print`L[0]`+"."[L[0]:]+`L`[4::3]

Supõe que o arquivo do dicionário w.txttermine com uma nova linha à direita e não tenha linhas vazias.

Sp3000
fonte
3

GNU sed, 82

(incluindo 1 para -r)

Obrigado a @TobySpeight pela ajuda no golfe.

s/$/:/
:
s/(.)(:.*)/\2\1/
t
s/://
y/oizehsglb/012345678/
/.{11}|[^0-9]/d;s/^0/&./

A lista de palavras de entrada é retirada de STDIN:

$ sed -rf 5318008.sed /usr/share/dict/words | tail
3705
53705
1705
0.705
50705
5705
505
2
0.02
5002
$ 
Trauma Digital
fonte
2

TI-BASIC, 75 88 bytes

editar 2: não importa, isso ainda é tecnicamente inválido, pois aceita apenas uma palavra por vez (não um dicionário). Vou tentar corrigi-lo para permitir mais de uma palavra como entrada ...

edit: oops; Eu originalmente fiz mostrar um 0 no final se o último número fosse 0, e não o contrário. Corrigido, embora essa seja uma solução alternativa ruim (exibe "0" ao lado do número se começar com 0, caso contrário, exibe dois espaços no mesmo local). No lado positivo, ele manipula corretamente palavras como "Otto" (exibe os dois 0s), pois na verdade não está exibindo um número decimal!


Não consigo pensar em um idioma melhor para fazer isso. Definitivamente, posso jogar mais, mas estou cansado demais agora. O til é o símbolo de negação [o ( - )botão].

A entrada é retirada da variável de resposta da calculadora, ou seja, o que foi avaliado pela última vez (como _no shell interativo do python), para que você tenha que digitar uma string na tela inicial (as aspas estão ativadas ALPHA+), pressione e ENTER, em seguida, execute o programa. Como alternativa, você pode usar dois pontos para separar comandos; portanto, se você nomear o programa, diga "CALCTEXT" e quiser executá-lo na cadeia "HELLO", poderá digitar em "HELLO":prgmCALCTEXTvez de executá- los separadamente.

seq(inString("OIZEHSGLB",sub(Ans,X,1))-1,X,length(Ans),1,~1
Text(0,0,sub("0.  ",1+2(0 or Ans(1)),2),sum(seq(Ans(X)10^(dim(Ans)-X),X,1,dim(Ans
MI Wright
fonte
2

Python 2, 147 158 156 bytes

Estava faltando esse '0'. requerimento. Espero que agora funcione bem.

edit : Removido ".readlines ()" e ainda funciona; p

edit2 : Removidos alguns espaços e mova print para a terceira linha

edit3 : salvou 2 bytes graças ao Sp3000 (espaço removido após a impressão e alterado 'index' para 'find')

for x in open("w.txt"):
 a="oizehsglb";g=[`a.find(b)`for b in x[::-1].lower()if b in a]
 if len(g)==len(x)-1<10:
  if g[0]=="0":g[0]="0."
  print"".join(g)
heo
fonte
1

Python 2, 184 174 bytes

for s in open('w.txt'):
 try:a=''.join(map(lambda c:dict(zip('bglioszhe','867105243'))[c],s[:-1][::-1]));a=[a,'0.'+a[1:]][a[0]=='0'];print['',''.join(a)][len(s)<11]
 except:0
dieter
fonte
1

Ruby 2, 88 86 bytes

x="oizehsglb"
puts$_.tr(x,"0-8").reverse.sub /^0/,"0." if$_.size<11&&$_.delete(x)<?A

A contagem de bytes inclui 2 para as lnopções na linha de comandos:

$ ruby -ln 5318008.rb wordlist.txt
daniero
fonte
Nesse caso, ==""pode ser substituído por <?A. E não há necessidade de gsub()como sub()é suficiente.
manatwork
1

C, 182 172 169/181 172 bytes

char*l="oizehsglb",S[99],*s,*t;main(x){for(;t=S+98,gets(S);){for(s=S;*s;s++)if(x=strchr(l,*s|32))*--t=48+x-(int)l;else break;*t==48?*t--=46,*t=48:0;*s||s-S>10?0:puts(t);}}

Expandido

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *l="oizehsglb",S[99],*s,*t;

main(int x, char **argv)
{
    for (;t=S+98,gets(S);){
        for (s=S;*s;s++)
            if (x=strchr(l,*s|32))
                *--t=48+x-(int)l;
            else
                break;
        if (*t==48) {       // '0'
            *t--=46;        // '.'
            *t=48;  // '0'
        }

        if (!*s && s-S <= 10)
            puts(t);
    }
}

usando as palavras vinculadas.txt, com conversão em minúsculas:

$ ./a.out  < words.txt  | tail
2212
0.2
0.802
0.602
7702
37702
0.02
321607002
515002
0.02002

$ ./a.out < words.txt   | wc -l
 550
algum usuário
fonte
11
Não *s|32funcionará como conversão em minúsculas nesse contexto?
Hagen von Eitzen
Boa ideia! Obrigado!
algum usuário
1

Haskell, 175 bytes sem importações (229 bytes com importações)

Código relevante (digamos no Arquivo Calc.hs):

import Data.Char(toLower)
import Data.Maybe(mapMaybe)
s="oizehsglb\n"
g('0':r)="0."++r
g x=x
main=mapM_(putStrLn.g.reverse.mapMaybe(`lookup`zip s['0'..'8'])).filter(\l->length l<10&&all(`elem`s)l).lines.map toLower=<<getContents

$ cat /usr/share/dict/words | runghc Calc.hs
saep
fonte
0

Java, 208 200 176 bytes

String f(char[] w){String o="",l="oizehsglb";for(int i=w.length;i>0;i--)o+=l.indexOf(w[i-1]|32);if(o.contains("-")||o.length()>8)o="  ";return o.charAt(0)+"."+o.substring(1);}

Expandido

String f(char[] w)
{
    String o = "", l = "oizehsglb";
    for(int i = w.length; i > 0; i--)
        o+=l.indexOf(w[i-1]|32);
    if(o.contains("-")||o.length() > 8)
        o = "  ";
    return o.charAt(0) + "." + o.substring(1);
}

Ele sempre adiciona o decimal e, quando inválido, retorna ".". Mas, caso contrário, funciona como deveria. : P

Obrigado @ LegionMammal978!

Whitcomb L. Judson
fonte
Você pode salvar 7 bytes alterando ;String l=para ,l=e =o+para +=.
LegionMammal978