Can the number reach 1 by repeatedly subtracting the largest prime less than it?

27

1

Challenge:

Given a number, take the largest prime strictly less than it, subtract it from this number, do this again to this new number with the biggest prime less than it, and continue doing this until it's less than 3. If it reaches 1, your program should output a truthy value, else, the program should output a falsey value.

Examples:

All of these should give a truthy value:

3
4
6
8
10
11
12
14
16
17
18
20
22
23
24
26
27
29
30
32
34
35
37
38
40
41
42
44
46
47
48
50

All of these should give falsey values:

5
7
9
13
15
19
21
25
28
31
33
36
39
43
45
49

Rules:

  • You can either write a program or function.
  • You can assume that the input is bigger than 2.
  • Standard loopholes apply
  • This is so the shortest answer wins!

Loovjo

Posted 2016-09-11T12:14:56.830

Reputation: 7 357

related http://oeis.org/A175071

– flawr – 2016-09-11T14:10:59.933

15-3=2, 2-(-2)=4, 4-3=1. (/wiseguy) – None – 2016-09-11T16:36:30.177

@Hurkyl -2 = -1×2, so it's not prime ;-) – ETHproductions – 2016-09-11T19:26:07.310

1@ETHProductions: Ah, but -1 is a unit; that factorization doesn't contradict the primality of -2 any more than 2=(-1)×(-2) does of 2. (or even 2=1×2) – None – 2016-09-11T19:31:40.510

@ETHproductions - just to clarify further, primes are numbers that cannot be expressed as the product of two or more other primes, but that also can't divide 1. If they can divide 1, they are called units, not primes. Both 1 and -1 are units. – Glen O – 2016-09-12T13:39:16.083

@Hurkyl - shame the question specifies "until it's less than 3". Otherwise, you'd be right. – Glen O – 2016-09-12T13:40:01.877

@GlenO Thanks for the explanation. Out of curiosity, does this mean that 1/2, -1/2, etc. are also units, or does this rule only apply to integers? – ETHproductions – 2016-09-12T13:55:17.153

@ETHproductions - it doesn't only apply to integers, but it doesn't apply to the rational numbers under the normal definitions of addition and multiplication. In fact, if you're considering the rational numbers (rather than the integers), then no number is prime. – Glen O – 2016-09-12T14:01:59.347

3@ETHproductions: The rational numbers are interesting because there are two very different approaches that are useful in practice! The rational numbers has no primes (not even 2!) because everything is a unit. However, you can also view the rationals as a construction made from the integers and study them using the primes of the integers. (e.g. anyone asking for the prime factorization of 9/10 as 2^(-1) 3^2 5^(-1) is thinking in terms of the latter) – None – 2016-09-12T17:15:56.983

@Hurkyl Fascinating! Thanks for educating me. So by the latter thinking, is 1/p always prime if p is prime? – ETHproductions – 2016-09-13T01:09:18.997

Answers

8

Jelly, 9 8 bytes

’ÆRṪạµ¡Ḃ

Try it online! or verify all test cases.

How it works

’ÆRṪạµ¡Ḃ  Main link. Argument: n

     µ    Combine all atoms to the left into a chain.
’           Decrement; yield n - 1.
 ÆR         Prime range; yield all primes in [2, ..., n -1].
   Ṫ        Tail; yield p, the last prime in the range.
            If the range is empty, this yields p = 0.
    ạ       Compute the absolute difference of p and n.
      ¡   Call the chain to the left n times.
          This suffices since each iteration decreases n, until one of the fixed
          points (1 or 2) is reached.
       Ḃ  Bit; return the parity of the fixed point.

Dennis

Posted 2016-09-11T12:14:56.830

Reputation: 196 637

11

Retina, 31 bytes

.+
$*
+`1(?!(11+)\1+$)11+
1
^1$

Prints 0 (falsy) or 1 (truthy).

Try it online! (The first line enables a linefeed-separated test suite.)

Explanation

.+
$*

Convert input to unary by turning input N into N copies of 1.

+`1(?!(11+)\1+$)11+
1

