17
\$\begingroup\$

Inspired by the recent craze over another two character language, ;#

Intro

According to community consensus, acceptable answers on this site must use programming languages that, at minimum:

  1. Can determine if a natural number is prime
  2. Can add two natural numbers together
  3. Can represent a list/tuple of numbers, as well as a single number

For purposes of this challenge, we will ignore #3. Therefore, the simplest language that could be used on this site (ignoring #3) would have exactly two commands, isPrime and add. For ease of interpretation and byte count, let's assign isPrime to p and add to +. Thus, we have our language, +p. Your challenge is to interpret some +p code.

Behavior

  • + the add instruction takes two numbers, adds them, and outputs the result
  • p the isPrime instruction takes a single number, and outputs 1 if it is prime, and 0 if it is not

Rules

  • You must write a program/function which, given a string of characters, interprets that string as +p code. You may assume well-formed input (only + and p characters).
  • Input is flexible. You may take in the program as a string, character array, integer array of codepoints, etc. Input for the program being interpreted is also flexible. You may take in an integer array, and use up entries as the program executes, or each instruction (+ and p) may individually request input. You may assume there will be enough input for every instruction. Input is guaranteed to consist of numbers between 0 and 200 (but your algorithms should theoretically work for any positive integer input).
  • Output is also flexible. You may print the results, return them as a list, return a string that contains all the results, etc. If printed or returned as a string, output must be separated by some non-digit, consistent separator, such as a new line, tab, space, or , character. You may have a trailing separator or some trailing whitespace. Also, p's output may be any truthy or falsey value, as defined by the language you are working in, rather than 1 or 0.
  • The interpreter may or may not terminate (if it is a full program), but it must stop printing after all instructions are interpreted. (It cannot continue printing the separator forever, or a null character, etc.).
  • These standard loopholes are forbidden by default
  • This is , the answer with the least bytes wins

Test Cases

Program: +
Input: [56, 50]
Output: 106 
----------------------------------
Program: p
Input: [12]
Output: 0 
----------------------------------
Program: p
Input: [13]
Output: 1 
----------------------------------
Program: ++
Input: [172, 120, 33, 58]
Output: 292 91 
----------------------------------
Program: p
Input: [29]
Output: 1 
----------------------------------
Program: pp
Input: [176, 12]
Output: 0 0 
----------------------------------
Program: ++++p
Input: [32, 16, 69, 197, 73, 171, 21, 178, 72]
Output: 48 266 244 199 0 
----------------------------------
Program: pp+++p+pp+
Input: [151, 27, 119, 189, 198, 107, 174, 15, 166, 106, 134, 108, 169, 55, 42]
Output: 1 0 308 305 189 0 240 0 0 97 
----------------------------------
Program: p+p+++++++pp+p
Input: [143, 67, 30, 149, 178, 52, 112, 122, 55, 122, 142, 199, 20, 175, 138, 80, 116, 180, 50, 116, 15, 92, 74]
Output: 0 97 1 230 234 177 341 195 218 296 0 0 107 0 
----------------------------------
Program: ++p++p+pp+++++p+p+pp++
Input: [120, 177, 23, 116, 163, 52, 65, 98, 177, 16, 96, 131, 160, 48, 153, 0, 139, 33, 62, 49, 129, 86, 99, 135, 187, 80, 137, 130, 113, 136, 0, 1, 186, 100, 38, 153]
Output: 297 139 1 117 275 0 227 0 0 153 172 111 215 234 0 217 0 249 0 0 286 191 
----------------------------------
Program: ++p+++++p+p+++++++
Input: [181, 169, 6, 84, 68, 171, 129, 107, 106, 114, 197, 58, 11, 88, 156, 169, 43, 77, 49, 43, 102, 78, 93, 51, 91, 37, 64, 93, 82, 126, 181, 81, 44]
Output: 350 90 0 300 213 311 69 244 0 120 0 145 171 142 101 175 307 125 
----------------------------------
Program: ++p+
Input: [131, 127, 115, 40, 113, 196, 83]
Output: 258 155 1 279 
----------------------------------
Program: +ppp++p+ppp+p++++++++p+p+++pp+ppp++
Input: [6, 9, 187, 168, 96, 167, 178, 139, 86, 148, 99, 103, 166, 18, 119, 15, 132, 77, 16, 88, 139, 34, 58, 90, 43, 69, 68, 152, 59, 106, 134, 49, 155, 100, 52, 55, 27, 188, 41, 77, 23, 49, 171, 23, 193, 84, 111, 165, 80, 18, 63, 23, 116, 112, 119]
Output: 15 0 0 0 345 225 0 202 0 0 0 147 0 104 173 148 112 220 165 183 255 0 82 0 118 72 194 1 0 276 0 0 0 139 231 
----------------------------------
Program: ++++++++p++++++++++++
Input: [156, 5, 34, 25, 117, 98, 139, 131, 88, 82, 191, 13, 1, 170, 51, 116, 144, 85, 92, 170, 25, 94, 149, 131, 19, 161, 115, 160, 8, 6, 195, 101, 11, 185, 87, 50, 33, 140, 188, 135, 164]
Output: 161 59 215 270 170 204 171 167 0 177 195 243 150 276 168 201 112 272 83 328 299 
----------------------------------

