7
\$\begingroup\$

I came across this picture, which I initially questioned and thought about posting to Skeptics. Then I thought they'll only tell me if this one case is true, but wouldn't it be great to know how true any "rule" really is? Today you're going program a skeptic-bot

Challenge

Write a program or function which when given a dictionary of valid words and a rule determines if the rule is well applied

Rules

  • The dictionary is "words.txt" taken from here. Your submission must theoretically be able to review all words in the file, but for testing you may use a shortened list
  • "Rules" come in the form x before y except <before/after> z. Your submission may take that input in any reasonable form, some examples below
  • Compliance is defined as: "There is an adjacent x and y in the word in the right order that are in the reverse order if before/after z"
  • Non-compliance is defined as: "There is an adjacent x and y in the word in the incorrect order or they are not reverse if before/after z"
  • Rules are evaluated case insensitive
  • Output or return a truthy value if the number of compliant words in the dictionary is greater than the number of non-compliant words, otherwise output a falsey value. Submissions cannot end in errors.
  • This is , so shortest submission in bytes wins

Example input:

["i","e","-","c"]  #list of values, "-" denotes "after"
[105,101,-99]    #list of values as ASCII numbers, "-99" denotes "after"
"ieac"           #string of values abbreviated

Test Cases

Below are sample cases as inputs, for clarity I list the matching words but this is not required

Example dictionary: ["caught", "lemon", "simplified", "queue", "qwerty", "believe", "fierce", "receive", "science", "foreign", "weird", "quit"]

Input: "I before E except after C"
Compliant: simplified, believe, fierce, receive   
Noncompliant: science, foreign, weird       
Output: Truthy        

Input: "Q before U except before E"
Compliant: quit
Noncompliant: queue 
Output: Falsey

Input: "C before E except before E"
Compliant: fierce, receive, science
Noncompliant: 
Output: Truthy
\$\endgroup\$
1
  • \$\begingroup\$ Looks like your link died :/ \$\endgroup\$
    – Nissa
    Oct 14, 2020 at 18:23

3 Answers 3

7
\$\begingroup\$

Python3, 105 103 bytes

This is my first golf here so be kind =)

-2 bytes tanks to Chas Brown

lambda d,b,x,y,z:sum((x+y in i)-2*((z*b+x+y+z)[:3]in i)-(y+x in i)+2*((z*b+y+x+z)[:3]in i)for i in d)>0

Takes the dictionary d as any iterator of strings; a boolean 'b' (True being after); and the three letters x,y,z as Strings;

Try it online!

Explanation: might add later

\$\endgroup\$
1
  • 3
    \$\begingroup\$ You can save a few bytes by replacing ...] in i with ...]in i in a couple of places. Welcome to PPCG! \$\endgroup\$
    – Chas Brown
    Aug 6, 2018 at 20:10
3
\$\begingroup\$

Java 8, 210 bytes

(D,a,b,c,f)->D.stream().filter(w->w.contains(a+b)&!w.contains(f?c+a+b:a+b+c)|w.contains(f?c+b+a:b+a+c)).count()>D.stream().filter(w->w.contains(b+a)&!w.contains(f?c+b+a:b+a+c)|w.contains(f?c+a+b:a+b+c)).count()

Takes the dictionary D as a java.util.List<String>; the three letters a,b,c as Strings; and whether it's after or before as a boolean f (truthy being 'after').

EDIT: Surprisingly enough using two .matches with regexes instead of the two times three .contains is longer. And creating variables for f?c+a+b:a+b+c and f?c+b+a:b+a+c is also 1 byte longer.

Try it online.

Explanation:

(D,a,b,c,f)->             // Method with List, 3 Strings, boolean parameters & boolean return
  D.stream()              //  Stream the given dictionary-List
   .filter(w->            //  Filter the words by:
     w.contains(a+b)      //   If the word contains `a+b`
      &!w.contains(f?     //   If the flag is true (after):
                   c+a+b  //    And the word does not contain `c+a+b`
                  :       //   Else (before):
                   a+b+c) //    And the word does not contain `a+b+c`
     |w.contains(f?       //   If the flag is true (after):
                  c+b+a   //    Or the word contains `c+b+a`
                 :        //   Else (before):
                  b+a+c)) //    Or the word contains `b+a+c`
   .count()               //  And get the amount of words left in the filtered result
  >                       //  And return whether this is larger than:
  D.stream()              //  Stream of the given dictionary again
   .filter(w->            //  Filtered by:
     w.contains(b+a)      //   If the word contains `b+a`
      &!w.contains(f?     //   If the flag is true (after):
                    c+b+a //    And the word does not contain `c+b+a`
                   :      //   Else (before):
                    b+a+c)//    And the word does not contain `b+a+c`
     |w.contains(f?       //   If the flag is true (after):
                  c+a+b   //    Or the word contains `c+a+b`
                 :        //   Else (before):
                  a+b+c)) //    Or the word contains `a+b+c`
   .count()               //  And get the amount of words left in the filtered result
\$\endgroup\$
2
\$\begingroup\$

Python 2, 109 107 bytes

lambda D,x,y,r,c:sum((((' '+w+' ')[w.find(p)+3*r]!=c)^(p==y+x))*2-1for p in(x+y,y+x)for w in D if p in w)>0

Try it online!

Takes Dictionary and rule input as D,x,y,r,c with r=0 to mean 'before' and r=1 to mean 'after'.

\$\endgroup\$

Your Answer

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

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