Longest Seven Segment Word

1

0

This question was inspired by Tom Scott's video here.

The English language has plenty of words, but what's the longest one that can be displayed on a seven segment display? Your challenge is given a list of letters that may not be displayed, display the longest English word in a 7 segment display format?

Input

  • Input will contain a series of unacceptable characters. (letters that you are not permitted to use in your word.)
  • Input can be taken from one of the following:
    • stdin
    • command-line arguments
    • function arguments

Output

  • Output the longest word using the provided alphabet from the input. (In the case of 2 words of the same length, the one that comes first is the "longest". When a hyphen is in the word, it counts towards its length, but is not displayed.)
  • Output must be formatted like a 7 segment display, see the rules below for more about the format.
  • Output must be in stdout or closest equivalent.
  • Output may contain a trailing newline character.

Letters

sevensegment This image shows my source of the alphabet

Here is my simple ascii display so you can visually see the letters (my apologies, the wrap function I used broke with spaces so I had to settle on asterisks). And here is a table to show the alphabet as well:

  ____  A
 | F  | B
 |    | 
  ____  G
 |    | 
 | E  | C
  ____  D

ABCDEFG Letter
1110111 a
0011111 b
1001110 c
0111101 d
1001111 e
1000111 f
1011110 g
0010111 h
0000110 i
0111100 j
1010111 k
0001110 l
1010100 m
1110110 n
1111110 o
1100111 p
1110011 q
1100110 r
1011011 s
0001111 t
0111110 u
0111010 v
0101010 w
0110111 x
0111011 y
1101001 z

Rules

  • Standard loopholes are disallowed HOWEVER words.txt (the dictionary) is the only outside file you may reference (renaming it is not allowed, it must be called words.txt as it is in the repository).
  • The seven segment display must:
    • Be an actual seven segment display. (I'm not going to be picky on how it looks, if it was accepted over there then it's accepted over here.)
    • Have any filler/whitespace character of choice.

Test Cases

Wrapping is an unnecessary challenge and is not needed; I did it out of ease of looking at it in my terminal. Remember: Your whitespace does not need the same character.

input:
gkmqvwxz

output:
******************____********************____****____****____********
******|**|*******|*******|*******|*******|****|**|****|**|****|*******
******|**|*******|*******|*******|*******|****|**|****|**|****|*******
**____********************____************************************____
*|****|**|*******|*******|****|**|*******|****|**|*******|****|**|****
*|****|**|*******|*******|****|**|*******|****|**|*******|****|**|****
**____************____************____****____************____****____
************____************____****____****************************__
|**|*******|****|**|*******|*******|****|**|****|**|*******|*******|**
|**|*******|****|**|*******|*******|****|**|****|**|*******|*******|**
************____****____****____************____************____******
|**|*******|*******|****|**|*******|****|*******|**|*******|*******|**
|**|*******|*******|****|**|*******|****|*******|**|*******|*******|**
****************************____************____****____****____******
__************____********************____****____****____****____****
**|**|*******|*******|*******|*******|****|**|****|**|****|**|*******|
**|**|*******|*******|*******|*******|****|**|****|**|****|**|*******|
**********************____************************************____****
*****|*******|*******|****|**|*******|****|**|*******|****|**|*******|
*****|*******|*******|****|**|*******|****|**|*******|****|**|*******|
**************____************____****____************____****____****
****************____****____****____**
*******|*******|****|**|****|**|******
*******|*******|****|**|****|**|******
____****____****____************____**
*******|****|**|****|**|****|**|******
*******|****|**|****|**|****|**|******
____****************************____**

The word should be "dichlorodiphenyltrichloroethane" for debugging purposes.

input:
gkmqvwxzio

