who are they?
they are Primes containing 666
these are Satan-Primes:[46663,266677,666599,666683,616669]
these are NOT :[462667,665669,36363631,555]


Every number bigger than 6661 has Satan-Primes behind him

The Challenge

Given an integer n>6661 find the Satan-Prime behind (or equal) and closest to itself.


Integer n=30000 has 3 Satan-Primes(SP) behind it:[6661, 16661, 26669].
Your code must return 26669 which is the closest behind it

Test Cases


66697->66697 (a SP returns himself)  


Yor code should work for any n in the range of your language.

This is , so the shortest answer in bytes wins!

  • 1
    \$\begingroup\$ define "about a minute." Is it +- 30 seconds? I personally think that 30 minutes and a minute don't differ that much... Also bonuses are generally frowned upon... also I think this might have been better as an output the nth satan prime challenge... \$\endgroup\$ – Socratic Phoenix Aug 25 '17 at 16:47
  • \$\begingroup\$ ok ok people... bonus will be removed... \$\endgroup\$ – user73398 Aug 25 '17 at 16:51
  • \$\begingroup\$ Hope you don't mind the edit I made to the challenge title. \$\endgroup\$ – Shaggy Aug 25 '17 at 17:29
  • 3
    \$\begingroup\$ @Shaggy What point does the title change serve...? \$\endgroup\$ – Conor O'Brien Aug 26 '17 at 1:40
  • 3
    \$\begingroup\$ @ConorO'Brien Rhyming and appearing archaic, I presume. \$\endgroup\$ – wizzwizz4 Aug 26 '17 at 15:17

22 Answers 22


Mathematica, 82 bytes

  • \$\begingroup\$ Wait, you mean there isn't a built-in for this one? \$\endgroup\$ – Fund Monica's Lawsuit Aug 27 '17 at 16:38

Neim, 9 bytes



>         Increment input
 ͻ        Start infinite loop
  :        Previous prime
   D       Duplicate
    +6     Push 666
      S    Swap
       𝕚   See if 666 is a substring of the top of the stack
        ÷  If true, break

Try it online!

  • \$\begingroup\$ So there's really a builtin to push "66 prepended to a digit"? O_O Neim has progressed. \$\endgroup\$ – Erik the Outgolfer Aug 25 '17 at 19:10
  • 1
    \$\begingroup\$ How does +6 push 666? Or is Neim just that metal? \$\endgroup\$ – Robert Fraser Aug 26 '17 at 5:58
  • 6
    \$\begingroup\$ @RobertFraser Apparently +x means 612 + character code of x. The code of 6 happens to be 54, so 612+54=666. \$\endgroup\$ – fergusq Aug 26 '17 at 8:19
  • \$\begingroup\$ @EriktheOutgolfer Well, Neim can represent all three digits numbers and a few four digits using two bytes. \$\endgroup\$ – Okx Aug 26 '17 at 12:32
  • 2
    \$\begingroup\$ @EriktheOutgolfer '\+* = 100,356,612,868 (plus the ordinal of the following char that is) \$\endgroup\$ – Jonathan Allan Aug 26 '17 at 13:13

Jelly, 10 9 bytes

Saved 10% thanks to @Dennis!


Try it online!


ÆR          # All primes in range [2, input]
   Ðf      # Keep those which satisfy
  w        # truthy if y is in x
     666   #           ^ (this is y)
        Ṫ  # Tail (take the last element)
  • \$\begingroup\$ Alternative: ÆRẇ@Ðf666Ṁ \$\endgroup\$ – Mr. Xcoder Aug 25 '17 at 17:30
  • 5
    \$\begingroup\$ I love that the Tail (right after 666) looks like a cross. \$\endgroup\$ – kaine Aug 25 '17 at 20:11
  • 4
    \$\begingroup\$ w should work instead of ẇ@. \$\endgroup\$ – Dennis Aug 26 '17 at 3:21
  • \$\begingroup\$ @Dennis s/sh/w/ of course it works :p \$\endgroup\$ – Erik the Outgolfer Aug 26 '17 at 13:17