Many, many, very long test cases

The java code used to generate test cases

Example

Below is an ungolfed java function which will interpret +p:

public static void interpret(String program, int[] input) {
    int index = 0;
    for (char inst : program.toCharArray()) {
        switch (inst) {
            case '+':
                System.out.print((input[index++] + input[index++]) + " ");
                break;
            case 'p':
                int n = input[index++];
                System.out.print((isPrime(n) ? 1 : 0) + " ");
                break;
        }
    }
}

public static boolean isPrime(long n) { //Taken from https://stackoverflow.com/a/2385999/4484294
    if (n < 2) return false;
    if (n == 2 || n == 3) return true;
    if (n % 2 == 0 || n % 3 == 0) return false;
    long sqrtN = (long) Math.sqrt(n) + 1;
    for (long i = 6L; i <= sqrtN; i += 6) {
        if (n % (i - 1) == 0 || n % (i + 1) == 0) return false;
    }
    return true;
}

Note: Using the search query prime AND add AND interpret is:question, there do not appear to be any duplicates to this question. If there is one, sorry.

\$\endgroup\$
12
  • \$\begingroup\$ In your outputs the ps' results are concatenated without separator, is this intended? \$\endgroup\$ May 25, 2017 at 14:48
  • \$\begingroup\$ Can we use a heuristic prime test? i.e. isprime in julia. \$\endgroup\$
    – Riker
    May 25, 2017 at 14:58
  • \$\begingroup\$ Interestingly enough, I made an exact opposite to the challenge \$\endgroup\$ May 25, 2017 at 15:22
  • \$\begingroup\$ @GáborFekete They are? They look fine to me... \$\endgroup\$ May 25, 2017 at 15:29
  • \$\begingroup\$ @Riker If what you mean is prime tests that are unproven, then no. If not, please clarify. \$\endgroup\$ May 25, 2017 at 15:33

13 Answers 13

33
\$\begingroup\$

05AB1E, 5 bytes

vy.V,

Try it online!

Explanation

This challenge fit 05AB1E like a glove :)

vy      # for each instruction in the program
  .V    # execute as 05AB1E code
    ,   # print
\$\endgroup\$
8
  • 6
    \$\begingroup\$ Definitely the right tool for the job. \$\endgroup\$ May 25, 2017 at 14:49
  • 1
    \$\begingroup\$ This looks cheaty... I mean really. \$\endgroup\$
    – user63187
    May 25, 2017 at 14:51
  • \$\begingroup\$ @Christopher: Luckily + and p means add and isPrime in 05AB1E :) \$\endgroup\$
    – Emigna
    May 25, 2017 at 14:53
  • \$\begingroup\$ @Emigna I've never used 05AB1E, so I had no idea! Clever answer :) \$\endgroup\$ May 25, 2017 at 15:35
  • \$\begingroup\$ @Emigna Wait were you Enigma? \$\endgroup\$
    – user63187
    May 25, 2017 at 16:40
7
\$\begingroup\$

Python 2, 135 133 bytes

l,p=input()
i=j=0
while len(l)-i:print(int(all(l[i]%k for k in range(2,l[i])))if p[j]=='p'else l[i]+l[i+1]);i+=1+'p+'.find(p[j]);j+=1

-2 bytes thanks to kundor

\$\endgroup\$
2
  • \$\begingroup\$ i,j=0,0 is redundant, right? Couldn't it be i,j=0 ? \$\endgroup\$
    – Pavel
    May 26, 2017 at 15:58
  • 1
    \$\begingroup\$ @Phoenix: No, that won't work. You can do i=j=0 though. \$\endgroup\$ May 26, 2017 at 21:01
6
\$\begingroup\$

Python 2, 91 bytes

p,i=input()
for c in p:n=i.pop(0);print all(n%k for k in range(2,n))if c>'+'else n+i.pop(0)

Try it online!

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

Haskell, 88 79 bytes

('+':r)!(a:b:c)=a+b:r!c
('p':r)!(a:c)=min(foldr((*).mod a)1[2..a-1])1:r!c
_!e=e