output:
**____************____****____****____************____****____****____
*|*******|****|**|****|**|*******|****|**|*******|****|**|****|**|****
*|*******|****|**|****|**|*******|****|**|*******|****|**|****|**|****
**____************____****____************____************____********
******|**|****|**|*******|*******|*******|*******|*******|****|**|****
******|**|****|**|*******|*******|*******|*******|*******|****|**|****
**____****____************____************____************************
****____****____****____****____************____****____************__
|**|*******|*******|*******|****|*******|**|*******|****|**|*******|**
|**|*******|*******|*******|****|*******|**|*******|****|**|*******|**
****____************____************____****____************____******
|*******|**|*******|*******|****|**|****|**|*******|****|**|*******|**
|*******|**|*******|*******|****|**|****|**|*******|****|**|*******|**
****____****____****____************____****____************____******
__****____****____****____**
**|**|*******|*******|******
**|**|*******|*******|******
******____****____****____**
**|**|************|*******|*
**|**|************|*******|*
******____****____****____**

The word should be "supertranscendentness" for debugging purposes.

input:
abcdefghijklm

output:
**********____****____************____********************____****____
*|*******|****|**|****|**|*******|*******|****|**|****|**|****|**|****
*|*******|****|**|****|**|*******|*******|****|**|****|**|****|**|****
**____********************____****____****____************************
*|*******|****|**|****|**|************|*******|**********|****|**|****
*|*******|****|**|****|**|************|*******|**********|****|**|****
**____****____****____****____****____****____****____****____****____
************____**********
|**|*******|*******|****|*
|**|*******|*******|****|*
****____****____****____**
|**|************|*******|*
|**|************|*******|*
****____****____****____**

The word should be "tootsy-wootsy" for debugging purposes. (We do not output the hyphen but it does count towards the length of the word.)

input:
ikmopqsvwz

output:
**____****____****____****____************____****____****____****____
*|*******|****|**|*******|****|**|*******|*******|****|**|****|**|****
*|*******|****|**|*******|****|**|*******|*******|****|**|****|**|****
******************____****____****____********************____********
*|****|**|*******|*******|****|**|*******|****|**|*******|****|**|****
*|****|**|*******|*******|****|**|*******|****|**|*******|****|**|****
**____************____************____****____************************
********************____************____********************____****__
|*******|*******|**|****|**|****|**|*******|*******|*******|*******|**
|*******|*******|**|****|**|****|**|*******|*******|*******|*******|**
****____****____****____********************____****____****____******
|**|****|**|****|**|****|**|****|**|****|**|****|**|*******|*******|**
|**|****|**|****|**|****|**|****|**|****|**|****|**|*******|*******|**
****____****____************____****____************____****____******
__**
**|*
**|*
****
****
****
****

The word should be "great-granddaughter" for debugging purposes. (We do not output the hyphen but it does count towards the length of the word.)

Scoring

This is , so the shortest submission (in bytes) wins.

(This is also my first question so tell me if I skipped over something or something is unclear or not. Thanks and good luck!)

Josh B.

Posted 2018-10-11T07:52:46.737

Reputation: 105

6As with a lot of challenges involving finding a specific english word, I reccomend the dictionary of words be passed to the program as a list rather thsn be stored somewhere else. This makes it much easier to test – Jo King – 2018-10-11T10:50:13.257

@JoKing So what you mean is it is passed in as a separate argument or input? (If you linked an example that may be helpful for me to get what you are saying.) – Josh B. – 2018-10-11T19:08:11.067

For example, Generate a Portmentout

– Jo King – 2018-10-11T21:00:09.423

6This seems like it would be more appropriate as 2 distinct challenges: (1) given some dictionary, find the longest word not using characters from some set; (2) convert a string of characters in a..z into 7-segment form according to your spec. – Chas Brown – 2018-10-12T00:59:37.707

As regards the part of the challenge where you seek the longest string in some dictionary which does not contain certain characters: you more generally say to ignore hyphens; so is 're-sort' longer than 'resort', or are they the same length? – Chas Brown – 2018-10-12T02:32:14.900

