A lipogram is a block of words that omits a particular symbol. Right now, I am avoiding our fifth symbol of 26 that commonly show up. You should know by now what I am omitting. If not, look up "lipogram" and you will know.

Your Task

With a char, a blank, and a following string (blanks may show up in this; with only ASCII 32-126 chars) in input, output falsy if this char is in input string, truthy if not. This char that you must look for will always fit in two spans: "A" to "Z" or "a" to "z" (ASCII 65-90, 97-122). Do not distinguish capitals and non-capitals. Also, don't worry about blanks or punctuation symbols. Both programs and functions satisfy. Also, you may split input char and string into two args for programs or functions, and string as first arg is okay.



e This is a lipogram.
a You need to consider other letters too.
E Capitals also count.


e This sentence is not a lipogram (for e).
t This particular letter is surprisingly hard.
A You don't need to care about any non-alphabetic symbols.

Non-lipogrammed version

A lipogram is a series of words that leaves out a letter. I left out the letter "e" above.

Your task is to take a character and a string (which may include spaces) as input, separated by a space or newline, and output falsy if the character is in the string, and truthy otherwise. You may assume the string is composed solely of printable ASCII characters (char codes 32-126). The character will always be in the English alphabet, and there is no difference between lowercase and uppercase. The character will not be a space or symbol. You may write a program or a function. For either, you may take the character and string as separate arguments, and the string may come first.

  • \$\begingroup\$ For full programs may I take input as separate lines? \$\endgroup\$
    – Blue
    Feb 22, 2016 at 19:40
  • \$\begingroup\$ @muddyfish: Yes. \$\endgroup\$ Feb 22, 2016 at 19:41
  • \$\begingroup\$ ... and string as first arg is ok. \$\endgroup\$
    – edc65
    Feb 22, 2016 at 20:56
  • \$\begingroup\$ @edc65: Oh, I like that better. \$\endgroup\$ Feb 22, 2016 at 20:57
  • 1
    \$\begingroup\$ You should try "and a string as your first arg is okay." or a similar configuration. \$\endgroup\$
    – mbomb007
    Feb 25, 2016 at 14:42

50 Answers 50


Mathematica, 33 32 bytes


I love it when ## can be used. Input is string, then char.

Or, a case sensitive version: (11 bytes:)


Yep, just a builtin.


Haskell, 45 bytes

import Data.Char
(.map t).notElem.t

Usage example: ( (.map t).notElem.t ) 'a' "You need to consider other letters too" -> True.

It's a pointfree version of f c s = notElem (toLower c) (map toLower s), i.e. convert letter and string to lowercase and see if the letter is not in the string.


Java 8 lambda, 48 46 bytes

Thanks to @Geobits for pointing out my stupidity and saving me 2 bytes!

(String i,char o)->i.split("(?i)"+o).length<2;

Splits the string if the sought char is found. Returns true if it is contained, false otherwise.

  • \$\begingroup\$ Why not (String i,char o)->!i.contains(o) with Java 8? \$\endgroup\$
    – Denker
    Feb 25, 2016 at 13:28
  • \$\begingroup\$ @DenkerAffe Didn't work insensitively. Fixed now, in lambda form. \$\endgroup\$ Feb 25, 2016 at 13:48

Fig, \$2\log_{256}(96)\approx\$ 1.646 bytes


Try it online!

as # Returns 0 for truthy and "true" (?!) for falsey. Takes a list of chars as input
 s # String equals ignore case (vectorising)
a  # Any truthy?

SpecBAS - 36 bytes

1 INPUT a$,b$: ?POS(UP$ a$,UP$ b$)=0

Returns 1 (True) if letter is NOT found, 0 (False) if it is. Converting to uppercase with UP$ save once character vs LOW$


Lua, 47 Bytes

Simply use string.find() and a ternary to know if there's a prohibited character in the string.

Takes input via command-line: lua golf.lua 'e' "This is a Lipogram."

Edit: Saved 20 Bytes thanks to @Oleg V. Volkov.

print(not arg[2]:lower():find(arg[1]:lower())) 
  • \$\begingroup\$ There's no need to waste bytes asigning to c, arg[2] could use a lower too, and right now it ouputs bad value 0, which is true in Lua. print(not arg[2]:lower():find(arg[1]:lower())) \$\endgroup\$ Feb 24, 2016 at 16:10
  • \$\begingroup\$ @OlegV.Volkov Oh, thanks. Don't know why I did it this way... must have been tired... \$\endgroup\$
    – Katenkyo
    Feb 25, 2016 at 7:06

><> , 42 bytes