"commands" ! [args] for use.

  • Saved 9 bytes thanks to @Laikoni (#56433)

I'm still learning Haskell; golfing tips appreciated!

\$\endgroup\$
3
  • \$\begingroup\$ This tip to use infix notation for functions can save you some bytes. Also the base case i _[]=[] can be moved to be the last pattern matching rule and then be shortened to i _ e=e, or something like _!e=e after you switched to infix notation. \$\endgroup\$
    – Laikoni
    May 26, 2017 at 6:15
  • \$\begingroup\$ (min$product ... can be min(product .... \$\endgroup\$
    – Laikoni
    May 26, 2017 at 6:17
  • \$\begingroup\$ product$map(mod a) can be shortened to foldr((*).mod a)1. \$\endgroup\$
    – Laikoni
    May 26, 2017 at 6:30
4
\$\begingroup\$

Ruby 2.4, 77+7 = 84 bytes

Uses the -rprime flag.

->g,i{g.chars.map{|c|c==?p?i.shift.prime?? 1:0: c==?+?i.shift(2).sum: p}-[p]}
\$\endgroup\$
4
\$\begingroup\$

Perl 6, 70 bytes

{@^b.rotor($^a.comb.map(1+(*ne'p'))).map({$_-2??.[0].is-prime!!.sum})}

First the rotor method is used to split the input list into chunks of size 1 or 2 depending on whether the next character of the program is p or not. Then that chunked list is mapped over; chunks of size 2 are summed, and chunks of size 1 have their sole element tested for primality.

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

Jelly, 18 bytes

ÆP,+/ị@L
OḂ‘Bṁ@Ç€K

Try it online!

Alternate solution, 18 bytes

⁴Ḣ
¢+¢µ¢ÆPµḂ?
OÇ€K

Try this one online!

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

C#, 130 129 bytes

p=>d=>{var i=0;p.Any(c=>{Console.Write((c==43?d[i++]+d[i]:Enumerable.Range(2,d[i]-2).Any(x=>d[i]%x==0)?0:1)+" ");return++i<0;});}

Try it online!

  • Saved 1 byte by currying the function (thanks to Cyoce)
\$\endgroup\$
2
  • \$\begingroup\$ not sure how C# works, but could you change (p,d)=> to p=>d=> to save a byte and make a curried function? \$\endgroup\$
    – Cyoce
    May 26, 2017 at 15:29
  • \$\begingroup\$ Right, thanks. (It is debatable how much of the required C# boilerplate should be included in the byte count, but yeah, you can write that. (See the linked TIO.)) \$\endgroup\$
    – Mormegil
    May 27, 2017 at 19:24
2
\$\begingroup\$

PowerShell 3+, 151 121 Bytes

$r,$v=$args;$p={0-notin((2..(($n=0+"$args")-1)|%{$n%$_}))};$i=0;$r|%{if($_-eq"p"){&p $v[$i]}else{$v[$i]+$v[($i+=1)]}$i++}

PowerShell has no prime built-ins so I had to roll my own. My first version was terrible and I took from most of the other ones that test for 0 among modulus results which saves a lot. Also sabed a few bytes by using -notin instead of -notcontains but it mean PowerShell v2 is out.

Comment based explanation

# $r is the program code. Assumed char array
# $v is the remaining variables in an assumed integer array.
$r,$v=$args
# Anonymous function to determine if a number is a prime or not.
# Test all potential factors. Check if any 0 modulus remainders are present
$p={0-notin((2..(($n=0+"$args")-1)|%{$n%$_}))}
# $i is an index for tracking location in $v
$i=0
# Cycle each of the instructions
$r|%{if($_-eq"p"){
        # Call the prime checking anonymous function on this number
        &p $v[$i]
    }else{
        # Add the next two numbers. Adjust the index accordingly. 
        $v[$i]+$v[($i+=1)]
        
    }
    # Next number in list. 
    $i++  
}
    # Next number in list. 
    $i++  
}
\$\endgroup\$
1
\$\begingroup\$

F#, 130 bytes

let rec r=function|[],_->()|'+'::t,f::s::u->printf"%i "(f+s);r(t,u)|_::t,n::u->printf"%b "(List.exists((%)n>>(=)0)[2..n-1]);r(t,u)

Try it online!

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

QBasic, 122 bytes

INPUT p$
FOR i=1TO LEN(p$)
INPUT x
IF"+"=MID$(p$,i,1)THEN INPUT y:?x+y:ELSE f=0:FOR j=2TO x:f=f-(x MOD j=0):NEXT:?f=1
NEXT

Takes the code as a line of input, then takes each input number on its own line. The outputs are interspersed with the inputs because they're printed as soon as they're calculated. The truthy value is -1; falsey is 0.

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

Japt, 15 bytes

Takes the programme as a character array, outputs true or false for the prime test.

Ëø²?Vv j:Vv +Vv

Try it (Header splits the programme into an array)

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

Rockstar, 206 197 177 bytes

Outputs 0 for composites and -0.5 for primes

listen to S
cut S
while S
listen to N
if roll S's "+"
listen to I
say N-I/-1
else
let D be N
let P be N-1
while P and D-2
let D be-1
let M be N/D
turn M up
let P be N/D-M

say P

Try it here (Code will need to be pasted in, with the programme as the first line of input and each integer on its own line)

\$\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.