Repeatedly remove the largest prime less than the input. This is based on the standard primality test with regex.

^1$

Check whether the result is a single 1.

Martin Ender

Posted 2016-09-11T12:14:56.830

Reputation: 184 808

How is it that you can use Retina without unary? O.o – Addison Crump – 2016-09-11T12:39:10.247

@Syxer the first two lines convert the input to unary. – Martin Ender – 2016-09-11T12:39:24.123

Doesn't that mean you can remove them and request unary input? – Addison Crump – 2016-09-11T12:40:06.697

2@Syxer I could, but I sort of stopped doing that. It seems like a dodgy I/O format, and now that the conversion is 6 bytes (as opposed to the ~200 it used to be), I don't think Retina counts as "can't reasonably take input in decimal". – Martin Ender – 2016-09-11T12:41:41.333

Ah, I see. I've only ever seen unary input in Retina, thus my confusion. – Addison Crump – 2016-09-11T12:45:28.263

8

Pyth, 18 15 14 bytes

Thanks to @Maltysen for -1 byte

#=-QefP_TUQ)q1

A program that takes input on STDIN and prints True or False as appropriate.

Try it online

How it works

#=-QefP_TUQ)q1  Program. Input: Q
#          )    Loop until error statement (which occurs when Q<3):
         UQ      Yield [0, 1, 2, 3, ..., Q-1]
     fP_T        Filter that by primality
    e            Yield the last element of that
 =-Q             Q = Q - that
            q1  Q is 1 (implicit variable fill)
                Implicitly print

Old version with reduce, 18 bytes

qu-G*<HGH_fP_TSQQ1

Try it online

How it works

qu-G*<HGH_fP_TSQQ1  Program. Input: Q
              SQ    Yield [1, 2, 3, ..., Q]
          fP_T      Filter that by primality
         _          Reverse it
 u                  Reduce it:
                Q    with base case Q and
                     function G, H -> 
     <HG              H<G
    *   H             *H (yields H if H<G, else 0)
  -G                  Subtract that from G
q                1  The result of that is 1
                    Implicitly print

TheBikingViking

Posted 2016-09-11T12:14:56.830

Reputation: 3 674

St is U 15 chars – Maltysen – 2016-09-11T18:45:31.847

7

JavaScript (ES6), 64 63 bytes

Saved 1 byte thanks to @Neil

g=(x,n=x-1)=>n<2?x:x%n?g(x,n-1):g(x-1)
f=x=>x<3?x%2:f(x-g(x-1))

I wrote this in 2 minutes... and it worked perfectly the first time. First user to find the inevitable bug wins....

Try it out

g=(x,n=x-1)=>n<2?x:x%n?g(x,n-1):g(x-1)
f=x=>x<3?x%2:f(x-g(x-1))
<input type="number" value=3 min=3 onchange="A.innerHTML=f(this.value)"><br>
<p id=A>1</p>

How it works

First we define g(x) as the function that finds the first prime number p <= x. This is done using the following process:

  1. Start with n = x-1.
  2. If n < 2, x is prime; return x.
  3. If x is divisible by n, decrement x and go to step 1.
  4. Otherwise, decrement n and go to step 2.

The solution to this challenge, f(x), is now fairly straightforward:

  1. If x < 3, return x = 1.
  2. Otherwise, subtract g(x-1) and try again.

ETHproductions

Posted 2016-09-11T12:14:56.830

Reputation: 47 880

4326, which should return true does not seem to return, but 4328 (true) and 4329 (false) do, is this a JS limitation or a bug? – Jonathan Allan – 2016-09-11T20:34:14.340

@JonathanAllan 4326 throws too much recursion to the browser console in Firefox 48, so I guess the recursion passes FF's recursion limit. – ETHproductions – 2016-09-11T20:38:25.197

Yep, next prime down is 4297 (and next up is 4327), which will be why 4328 works. – Jonathan Allan – 2016-09-11T20:44:48.057

4x%2 should save you a byte over x==1. – Neil – 2016-09-11T23:52:30.683

