59
\$\begingroup\$

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.

Illustrations

Truthy

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

Falsy

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.

\$\endgroup\$
6
  • \$\begingroup\$ For full programs may I take input as separate lines? \$\endgroup\$
    – Blue
    Commented Feb 22, 2016 at 19:40
  • \$\begingroup\$ @muddyfish: Yes. \$\endgroup\$ Commented Feb 22, 2016 at 19:41
  • \$\begingroup\$ ... and string as first arg is ok. \$\endgroup\$
    – edc65
    Commented Feb 22, 2016 at 20:56
  • \$\begingroup\$ @edc65: Oh, I like that better. \$\endgroup\$ Commented 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
    Commented Feb 25, 2016 at 14:42

50 Answers 50

34
\$\begingroup\$

C, 42 bytes

#define f(c,s)!strchr(s,c)&!strchr(s,c^32)
\$\endgroup\$
1
  • 8
    \$\begingroup\$ Codegolfing in C, Ubercodegolfing. \$\endgroup\$ Commented Feb 23, 2016 at 9:45
25
\$\begingroup\$

Javascript ES6 34 26 23 Bytes

x=>!/^(.).*\1/i.test(x)

shaved 8 bytes thanks @MartinBüttner

\$\endgroup\$
1
  • 9
    \$\begingroup\$ Wow, I didn't know that /i affected \1! \$\endgroup\$
    – Neil
    Commented Feb 22, 2016 at 22:17
19
\$\begingroup\$

05AB1E, 7 6 4 3 bytes

Code:

l`-

Explanation:

l     # Convert both elements to lowercase
 `    # Flatten the array
  -   # Loop over the second line of text and substract each char from the first character
        For example: "abcde""ba"- would result in "cde"

Try it online!

Truthy is when the current letter is outputted. Falsy is when nothing is outputted.

\$\endgroup\$
2
  • \$\begingroup\$ So - effectively does a complement operation? \$\endgroup\$ Commented Feb 23, 2016 at 2:15
  • \$\begingroup\$ @2012rcampion Yes, that is correct. But only when both values are not integers. \$\endgroup\$
    – Adnan
    Commented Feb 23, 2016 at 12:44
14
\$\begingroup\$

TeaScript, 5 3 bytes

AµN

Aha \o/! I forgot about implicit input! TeaScript will automatically insert x. (the input) at the beginning. I can then check if it has the other input (in variable µ) and so a NOT (N). I guess TeaScript's best advantage here is its implicit input

Try it online

Explanation

  A µ  N
x.A(y).N  // At compile time

x.A // input, has...
(y) // second input
N   // Logical NOT
\$\endgroup\$
1
  • \$\begingroup\$ Wow. Much built-in. That reminds me, Japt has this same built-in... cuts another two bytes off :) \$\endgroup\$ Commented Feb 23, 2016 at 1:57
12
\$\begingroup\$

Bash, 16 11 bytes

grep -iv $1

-i is the case-insensitive flag, -v inverts (checks for a non-match).

Character must be provided as a command line argument, and the test string on STDIN.

Reduced by 5 bytes with @DigitalTrauma's help!

Sample runs:

llama@llama:~$ echo 'This is a lipogram' | ./lipogram.sh e
This is a lipogram.
llama@llama:~$ echo 'This sentence is not a lipogram (for e).' | ./lipogram.sh e
\$\endgroup\$
6
  • \$\begingroup\$ Why not read the sentence from STDIN? grep -iv $1. I don't see anything wrong with mixing STDIN and command-line args as input methods - I done it before - but perhaps there is a meta precedent I have missed... \$\endgroup\$ Commented Feb 22, 2016 at 20:19
  • \$\begingroup\$ @DigitalTrauma I considered that, but figured it'd be a bit sketchy. Perhaps a topic to be discussed on meta. \$\endgroup\$
    – Doorknob
    Commented Feb 22, 2016 at 20:21
  • 2
    \$\begingroup\$ Programs may combine two or more input methods \$\endgroup\$
    – Dennis
    Commented Feb 22, 2016 at 20:24
  • \$\begingroup\$ Good find @Dennis! \$\endgroup\$ Commented Feb 22, 2016 at 21:27
  • 1
    \$\begingroup\$ Can we get any more ^D users to comment on this answer? @Downgoat - are you there? ;-) \$\endgroup\$ Commented Feb 22, 2016 at 21:30