@ChasBrown It should have been more clearly stated, what I meant was you are to ignore the hyphens when it is output but 're-sort' is longer than `'resort'``. I will change the phrasing of the question to help remove that confusion. – Josh B. – 2018-10-12T19:04:54.150

Need clarification on non-letters: should they A) be skipped in output or B) be assumed blank or C) can we choose? – Titus – 2018-10-17T11:38:51.163

2test case with "abcdefghijklm" input states than correct word is "tootsy-wootsy". But "Rostov-on-Don" has the same length and comes first. may you to justify that result? – J. Sendra – 2019-03-01T21:36:11.813

Answers

1

PHP, 292 bytes

foreach(file("words.txt")as$w)preg_match("%[$argn]%i",$w)||$e<($n=strlen($w=trim($w)))&&$s=strtoupper($w.$e=$n;for($r=["
","
","
"];$i<$e;$b&&$k+=4)for($b=ord("}7f\37vtg5$\17u&Emo|yls6/+*=;Z"[ord($s[$i++])-65]),$p=7;$p--;)$b>>$p&1&&$r[(8-$p)/3][$k+$x="3213212"[$p]]="_|"[$x&1];echo join($r);

Run as pipe with -nr or try it online (with a much smaller dictionary).

In case you run out of memory, replace foreach(file("words.txt")as$w) with for($f=fopen("words.txt",r);$w=fgets($f);). This will also improve performance a lot.

breakdown

foreach(file("words.txt")as$w)      # 1. loop $w through words
    preg_match("%[$argn]%i",$w)||       # if there are forbidden characters, skip
        ($e<$n=strlen($w=trim($w)))     # if length $n exceeds current max length $e
            &&$s=strtoupper($w)             # then update longest word $s
            .$e=$n;                         # and max length
for($r=["\n","\n","\n"];            # 2. init my ouput buffer
    $i<$e;                          # 3. loop through word characters
    $b&&$k+=4)                          # 3. if previous char was legal, increment output offset
    for(                                # 1. get bit mapping for character: (none for non-letters)
        $b=ord("}7f\37vtg5$\17u&Emo|yls6/+*=;Z"[ord($s[$i++])-65]),
        $p=7;$p--;)                     # 2. loop through bits
        $b>>$p&1&&                          # if bit $p is set,
            $r[(8-$p)/3][$k+$x="3213212"[$p]]   # then map bit no. to segment coordinates
                =$x&1?d|t:_;                    # and draw the according character
echo join($r);                      # 4. print my output buffer

notes

  • I could lose 11 bytes if the dictionary contained only letters, space and linebreaks
    OR 12 if only all letters were uppercase. Dang!
  • I could paint every "longest" word; the last will remain in the buffer for printing; that would mean I wouldn´t have to copy $w to $s and I could copy $n to $e in the character loop, but I would need if(!preg_match(...)&&$e<$n=strlen(...)) and I had to reset $i=$k=0; that would eat up all the savings.
    I could do !$i=$k=preg_match(...) but that would require extra parentheses - no savings either.
    Makes me almost wish that we also had to paint the digits.
  • Painting the whole thing into a single string instead of an array would save five bytes in the painting, but cost nine in the output.

Titus

Posted 2018-10-11T07:52:46.737

Reputation: 13 814

0

JavaScript, 830 characters, oooooof

Edit: I fixed the issue and ignore my previous edits where I started I found an error, I was sanitizing the dictionary incorrectly. Funny enough, this didn't change the code length

Anyways, someone had to do this challenge. If winning only requires the shortest, it's always possible to win by default, right? :P

var q=new XMLHttpRequest();q.open("get","words.txt");q.onreadystatechange=()=>{if(q.readyState!=4)return;(z=>q.responseText.toLowerCase().split("\n").filter(w=>w.split("").reduce((j,l)=>j&&z.indexOf(l)<0,true)).map((o,p)=>[o,p]).sort((a,b)=>{if(a[0].length == b[0].length){return a[1]-b[1]}return b[0].length-a[0].length;})[0][0].split("").forEach(e=>e=e.replace(/[^a-z]/,"")&&console.log(("ABCEFGCDEFGADEFBCDEGADEFGAEFGACDEFCEFGEFBCDEACEFGDEFACEABCEFABCDEFABEFGABCFGABEFACDFGDEFGBCDEFBCDFBDFBCEFGBCDFGABDG".split("").reduce((f,v,i)=>{if(i==114){f[0].unshift(v);f[1].push(f[0])}else if(v<f[0][0]){f[1].push(f[0]);f[0]=[v]}else{f[0].unshift(v)}return f},[[0],[]])[1][e.charCodeAt()-97]).reduce((f,v)=>f.replace(RegExp(`${v}`,"g"),"#"),"-AAA-\nF---B\nF---B\n-GGG-\nE---C\nE---C\n-DDD-").replace(/[^#\n]/g,"-"))))(prompt())};q.send()

Basically, how it works is, there's an output string that encodes segments for letters, and a format string, that the output string is applied onto.

Here's a version that labels these variables and is a bit less... Harsh.

It skips functions entirely and recalculates variables for any place they are iterated, so it's very inefficient, but it should never take more than a few seconds at worst case to run. Input is given through an html prompt. The script assumes it is part of a window with relative file access and outputs to the console.

const outputString = "ABCEFGCDEFGADEFBCDEGADEFGAEFGACDEFCEFGEFBCDEACEFGDEFACEABCEFABCDEFABEFGABCFGABEFACDFGDEFGBCDEFBCDFBDFBCEFGBCDFGABDG";
const formatString = "-AAA-\nF---B\nF---B\n-GGG-\nE---C\nE---C\n-DDD-";

var q=new XMLHttpRequest();
q.open("get","words.txt");
q.onreadystatechange=()=>{
    if(q.readyState!=4)return;
    (z=>q.responseText.toLowerCase().split("\n").filter(
        w=>w.split("").reduce((j,l)=>j&&z.indexOf(l)<0,true)
    ).map(
        (o,p)=>[o,p]
    ).sort(
        (a,b)=>{
            if(a[0].length == b[0].length){
                return a[1]-b[1]
            }
            return b[0].length-a[0].length;
        }
    )[0][0].split("").forEach(
        e=>e=e.replace(/[^a-z]/,"")&&console.log(
            (outputString.split("").reduce(
                (f,v,i)=>{
                    if(i==114){
                        f[0].unshift(v);f[1].push(f[0])
                    }else if(v<f[0][0]){
                        f[1].push(f[0]);f[0]=[v]
                    }else{
                        f[0].unshift(v)
                    }return f
                },[[0],[]]
            )[1][e.charCodeAt()-97]).reduce(
                (f,v)=>f.replace(RegExp(`${v}`,"g"),"#"),formatString
            ).replace(/[^#\n]/g,"-"))
    ))(prompt())
};
q.send()

These particular seven segment display codes for the alphabet (for example, 0101100) can't overlap when you remove their zeroes. What I mean by that is for each index of the string if you were to encapsulate that spot, chaining all the strings together never results in a case that the last index of a display code is lower than the first index of the following code. This isn't particularly true of all display code permutations and orderings, but in this case it was so we use that.

I haven't double checked because I got so, um, involved in this code, but I think that it might be smaller to store these modified display codes in a flat array than to break them into an array based on one string. But that wasn't as fun.

I don't expect to win, but I am curious if anyone else can beat this in web-oriented JavaScript using an XMLHttpRequest and prompt() for input.

user41392

Posted 2018-10-11T07:52:46.737

Reputation:

I'd recommend you have a look at the fetch() API.

– darrylyeo – 2018-10-18T06:40:30.110