@Neil I would never have thought of that :-) – ETHproductions – 2016-09-12T13:56:28.397

@Neil, ooo... this will save me a byte in another question. +1 – Magic Octopus Urn – 2016-09-12T20:38:09.830

@JonathanAllan If you want an iterative version, I came up with x=>[1,1,...Array(x)].map((c,i,b)=>(a[i]=a[i-p],c||b.map((_,j)=>b[j]|=j%i<1,p=i)),a=[,1],p=0)&&a[x] - it's a bit long though. – Neil – 2016-09-12T23:38:28.023

@Neil I was just wondering what the reason was, it's fine to have correct code that only fails due to a recursion limitation IMO; but nice stuff! – Jonathan Allan – 2016-09-12T23:56:49.193

6

Pyke, 15 11 bytes

WDU#_P)e-Dt

Try it here!

            - stack = input
W           - while continue:
  U#_P)     -     filter(is_prime, range(stack))
       e    -    ^[-1]
 D      -   -   stack-^
         Dt -  continue = ^ != 1

Returns 1 if true and raises an exception if false

Blue

Posted 2016-09-11T12:14:56.830

Reputation: 26 661

5

Julia, 32 bytes

While it's not going to be the shortest solution among the languages, this might be the shortest of the human-readable ones...

!n=n>2?!(n-primes(n-1)[end]):n<2

Or, to put it in slightly clearer terms

function !(n)
  if n>2
    m=primes(n-1)[end]   # Gets largest prime less than n
    return !(n-m)        # Recurses
  else
    return n<2           # Gives true if n is 1 and false if n is 2
  end
end

Called with, for example, !37.

Glen O

Posted 2016-09-11T12:14:56.830

Reputation: 2 548

3

Mathematica, 32 bytes