Pyth, 15 14 bytes

Saved 1 byte with help from Dave.

Memory errors for 969696 and anything higher on my machine, but it is fine if it is given enough memory.


Try it here or check out the Test Suite.


ef&/`T*3\6P_TSQ - Full program, with implicit input (Q) at the end

             SQ - Range [1,Q]
 f              - Filter.
          P_T   - Is prime?
  &             - And
   /`T*3\6      - It contains 666.
e               - Last element.
                - Implicitly output the result.

Pyth, 14 bytes


Try it here!

  • \$\begingroup\$ 14 bytes: ef&/`T*3\6P_TS \$\endgroup\$ – Dave Aug 25 '17 at 17:10
  • \$\begingroup\$ I added the ending Q by mistake, its 14 \$\endgroup\$ – Dave Aug 25 '17 at 17:10
  • \$\begingroup\$ "666" is a less efficient way to describe the string 666 that *3\6 \$\endgroup\$ – Dave Aug 25 '17 at 17:11

05AB1E, 11 bytes


Try it online!


Bash + Core Utils, 51 49 Bytes

seq $1|tac|factor|awk 'NF==2&&/666/&&!a--&&$0=$2'

Takes command line argument. Can be quite slow with larger numbers.

  • \$\begingroup\$ This outputs all "satan primes" down to 6661, but it should only be printing the closest one below the input: try it online. One fix would be to just add |head -1 to the end. \$\endgroup\$ – Justin Mariner Aug 26 '17 at 2:47
  • \$\begingroup\$ @JustinMariner lol, whoops, fixed it \$\endgroup\$ – markasoftware Aug 26 '17 at 4:25

Mathematica, 64 62 61 53 bytes


-1 byte thanks to @KellyLowder

-8 bytes (wow) thanks to @Notatree


Take an input. We decrement it under these conditions:

  • the input is not prime, OR

  • the digits of the inputs does not contain three 6s in a row.

We repeat that until a Satan prime is reached.

  • 2
    \$\begingroup\$ Very nice. You can lose one more _ at the end since a prime can't end in 6. \$\endgroup\$ – Kelly Lowder Aug 25 '17 at 20:33
  • \$\begingroup\$ @KellyLowder good point \$\endgroup\$ – JungHwan Min Aug 26 '17 at 4:13
  • 1
    \$\begingroup\$ This is even shorter with strings: #//.i_/;!PrimeQ@i||ToString@i~StringFreeQ~"666":>i-1& \$\endgroup\$ – Not a tree Aug 26 '17 at 5:44
  • 1
    \$\begingroup\$ @Notatree wow! nice! \$\endgroup\$ – JungHwan Min Aug 26 '17 at 15:05

Perl 5, 47 bytes

46 bytes of code + 1 for -p


Try it online!


Japt, 14 bytes

õ fj w æ_sø666

Test it

Seeing as there was a 50% time-based bonus: Completes test case 969696 in under half a second.


Implicit input of integer U.


Generate an array of integers from 1 to U.


Filter (f) primes.




Return the first element that returns a truthy value (in this case 1) when passed through a function that checks if ...


The integer converted to a string (s) contains (ø) 666.

Faster Alternative, 15 bytes

Again, seeing as there was originally a time-based bonus, here's an alternative, and much faster, solution which I can't seem to golf any further.

U-@j *U´sø666}a

Test it


PowerShell, 128 bytes

param($n)function f($a){for($i=2;$a-gt1){if(!($a%$i)){$i;$a/=$i}else{$i++}}}for(){if($n-match666-and($n-eq(f $n))){$n;exit}$n--}

Try it online!

PowerShell doesn't have any prime factorization built-ins, so this borrows code from my answer on Prime Factors Buddies.

We take input $n, then declare a new function f that calculates out the factors of input $a. If the input $a is prime, then this will return just $a.

The main part of the program is the infinite for() loop. Inside the loop, we check if $n -matches against 666 and whether $n is prime (i.e., $n matches all of the factors of $n). If it is, we place $n on the pipeline and exit, with implicit output. Otherwise, we decrement $n-- and continue the loop.


Python 2, 77 76 bytes

Edit: -1 byte thanks to @Mr.Xcoder

Slow running time, runs in O(n^2)

lambda x:max(q for q in range(x+1)if"666"in`q`*all(q%t for t in range(2,q)))

Try it online!

Another 76 bytes solution

lambda x:max(q*("666"in`q`*all(q%t for t in range(2,q)))for q in range(x+1))

Try it online!

With SymPy 73 bytes

lambda x:max(q for q in primerange(0,x+1)if"666"in`q`)
from sympy import*

Try it online!

  • \$\begingroup\$ 76 bytes: lambda x:max(q for q in range(x+1)if"666"in`q`*all(q%t for t in range(2,q))) - use max() instead of [][-1] \$\endgroup\$ – Mr. Xcoder Aug 25 '17 at 17:18

PowerShell, 71 69 64 bytes


Try it online!

  • 328765 takes ~30 seconds on my machine, but times out the 60 second limit on Tio.run.

  • 678987 takes ~1.5 minutes.

  • 969696 takes ~4.5 minutes.
  • \$\begingroup\$ Clever way of doing the factors. \$\endgroup\$ – AdmBorkBork Aug 29 '17 at 12:33

MATL, 16 bytes


Try it at MATL Online


         Implicitly grab input (n)
Zq       Compute the primes up to n (output is in increasing order)
P        Flip the array (so larger primes come first)
"        For each prime
  @V     Convert it to a string
  '666'  Push the string literal '666' to the stack
  Xf     Find the location of '666' in the prime
  ?      If it was present...
    @.   Push it to the stack and break
         Implicitly display the stack contents

C++ 389 bytes

#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/miller_rabin.hpp>
using namespace boost::random;typedef boost::multiprecision::cpp_int Z;int main(int,char**v){mt19937 m(clock());independent_bits_engine<mt11213b,256,Z>g(m);Z n{v[1]},p;while(p++<=n)if(miller_rabin_test(p,25,g)&&p.convert_to<std::string>().find( "666" )!=-1)std::cout<<p<<" ";}

This is a full program!
You'll need Boost to compile it. (Or copy and paste into your favorite online C++ shell.)
Run it from the command-line giving n as argument.


#include <iostream>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/multiprecision/miller_rabin.hpp>
using namespace boost::random;

typedef boost::multiprecision::cpp_int integer;

int main( int argc, char** argv )
  mt19937 mt( clock() );
  independent_bits_engine <mt11213b, 256, integer> rng( mt );

  integer input {argv[ 1 ]};
  integer possible;

  while (possible++ <= input)
    if (
      // is_prime( possible )
      miller_rabin_test( possible, 25, rng )
      // possible has "666" in it
      (possible.convert_to <std::string> ().find( "666" ) != std::string::npos))

    std::cout << possible << " ";

Shortcuts were made in terms of random number testing. The original code started testing possible primes at 6661 and incremented by two. You'll also get a compiler warning because of that (-1) there instead of npos.

Still, this runs pretty quickly. It only took about 40 seconds to find all 214 satan primes under 1,000,000 on my old AMD Sempron 130.



Bash + bsd-games package, 33

  • 2 bytes saved thanks to @FedericoPoloni.
primes 2 $[$1+1]|grep 666|tail -1

Try it online.

  • \$\begingroup\$ You can save 1 byte if you replace the last two commands with tail -n1. \$\endgroup\$ – Federico Poloni Aug 26 '17 at 8:10
  • \$\begingroup\$ @FedericoPoloni duh - can't believe I forgot tail here. In fact tail -1 is even 1 less. \$\endgroup\$ – Digital Trauma Aug 30 '17 at 16:56

Python 3, 85 83 80 bytes

Halvard's is 4 bytes shorter because it's done in Python 2.

lambda k:max(x for x in range(k+1)if"666"in str(x)*all(x%i for i in range(2,x)))

Try it online!

Give it some time, it's extremely slow because of its O(n^2) complexity.


JavaScript (ES6), 55 54 bytes

-1 byte thanks to @ThePirateBay.


Very slow with large inputs. Primality test adapted from this code golf answer.


  • Input 10000 took 10 seconds
  • Input 328765 took 3 minutes
  • Input 678987 took 9 minutes
  • Input 969696 took 16 minutes


Some of these will hang your browser for several minutes.


function test(n) {
    let t = Date.now()
    O.value=`f(${n}) = ${f(n)} in ${(Date.now()-t)/1000}s`
  }, 10)
<button onclick="test(6662)">6662</button>
<button onclick="test(10000)">10000</button>
<button onclick="test(328765)">328765</button>
<button onclick="test(678987)">678987</button>
<button onclick="test(969696)">6662</button><br>
<input id=O type=text size=25 readonly>

Faster Version, 56 bytes

Completes each test case in under a second.


;[6662, 10000, 328765, 678987, 969696].forEach(n=>console.log(`f(${n}) -> ${f(n)}`))

  • 2
    \$\begingroup\$ You should never do that. This is code golf and the performance is totally irrelevant. I strongly suggest rolling back to your previous 55 byte answer. Also, you can reduce it to 54 bytes by replacing d==1 with d<2 since n>6661. \$\endgroup\$ – user72349 Aug 26 '17 at 5:41
  • \$\begingroup\$ 52 bytes: f=n=>/666/.test(n)&(g=d=>n%--d?g(d):d<2)(n)?n:f(n-1) but will throw a recursion error for larger numbers. \$\endgroup\$ – Shaggy Aug 30 '17 at 16:45
  • \$\begingroup\$ f=n=>/666/.test(d=n)-eval("while(n%--d);d")?f(n-1):n \$\endgroup\$ – l4m2 May 2 '18 at 10:22

Ruby, 67, 66, 58, 56 bytes

Includes +7 bytes for -rprime


It's pretty fast, computing values up to ~2^52 in about a second and 2^64 in under 5 minutes (2011 MBP, Ruby 2.3.1).


Stax, 10 bytes


Run and debug it

Explanation (unpacked):

^w:pc$666$#! Full program, implicit input-parsing
^            Increment input
 w           do-while:
  :p           Previous prime
    c$         Copy and stringify
      666$     Push "666"
          #    Number of occurences
           !   Logical not
             Implicit output
  • \$\begingroup\$ Nice program. Thanks for trying stax. FYI, it's also possible to do multiple cases by using the "Separator" option like this \$\endgroup\$ – recursive May 1 '18 at 14:09
  • \$\begingroup\$ @recursive ah, thx \$\endgroup\$ – wastl May 1 '18 at 14:48

PHP, 148 bytes

<?php $p=[2];$s=[];for($i=3;$i<=$argv[1];$i++){foreach($p as $q)if($i%$q===0)continue 2;$p[]=$i;if(strpos($i,'666')!==false)$s[]=$i;}echo end($s);?>

Try it online!


Perl 6, 35 bytes

my&f={/666/&&.is-prime??$_!!f $_-1}

Try it online!

Straightforward recursive solution.


C# (.NET Core), 117 115 112 bytes

f=>{for(int i=f;i>1;i--){int p=1,j=2;while(j<i)if(i%j++<1)p=0;if(p>0&$"{i}".Contains("666"))return i;}return 0;}

Try it online!

  • 2 bytes saved by removing unnecessary braces.
  • 3 bytes saved by combining int declarations.

I'm sure this could be made shorter; maybe by recursively calling func f and removing the outer for-loop.

Recursive Approach, 85 bytes

i=>{int p=1,j=2;while(j<i)if(i%j++<1)p=0;return p>0&$"{i}".Contains("666")?i:f(--i);}

Try it online!

I'm unsure how well this approach fits within the bounds of code-golf due to having to set the Func<int,int> f = null first, and that f is called again, but not counted towards the bytes. Any clarification would be appreciated.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy