5318008 - Diversión con calculadoras

32

En las escuelas de todo el mundo, los niños escriben un número en su calculadora LCD, lo ponen boca abajo y se echan a reír después de crear la palabra 'Bobos'. Por supuesto, esta es la palabra más popular, pero hay muchas otras palabras que se pueden producir.

Sin embargo, todas las palabras deben tener menos de 10 letras (sin embargo, el diccionario contiene palabras más largas que esta, por lo que debe realizar un filtro en su programa). En este diccionario, hay algunas palabras en mayúscula, por lo tanto, convierta todas las palabras en minúsculas.

Usando un diccionario de idioma inglés, cree una lista de números que se pueden escribir en una calculadora LCD y crea una palabra. Al igual que con todas las preguntas de código de golf, gana el programa más corto para completar esta tarea.

Para mis pruebas, utilicé la lista de palabras UNIX, reunida escribiendo:

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

O, alternativamente, consíguelo aquí .

Por ejemplo, la imagen de arriba se creó escribiendo el número 35007en la calculadora y dándole la vuelta.

Las letras y sus respectivos números:

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

Tenga en cuenta que si el número comienza con un cero, se requiere un punto decimal después de ese cero. El número no debe comenzar con un punto decimal.

Creo que este es el código de MartinBüttner, solo quería acreditarte por ello :)

/* 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>

Decaimiento Beta
fuente
44
¿Se puede usar un punto decimal después del primer número incluso si no es necesario?
Dennis
1
¿Tenemos que escribir 0.7734para hola o sería .7734aceptable?
Dennis
3
¿Cuál es el comportamiento correcto si el diccionario contiene palabras en mayúscula, puntuación, etc.?
Peter Taylor
1
@Dennis 0.7734es obligatorio
Beta Decay
44
¿Qué pasa con las palabras que requieren un cero al final del decimal? Por ejemplo, oligorequiere un cero detrás después del punto decimal:0.6170
Sr. Llama

Respuestas:

7

CJam, 44 42 bytes

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

Pruébelo en línea en el intérprete de CJam .

Para ejecutar el programa desde la línea de comandos, descargue el intérprete de Java y ejecute:

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

Cómo 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
fuente
9

Bash + coreutils, 54

Nuevamente, gracias a @TobySpeight por la ayuda en el golf.

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

La lista de palabras de entrada se toma de STDIN:

$ ./5318008.sh < /usr/share/dict/words | head
8
38
338
5338
638
5638
36138
31738
531738
7738
$ 
Trauma digital
fuente
"Belie" y "Belies" son palabras? Cuanto más sepa ...
clismique
6

Pitón 2, 271 216 211 205 Bytes

Esta es la única idea que he tenido hasta ahora ... ¡Actualizaré esto una vez que piense en otra cosa! Supuse que necesitábamos leer de un archivo, pero si no, hágamelo saber para que pueda actualizar :)

Muchas gracias a Dennis por salvarme 55 bytes :)

También gracias a Sp3000 por guardar 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
fuente
No conozco mucho Python, pero ¿no sería algo "oizehsglb".index(b)más corto?
Dennis
3
d[b] == "oizehsglb".index(b). Posiblemente carezca de un elenco para cadena / personaje.
Dennis
1
Oh, wow, nunca se me ocurrió que los números que pudimos reemplazar tenían valores numéricos en orden ... ¡Sí, eso definitivamente funcionará! ¡Gracias!
Kade
1
No lo he probado pero: 1) .findes más corto que .index, 2) Dependiendo de la versión que tenga, al menos en 2.7.10 opensin un argumento de modo predeterminado r, 3) ¿No for x in open(...)funciona? (puede que sea necesario eliminar una nueva línea final) Si no es así, entonces .split('\n')es más corta que.splitlines()
Sp3000
1
Además g+=[['0.'+c[1:],c][c[0]!='0']]*c.isdigit(), y puede ahorrar algunos más invirtiendo y fluego haciendo en for c in flugar de tener c=x[::-1]. Además, solo lo usa funa vez, por lo que no necesita guardarlo como una variable
Sp3000
6

JavaScript (ES7), 73 bytes

Esto se puede hacer en ES7 a solo 73 bytes:

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

Sin golf:

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

Función:

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

Ejecuté esto en la lista de palabras de UNIX y puse los resultados en una papelera:

Resultados

El código utilizado para obtener los resultados en Firefox :

document.querySelector('pre').innerHTML.split('\n').map(i => t(i.toLowerCase())).join('\n').replace(/^\s*[\r\n]/gm, '');
Downgoat
fuente
¿Qué ocurre con t('Impossible')?
Arturo Torres Sánchez
@ ArturoTorresSánchez Tienes razón, lo arreglé
Downgoat
es join`` ES2015 o es anterior a ES2015?
WallyWest
@WallyWest Esa es una característica de ES6. Es compatible con la mayoría de los principales navegadores
Downgoat
¿Qué es ES7 específico en esto?
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]

Asume que el archivo del diccionario w.txttermina con una nueva línea final y no tiene líneas vacías.

Sp3000
fuente
3

GNU sed, 82

(incluido 1 para -r)

Gracias a @TobySpeight por la ayuda en el golf.

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

La lista de palabras de entrada se toma 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
fuente
2

TI-BASIC, 75 88 bytes

editar 2: no importa, esto todavía es técnicamente inválido, ya que solo acepta una palabra a la vez (no un diccionario). Trataré de arreglarlo para permitir más de una palabra como entrada ...

editar: oops; Originalmente hice que mostrara un .0 al final si el último número era 0, no al revés. Se corrigió, aunque esta es una solución alternativa (muestra "0" junto al número si comienza con 0, de lo contrario, muestra dos espacios en el mismo lugar). En el lado positivo, maneja correctamente palabras como "Otto" (muestra ambos ceros) ya que en realidad no muestra un número decimal.


No puedo pensar en un mejor idioma para hacerlo. Definitivamente se puede jugar más al golf, pero ahora estoy demasiado cansado. La tilde es el símbolo de negación [el( - ) botón].

Input is taken from the calculator's answer variable, meaning whatever was last evaluated (like _ in the interactive python shell) so you have to type a string on the homescreen (quote mark is on ALPHA+), press ENTER, then run the program. Alternatively, you can use a colon to separate commands, so if you name the program, say, "CALCTEXT" and you want to run it on the string "HELLO", you can type "HELLO":prgmCALCTEXT instead of doing them separately.

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
M. I. Wright
fuente
2

Python 2, 147 158 156 bytes

I was missing this '0.' requirement. Hope now it works allright.

edit: Removed ".readlines()" and it still works ;p

edit2: Removed some spaces and move print to the 3rd line

edit3: Saved 2 bytes thanks to Sp3000 (removed space after print and changed 'index' to '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
fuente
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
fuente
1

Ruby 2, 88 86 bytes

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

Byte count includes 2 for the ln options on the command line:

$ ruby -ln 5318008.rb wordlist.txt
daniero
fuente
In this case =="" can be replaced with <?A. And no need for gsub() as sub() is enough.
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);}}

Expanded

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

using the linked words.txt, with lower case conversion:

$ ./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
some user
fuente
1
Won't *s|32 work as lowercase conversion in this context?
Hagen von Eitzen
Great idea! Thanks!
some user
1

Haskell, 175 bytes without imports (229 bytes with imports)

Relevant code (say in File 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
fuente
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);}

Expanded

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

It always adds the decimal, and when invalid returns " . ". But otherwise works like it should. :P

Thanks @LegionMammal978!

Whitcomb L. Judson
fuente
You can save 7 bytes by changing ;String l= to ,l= and =o+ to +=.
LegionMammal978