2>(#//.x_/;x>2:>x+NextPrime@-x)&

This is an unnamed function which takes an integer and returns a boolean.

Explanation

There's a lot of syntax and funny reading order here, so...

   #                               This is simply the argument of the function.
    //.                            This is the 'ReplaceRepeated' operator, which applies
                                   a substitution until the its left-hand argument stops
                                   changing.
       x_/;x>2                     The substitution pattern. Matches any expression x as
                                   long as that expression is greater than 2.
              :>                   Replace that with...
                  NextPrime@-x     Mathematica has a NextPrime built-in but no
                                   PreviousPrime built-in. Conveniently, NextPrime
                                   works with negative inputs and then gives you the 
                                   next "negative prime" which is basically a
                                   PreviousPrime function (just with an added minus sign).
                x+                 This gets added to x, which subtracts the previous
                                   prime from it.
2>(                           )    Finally, we check whether the result is less than 2.

Martin Ender

Posted 2016-09-11T12:14:56.830

Reputation: 184 808

Closely beats #+0~Min~NextPrime@-#&~FixedPoint~#==1& (36 bytes). Nice use of //. ! – Greg Martin – 2016-09-11T20:31:19.533

1@GregMartin 35 when you use <2 at the end. – Martin Ender – 2016-09-11T20:54:58.347

3

Python3, 102 92 90 89 88 bytes

f=lambda n:n<2if n<3else f(n-[x for x in range(2,n)if all(x%y for y in range(2,x))][-1])

Golfing suggestions welcome! I see that gmpy contains a function next_prime, but I can't test it yet :(

-2 bytes, thanks to @JonathanAllan!

-1 byte, thanks to @Aaron!

Testcases

f=lambda n:n<2if n<3else f(n-[x for x in range(2,n)if all(x%y for y in range(2,x))][-1])

s="3 4 6 8 10 11 12 14 16 17 18 20 22"
h="5 7 9 13 15 19 21 25 28 31 33 36 39"

for j in s.split(" "):print(f(int(j)))
for j in h.split(" "):print(f(int(j)))

Output is 13 truthy values and 13 falsey values. s contains the truthy cases and h the falseys.

Yytsi

Posted 2016-09-11T12:14:56.830

Reputation: 3 582

1if all(x%y for... works – Jonathan Allan – 2016-09-11T18:00:53.957

1n<3 else -> n<3else to get same length as mine ;) – Aaron – 2016-09-13T16:20:40.140

2

Python, with sympy, 60 bytes

import sympy
f=lambda n:n>2and f(n-sympy.prevprime(n))or n<2

My previous method was 83 bytes without sympy using recursion, but I took truthy/falsey to mean distinguishable and consistent, but I have been informed that's an incorrect interpretation. I can't seem to salvage it due to the tail, but I'll leave it here in case someone knows how to do so:

f=lambda n,p=0:n>2and(any(p%x==0for x in range(2,p))and f(n,p-1)or f(n-p,n+~p))or n

Jonathan Allan

Posted 2016-09-11T12:14:56.830

Reputation: 67 804

2 is not a falsey value. – mbomb007 – 2016-09-12T13:45:31.353

@mbomb007 I thought specs are "true or false" if that is required, whereas "truthy or falsey" means distinguishable and consistent? – Jonathan Allan – 2016-09-12T21:01:03.860

1Nope. They are defined as we decided on the meta site. Any question that allows "distinguishable and consistent" output must specify that, rather than truthy/falsey. – mbomb007 – 2016-09-12T21:04:13.483

OK I read this, will update at some point...

– Jonathan Allan – 2016-09-12T21:20:41.003

1

Vitsy, 28 26 bytes

This can definitely be shortened.

<]xN0)l1)-1[)/3D-];(pD-1[D

<                    Traverse the code in this direction, rotating on the line.
                     For the sake of reading the code easier, I'm reversing the
                     code on this line. This will be the order executed.

 D[1-Dp(;]-D3/)[1-)1l)0Nx]
 D                         Duplicate the top member of the stack.
  [      ]                 Do the stuff in brackets until break is called.
   1-                      Subtract 1 from the top item of the stack.
     D                     Duplicate the top member of the stack.
      p(                   If the top member is a prime...
        ;                  break;
          -                Pop a, b, push a - b.
           D3/)[         ] If this value is less than 3, do the bracketed code.
                1-         Subtract the top item of the stack by 1.
                  )        If the top item is zero...
                   1       Push 1.
                    l)     If the length of the stack is zero...
                      0    Push 0.
                       N   Output the top member of the stack.
                        x  System.exit(0);

Try it online!

Addison Crump

Posted 2016-09-11T12:14:56.830

Reputation: 10 763

1

CJam, 21 16 bytes

Thanks to Dennis for saving 4 bytes.

ri{_1|{mp},W=-}h

Try it online!

Explanation

ri       e# Read input and convert to integer N.
{        e# Run this block as long as N is positive (or until the program aborts
         e# with an error)...
  _1|    e#   Duplicate and OR 1. This rounds up to an odd number. For N > 2, this
         e#   will never affect the greatest prime less than N.
  {mp},  e#   Get all primes from 0 to (N|1)-1.
         e#   For N > 2, this will contain all primes less than N.
         e#   For N = 2, this will contain only 2.
         e#   For N = 1, this will be empty.
  W=     e#   Select the last element (largest prime up to (N|1)-1).
         e#   For N = 1, this will result in an error and terminate the program, which
         e#   still prints the stack contents though (which are 1, the desired output).
  -      e#   Subtract from N. Note that this gives us 0 for N = 2, which terminates the 
         e#   loop.
}h

Martin Ender

Posted 2016-09-11T12:14:56.830

Reputation: 184 808

ri_{_1|{mp},W=-}* should work. – Dennis – 2016-09-11T19:01:56.313

@Dennis Thanks, the 1| is really clever. :) (And I always forget that {...}, does an implicit range...) – Martin Ender – 2016-09-11T21:00:26.353

1

MATL, 13 bytes