12
\$\begingroup\$

Japt, 12 6 4 bytes

!VoU

Test it online!

@Downgoat's TeaScript answer reminded me that Japt has exactly the same built-in, cutting off a final two bytes.

How it works

       // Implicit: U = input char, V = input string
VoU    // Keep only the chars in V that are equal to U, ignoring case.
!      // Take logical NOT. Returns true if no matches were found, false otherwise.
\$\endgroup\$
2
  • \$\begingroup\$ @CᴏɴᴏʀO'Bʀɪᴇɴ Thanks to a built-in I had forgotten about, it's now even shorter :) \$\endgroup\$ Commented Feb 23, 2016 at 1:57
  • 6
    \$\begingroup\$ um wait no that's too short \$\endgroup\$ Commented Feb 23, 2016 at 1:57
10
\$\begingroup\$

JavaScript (ES6), 29 bytes

(c,s)=>!RegExp(c,'i').test(s)
\$\endgroup\$
5
  • 5
    \$\begingroup\$ You can curry the answer as c=>s=>!RegExp(c,"i").test(s), saving a byte. \$\endgroup\$ Commented Feb 22, 2016 at 19:54
  • \$\begingroup\$ c=>s=>!s.match(c,'i') is 21. :) \$\endgroup\$ Commented Feb 22, 2016 at 20:03
  • \$\begingroup\$ @ETHproductions match only takes one argument. The second argument logs a console warning in Firefox 39 or later, and won't work in Firefox 47 at all. \$\endgroup\$
    – Neil
    Commented Feb 22, 2016 at 22:15
  • \$\begingroup\$ @Neil I'm using Firefox 44, and it seems to work perfectly fine. \$\endgroup\$ Commented Feb 22, 2016 at 22:18
  • \$\begingroup\$ @ETHproductions Sure, but I have no reason to believe it works in other browsers, and it will also stop working in Firefox soon. \$\endgroup\$
    – Neil
    Commented Feb 22, 2016 at 22:47
10
\$\begingroup\$

CJam, 6 byte