i:"a"(?\:i:0(?\= ?\70.
.18+" "/   ;n1/;n0/

Overview :

.18+" "/

Grabs the first letter, adds space (32) to it if it's not lowercase


Grabs the following letters from the input. It compares them to 0 in order to know if it has reached the end of the input, in which case i returns -1. In this case it will output 1 and stop.

= ?\70.

Compare the current letter to the first one. If they're equal, output 0 and stop. Otherwise, jump back to the beginning of the loop.

You can give it a try on the online interpreter, it nicely illustrates the program flow.


Hoon, 61 56 bytes

{a/* b/*}
(lien (trip (cuss b)) (cury test (cuss a)))

There are a couple reasons why this is so bad. Unfortunately, Hoon's uppercase/lowercase function is tape -> cord, so another ++trip call is needed from the result of cuss to turn it back into a list of characters. It also doesn't have a function to test if the list contains a value, only if a function returned yes on any entry.

Hoon has two syntaxs: wide-form and tall-form. Wide-form uses ()'s for grouping such as ?:(a b c), while tall-form uses whitespace (either two spaces or a newline) for seperation of twigs. Since newlines count as one byte, using tall-form after runes is smaller although it looks very silly and no one would write it like that.

This entry also abuses Hoon's generic system, wet gates. The |* rune is like |=, which creates a "function" except that it replaces the type signature with the type of the sample and typedchecks at the callsite instead of definition. Since |* and |= are the exact same length, but you can omit the type info for the function args, it's smaller to just let the caller provide the type information instead of having |= {a/tape b/tape}.

To call it, enter %+ in the Urbit :dojo, then this snippet, then "A" "You don't need to care about any non-alphabetic symbols." (two spaces between those strings!). This is simply a Hoon two-argument function call.


Befunge 27x2 = 54 bytes

#^_0.@  >\: #^_$~%:0 >84*%-

Try It Online

A shorter version that doesn't account for non-alpha characters

#^_0.@  >\:!#^_\84*%-

GML, 66 bytes

return string_pos(string_lower(argument0),string_lower(argument1))
  • \$\begingroup\$ How does this take input? \$\endgroup\$ Feb 23, 2016 at 23:27
  • \$\begingroup\$ It's a function. \$\endgroup\$ Feb 24, 2016 at 1:38
  • \$\begingroup\$ In GML all scripts receive arguments in the form of argument0, argument1, etc. or as an argument[] array. They can return a value with return. \$\endgroup\$
    – Timtech
    Feb 24, 2016 at 22:44

Scala, 50 bytes

def f(s:String,c:Char)= !s.matches(s"(?i:.*$c.*)")

(Mostly derived from the Java answer)


Groovy, 58 bytes

print args[1].toLowerCase().indexOf(args[0].toLowerCase())

Run with:

groovy filename.groovy *char* *string*

Oracle SQL 11.2, 68 bytes


:1 is the char

:2 is the string

Return NULL/empty string as truthy, everything else is falsy.

It translates every character of the string :2 to nothing, which removes them, except for the :1 char.


DUP, 33 bytes


Try it here.

Anonymous lambda that takes input from both argument and STDIN and leaves result on stack. Usage:



[                                ] {lambda}
 `                                 {get STDIN char}
  32~&                             {uppercase (charcode representation)}
      a:                           {store to a}
        0                          {push 0 to stack as bool}
         [      ][          ]#     {while loop}
          \1-$;$                   {reduce from last string char:}
                  32~&               {uppercase}
                      a;=            {get a==[uppercase char]}
                          @|         {XOR result with bool}
                              %%~  {drop twice, negate TOS (bool)}

C++14, 53 bytes

Based on Josh's answer

As unnamed lambda, assumes s to be std::string and c to be char:

[](auto s,auto c){return s.find(c)+s.find(c^32)==-2;}

Also assumes the length of the strings is below 2^31. If that may be the case, use the safer 58 byte variant:

[](auto s,auto c){return s.find(c)==-1&&s.find(c^32)==-1;}


auto f =
  [](auto s,auto c){return s.find(c)+s.find(c^32)==-2;}

int main() {
  std::string a = "abcdfg";
  std::cout << f(a,'e') << std::endl;
  std::cout << f(a,'E') << std::endl;
  std::cout << f(a,'a') << std::endl;
  std::cout << f(a,'A') << std::endl;

C#, 52 51 bytes


If I could find a way to get rid of ToLower(), I'd save 16 bytes.

One of those cases where I can get rid of the space after return, yay.

  • \$\begingroup\$ C|32 makes ToUpper(), that way you could check I.ToUpper().Contains(C|32) \$\endgroup\$
    – Karl Napf
    Nov 23, 2016 at 17:57
  • \$\begingroup\$ Yeah I tried that route, but I'd have to cast to char and then convert that to a string with "" for Contains, which ends up being longer than just ToLower twice. \$\endgroup\$
    – Yodle
    Nov 23, 2016 at 18:00

J, 19 bytes

1=&#[:<;._1 tolower

Try it online!


Go, 77 bytes, using regexp

func k(c,s string)bool{b,_:=MatchString("(?i)"+c,s)

Attempt This Online!

Go, 78 bytes, using strings

func f(c,s string)bool{L:=ToLower

Attempt This Online!


Thunno 2, 3 bytes


Try it online!

Port of Adnan's 05AB1E answer.


LẸ-  # Implicit input
L    # Lowercase
 Ẹ   # Dump
  -  # Subtract
     # Implicit output

Java, 51 bytes


Uses s as input and c as char, but c must be of type String.

  • \$\begingroup\$ This tries to take input from variables, which isn't allowed. \$\endgroup\$
    – emanresu A
    Jun 12, 2022 at 22:28

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.