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 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 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.


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

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


  • 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.



The word should be "dichlorodiphenyltrichloroethane" for debugging purposes.



The word should be "supertranscendentness" for debugging purposes.



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



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


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

  • 6
    \$\begingroup\$ As 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 \$\endgroup\$
    – Jo King
    Oct 11, 2018 at 10:50
  • \$\begingroup\$ @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.) \$\endgroup\$
    – Josh B.
    Oct 11, 2018 at 19:08
  • \$\begingroup\$ For example, Generate a Portmentout \$\endgroup\$
    – Jo King
    Oct 11, 2018 at 21:00
  • 6
    \$\begingroup\$ This 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. \$\endgroup\$
    – Chas Brown
    Oct 12, 2018 at 0:59
  • 2
    \$\begingroup\$ test 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? \$\endgroup\$
    – J. Sendra
    Mar 1, 2019 at 21:36

2 Answers 2


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 formatString = "-AAA-\nF---B\nF---B\n-GGG-\nE---C\nE---C\n-DDD-";

var q=new XMLHttpRequest();
            if(a[0].length == b[0].length){
                return a[1]-b[1]
            return b[0].length-a[0].length;
                    }else if(v<f[0][0]){
                    }return f

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.

  • \$\begingroup\$ I'd recommend you have a look at the fetch() API. \$\endgroup\$
    – darrylyeo
    Oct 18, 2018 at 6:40

PHP, 292 bytes

"];$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.


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


  • 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.