lel(&!

Try it online! lel

Explanation

l  e# Read a line of input.
el e# Convert to lower case.
(  e# Pull off the first character.
&  e# Set intersection with the rest of the input.
!  e# Logical NOT.
\$\endgroup\$
7
\$\begingroup\$

Python 3, 36

Having to ignore case is surprisingly expensive.

lambda a,b:a.lower()not in b.lower()

Takes the arguments as (char, string)

\$\endgroup\$
7
\$\begingroup\$

Perl, 11 + 1 = 12 bytes

$_=lc!~lc<>

Requires the -p switch and takes input as $string\n$letter

$ perl -pe'$_=lc!~lc<>' <<< $'this is a lipogram\ne'
1

How it works:

            # -p auto reads input into $_ and auto prints at the end
   lc       # lowercase $_
     !~     # Check against regex
       lc<> # Read next line and lowercase it. '=~' will expect the rValue to be
            # a regex and therefore the result from 'lc<>' will be treated as such
$_=         # Assign result ('1' or '') to $_ which will be printed
\$\endgroup\$
3
  • \$\begingroup\$ You should specify your shell. For me, bash on Ubuntu, this prints 1 no matter the input, following the template you give. (I don't know why, but, then, I'm unfamiliar with <<<.) (And using normal STDIN (no <<<), I get 1 unless the letter is the last character in the string, because you don't chomp the letter.) \$\endgroup\$
    – msh210
    Commented Jun 2, 2016 at 21:35
  • \$\begingroup\$ @msh210 You can use printf "this is a lipogram\ne\n" | perl -pe'$_=lc!~lc<>' instead. <<< is bash syntax. \$\endgroup\$ Commented Jun 2, 2016 at 21:51
  • \$\begingroup\$ @msh210 <<< is just another way to pass stdin. \$\endgroup\$ Commented Jun 2, 2016 at 21:57
6
\$\begingroup\$

Pyth, 8 7 bytes

-rz0rw0

Explanation

 rw0    -  input().lower()
-       - ^ - V
    rw0 -  input().lower()

Thanks @FryAmTheEggman for telling me I can use - instead of !}

Try it here

\$\endgroup\$
0
6
\$\begingroup\$

Julia 0.3, 22 20 bytes

c%s=c&95∉[s...]&95

uppercase is a long word.

How it works

c%s=c&95∉[s...]&95

c%s=                Redefine the binary operator % so it takes a character c and
                    a string s and...
     c&95                Compute lo bitwise AND of c and 95.
                         This casts the character c to uppercase.
          [s...]         Yield the list of the characters of the string s.
                &95      Compute lo bitwise AND of each chararacter and 95.
                         This casts the characters of s to uppercase.
         ∉               Return a Boolean, signaling non-membership.
\$\endgroup\$
0
5
\$\begingroup\$

Java, 63 bytes.

boolean f(String s,char c){return!s.matches("(?i:.*"+c+".*)");}
\$\endgroup\$
2
  • \$\begingroup\$ You could also write a lambda expression (s,c)->!s.matches("(?i:.*"+c+".*)") which is shorter \$\endgroup\$
    – randers
    Commented Feb 22, 2016 at 22:41
  • 1
    \$\begingroup\$ It wouldn't be a proper method though, you have to put String and char somewhere. \$\endgroup\$
    – shooqie
    Commented Feb 23, 2016 at 15:56
5
\$\begingroup\$

O, 8 bytes

{_.@_-=}

An anonymous function that takes a character and a string.

Try it online.

Explanation

{_.@_-=}

{      }
 _        Lowercase string
  .       Duplicate
   @      Rotate stack
    _     Lowercase character
     -    Remove all instances of the character
      =   Compare to original
\$\endgroup\$
2
  • \$\begingroup\$ Why does this need to be a function? Why not just have it be a program? \$\endgroup\$
    – jado
    Commented Feb 24, 2016 at 6:22
  • \$\begingroup\$ @phase I couldn't figure out what char was split. At any rate, I'm pretty sure it's shorter as a function anyways. \$\endgroup\$ Commented Feb 24, 2016 at 16:02
5
\$\begingroup\$

PowerShell, 36 32 30 29 25 bytes

param($a,$b)$b-notmatch$a

Uses the -notmatch operator, and simply outputs True or False.

\$\endgroup\$
5
\$\begingroup\$

MATL, 5 bytes

kikm~

Try it online!

k        % take first input (letter) implicitly. Convert to lowercase
ik       % take second input (text). Convert to lowercase
m        % ismember function
~        % negate
\$\endgroup\$
5
\$\begingroup\$

Seriously, 6 bytes

,ù,ùíu

Try it online!

Takes input as 'string'\n'char'

Explanation:

,ù,ùíu
,ù      get string (lowercase)
  ,ù    get char (lowercase)
    íu  1-based index (0 if not found)
\$\endgroup\$
1
  • \$\begingroup\$ Wouldn't something like ,ù,ùìuY work? (That's supposed to be the I that does indexOf but I don't remember which one does that) \$\endgroup\$
    – quintopia
    Commented Feb 23, 2016 at 6:09
4
\$\begingroup\$

Retina, 11

iA`^(.).*\1

I'm not sure what counts as truthy / falsy in Retina, this will echo the line if it is a lipogram for the given character, and it will return the empty string if it isn't.

This will also work for multiline input.

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ An empty string is falsy, so that counts. \$\endgroup\$ Commented Feb 22, 2016 at 19:31
4
\$\begingroup\$

Minkolang 0.15, 10 bytes

$or7Z0Z,N.

Try it here.

Explanation

$o            Read in whole input as characters
  r           Reverse stack
   7Z         Lowercase everything
     0Z       Pop top of stack (a) and count how many 'a's are in the stack
       ,      'not' the top of stack
        N.    Output as number and stop.
\$\endgroup\$
4
\$\begingroup\$

Rust, 75 bytes

|c:char,s:&str|!s.to_lowercase().contains(c.to_lowercase().next().unwrap())

Biggest score means I win, right? >_<

Try it here.

\$\endgroup\$
4
\$\begingroup\$

Jelly, 8 bytes

ḢO^O&95P

Try it online!

How it works

ḢO^O&95P  Main link. Input: S (string)

Ḣ         Pop the first character of S.
 O        Ordinal; compute its code point.
  ^O      XOR it with the code points of the remaining characters.
    &95   AND each result with 95.
       P  Take the product of the results.
\$\endgroup\$
3
  • \$\begingroup\$ Wait, jelly isn't winning? There must be a way to golf it down further! \$\endgroup\$ Commented Feb 22, 2016 at 21:30
  • \$\begingroup\$ Not when strings are involved... \$\endgroup\$
    – Dennis
    Commented Feb 22, 2016 at 21:52
  • \$\begingroup\$ This must be rectified. \$\endgroup\$ Commented Feb 22, 2016 at 22:08
4
\$\begingroup\$

Python, 34 bytes

lambda c,s:c not in s+s.swapcase()

Checks for character c being in string s, ignoring case by appending a case-swapped copy of s to s. The negation is done with not, which looks lengthy but I don't see better. This is same length:

lambda c,s:(c in s+s.swapcase())<1

You can't omit the parens or else Python will interpet the expression as a chained three-value inequality of form _ in _ < _.

Python 3.5 should allow 33 bytes via set conversions, though I can't test it now.

lambda c,s:{*c}-{*s+s.swapcase()}
\$\endgroup\$
4
\$\begingroup\$

Pyke, 7 bytes

Dl3+R{!

Explanation:

D       -     eval_or_not(input()).lower()
 l3     -    ^.swapcase()
   +    -   ^+^
    R   -  rotate 2
     {  -  ^ in ^
      ! - not ^
\$\endgroup\$
3
\$\begingroup\$

JavaScript ES6, 41 40 bytes

x=>!~x.slice(2).search(RegExp(x[0],"i"))

Takes the entire string as an argument. I cannot save bytes by accepting two different arguments because then my answer would melt into the other ES6 answer :(

\$\endgroup\$
3
  • \$\begingroup\$ I win this time, ES6. ;) Your anonymous function syntax is no match for my not in. \$\endgroup\$ Commented Feb 22, 2016 at 19:47
  • \$\begingroup\$ @MorganThrapp Gahh, foiled again! \$\endgroup\$ Commented Feb 22, 2016 at 19:47
  • \$\begingroup\$ that's ok I got this, You move @MorganThrapp. \$\endgroup\$
    – Shaun H
    Commented Feb 22, 2016 at 21:14
3
\$\begingroup\$

CJam, 10 bytes

{el\ele=!}

An anonymous function (block) that takes a character (not a string!) and a string.

Try it online.

Explanation

{el\ele=!}

{        }
 el\el      lowercase both args
      e=    count occurrences of the character
        !   logical not
\$\endgroup\$
0
3
\$\begingroup\$

R, 26 bytes

 function(x,y)!grepl(y,x,T)

x is the string, y is the letter, the T in the call to grepl makes it case insensitive.

\$\endgroup\$
3
\$\begingroup\$

Jolf, 6 7 bytes

So. Many. Sixes. SMS? Well, try it here nonetheless. Replace with \x7f.

⌂ MiI'i
⌂_M      match with flags
   i     the input
    I    with another input
     'i  using i as a flag
\$\endgroup\$
3
+100
\$\begingroup\$

Vyxal, 6 bytes

ɽfhO2<

Try it Online!

Accepts one line as input, formatted like the test cases.

How it works:

ɽf          # convert input to lowercase and turn into list
  hO        # count the number of times the first item in the list occurs
     2<     # is it less than 2 (should only occur once as the first character)
\$\endgroup\$
3
  • 1
    \$\begingroup\$ I managed to get this down to 3 bytes for you: Try it Online!. It outputs a single letter if it is a lipogram and an empty string if it isn't. \$\endgroup\$
    – lyxal
    Commented Oct 4, 2022 at 22:42
  • \$\begingroup\$ thanks! are single letters truthy values? \$\endgroup\$
    – pacman256
    Commented Oct 5, 2022 at 2:38
  • 1
    \$\begingroup\$ Any non-empty string is a truthy value. Also, 05ab1e uses the same output format as the 3 byter. \$\endgroup\$
    – lyxal
    Commented Oct 5, 2022 at 2:40
2
\$\begingroup\$

Ruby, 17 bytes

->c,s{/#{c}/i!~s}
->c,s{  # lambda with two arguments
/#{c}/  # turn the input character into a regexp w/ interpolation
i       # case insensitive
!~      # does not match
s       # input string
}
\$\endgroup\$
2
\$\begingroup\$

Batch, 53 bytes

@set s=%2
@call set t=%%s:%1=%%
@if %s%==%t% echo 1

Accepts input as two command-line arguments. (Quote the second argument if necessary.) Outputs 1 on success, nothing if the first argument is (insensitively) found in the second.

\$\endgroup\$

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.