`tqZq0)-t2>}o

Try it online! Or verify all test cases at once.

Explanation

`        % Do...while
  t      %   Duplicate. Takes input implicitly in the first iteration
  qZq    %   All primes less than that
  0)     %   Get last one
  -      %   Subtract (this result will be used in the next iteration, if any)
  t      %   Duplicate
  2>     %   Does it exceed 2? If so: next iteration. Else: execute the "finally" 
         %   block and exit do...while loop
}        % Finally
  o      %   Parity. Transforms 2 into 0 and 1 into 1
         % End do...while implicitly
         % Display implicitly

Luis Mendo

Posted 2016-09-11T12:14:56.830

Reputation: 87 464

1

Perl, 42 bytes

Includes +1 for -p

Run with input on STDIN

reach1.pl:

#!/usr/bin/perl -p
$_=1x$_;$_=$`while/\B(?!(11+)\1+$|$)|11$/

Uses the classic primality regex

Ton Hospel

Posted 2016-09-11T12:14:56.830

Reputation: 14 114

1

.NET Regex, 38 bytes

Just to show that it can be checked in a single regex.

^(?>(?<=(.*))..+(?<!^\1\2+(.+.)|$))+.$

Input is assumed to be in unary.

Explanation

It simply implements the requirement to the word, repeatedly removing the biggest prime and check whether there remainder is 1.

  • (?>(?<=(.*))..+(?<!^\1\2+(.+.)|$))+: Non-backtracking group makes sure the biggest prime we found is not overriden, and + simply repeat the process of matching the biggest prime.

    • (?<=(.*))..+(?<!^\1\2+(.+.)|$): Match the biggest prime less than the remaining number

      • (?<=(.*)): Record how much we have subtracted to establish an "anchor" point for assertion.

      • ..+: Look for the biggest number...

      • (?<!^\1\2+(.+.)|$): ... which is prime and less than the remaining number.
        • (?<!^\1\2+(.+.)): The usual prime test routine, with ^\1 tacked in front to make sure we are checking the amount matched by ..+
        • (?!<$): Assert less than the remaining number

n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Posted 2016-09-11T12:14:56.830

Reputation: 5 683

The (?<=(.*)) part is rather clumsy. Not sure if there is a better way. Also, I'm curious if there is a solution in PCRE. – n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳ – 2016-09-13T10:50:41.007

0

Clojure, 125 bytes

#(loop[x %](if(> x 2)(recur(- x(loop[y(dec x)](if(some zero?(vec(for[z(range 2 y)](mod y z))))(recur(dec y))y))))(quot 1 x)))

Yikes, that is one long piece of code. The most verbose language strikes again!

Ungolfed:

(defn subprime [n]
  (loop [x n]
    (if (> x 2)
      (recur
        (- x
          (loop [y (dec x)]
            (if (some zero? (vec (for [z (range 2 y)] (mod y z))))
              (recur (dec y)) y))))
      (quot 1 x))))

clismique

Posted 2016-09-11T12:14:56.830

Reputation: 6 600

0

Floroid, 45 30 29 bytes

f=Bb:b<2Fb<3Gf(b-en(b-1)[-1])

Yytsi

Posted 2016-09-11T12:14:56.830

Reputation: 3 582

0

Perl 6,  54 53 52  51 bytes

{($_,{$_-($_-1...2).first: *.is-prime}...3>*)[*-1]==1}
{($_,{$_-($_-1...2).first: *.is-prime}...3>*).any==1}
{any($_,{$_-($_-1...2).first: *.is-prime}...3>*)==1}
{any($_,{$_-(^$_).grep(*.is-prime)[*-1]}...3>*)==1}

Explanation:

# bare block lambda with implicit parameter 「$_」
# used to generate all of the rest of the elements of the sequence
{
  # create an any Junction of the following list
  any(
    $_, # initialize sequence with the inner block's argument

    # bare block lambda with implicit parameter 「$_」
    {
      # take this inner block's argument and subtract
      $_ -

      ( ^$_ )            # Range up-to and excluding 「$_」
      .grep(*.is-prime)\ # find the primes
      [ * - 1 ]          # return the last value
    }

    ...   # keep doing that until

    3 > * # the result is less than 3

  # test that Junction against 「1」
  # ( returns an 「any」 Junction like 「any(False, False, True)」 )
  ) == 1
}

Example:

# show what is returned and if it is truthy
sub show ($_) {
  # 「.&{…}」 uses the block as a method and implicitly against 「$_」
  my $value = .&{any($_,{$_-(^$_).grep(*.is-prime)[*-1]}...3>*)==1}
  say join "\t", $_, ?$value, $value.gist;
}

show 3;  # 3    True    any(False, True)
show 4;  # 4    True    any(False, True)
show 5;  # 5    False   any(False, False)
show 10; # 10   True    any(False, False, True)
show 28; # 28   False   any(False, False, False)
show 49; # 49   False   any(False, False)
show 50; # 50   True    any(False, False, True)

Brad Gilbert b2gills

Posted 2016-09-11T12:14:56.830

Reputation: 12 713

0

Irregular, 63 bytes

p~?1_$-1p:;
n=i(0)?1_$-1p:;
_~
N=n
1(?!(11+)\1+$)11+~1
^11$~0
N

I created this language two days ago, and the basic premises are that there are no built in loops, the only features are basic arithmetic and decision making, and program evaluation is based on regular expressions.

Explanation

p~?1_$-1p:;
n=i(0)?1_$-1p:;
_~
N=n

This part converts the input into unary. It repeatedly subtracts 1 from the input until it equals 0, prepending 1_ each time. It then removes all of the _s. If I hadn't forgotten a break in my code it could be written as so:

p~?1_$-1p:;
_~
n=i(0)?1_$-1p:;

The next part repeatedly removes the largest prime from the input until it is equal to 1 or 11, with 11 being replaced with 0.

1(?!(11+)\1+$)11+~1
^11$~0
N

I used the regex from Martin Ender's answer.

DanTheMan

Posted 2016-09-11T12:14:56.830

Reputation: 3 140

0

Haskell, 79 bytes

Not really short but pointfree :)

(<2).until(<3)(until(flip(`until`(+1))2.(.)(<1).mod>>=(==))pred.pred>>=flip(-))

Damien

Posted 2016-09-11T12:14:56.830

Reputation: 2 407

0

PowerShell v2+, 81 bytes

param($n)while($n-gt2){$n-=(($n-1)..2|?{'1'*$_-match'^(?!(..+)\1+$)..'})[0]}!--$n

Takes input $n. Enters a while loop so long as $n is still 3 or greater. Each iteration, subtracts a number from $n. The number is the results of the regex primality test applied against a range ($n-1)..2 via the Where-Object (?) operator, then the first [0] of the results (since the range is decreasing, this results in the largest one being selected). After concluding the loop, $n is either going to be 1 or 2, by definition, so we pre-decrement $n (turning it into either 0 or 1), and take the Boolean-not ! thereof. That's left on the pipeline and output is implicit.

Examples

PS C:\Tools\Scripts\golfing> 3..20|%{"$_ --> "+(.\can-the-number-reach-one.ps1 $_)}
3 --> True
4 --> True
5 --> False
6 --> True
7 --> False
8 --> True
9 --> False
10 --> True
11 --> True
12 --> True
13 --> False
14 --> True
15 --> False
16 --> True
17 --> True
18 --> True
19 --> False
20 --> True

AdmBorkBork

Posted 2016-09-11T12:14:56.830

Reputation: 41 581

0

Matlab, 51 bytes

v=@(x)x-max(primes(x-1));while(x>=3)x=v(x);end;x==1

This is VERY similar to the JS6 solution by ETHProductions, but needs the variable to be in the workspace.

ptev

Posted 2016-09-11T12:14:56.830

Reputation: 111

0

Python 2.7: 88 87 Bytes

r=lambda n:n>2and r(n-[a for a in range(2,n)if all(a%b for b in range(2,a))][-1])or n<2

Thx @TuukkaX for -1 more byte!

Aaron

Posted 2016-09-11T12:14:56.830

Reputation: 1 213

1Update your description ;) Also, you could save one byte by saying n<2 instead of n==1. – Yytsi – 2016-09-14T09:37:22.587