Do you know the book Murderous Maths, in the Horrible Science series? In the book, the Laplace Princess' "ridiculous" cipher might be interesting enough and simple enough to be a code-golf challenge.

The original cipher looks like this:

The nth word is only meaningful if it is a prime. So, the cipher becomes:

Your task is to write a program that inputs the cipher and outputs the plaintext.

# Rules

• You can take the input in any acceptable forms, e. g. an list of words.

• The input will only consist of printable-ASCII characters.

• You can use 0-based index or 1-based index.

• A "Word" includes any punctuation. For example:

This is, "a" great test! I think.


should output

is, "a" test! think.


# Japt-f, 6 2 bytes

I/O as arrays of words with 0-based indexing

Vj


Try it

Vj     :Implicit filter of input array
V      :0-based index of current word
j     :Is prime?


## Japt -S, 4 bytes

I/O as space-delimited strings, with 0-based indexing

¸fÏj


Try it

¸fÏj     :Implicit input of string
¸        :Split on spaces
f       :Filter by
Ï      :  0-based index
j     :  Is prime?
:Implicit output, joined by spaces


## Japt -S, 6 bytes

I/O as space-delimited strings, with 1-based indexing

¸fÏÄ j


Try it

Same as above using Ä to add 1 to the index.

# 05AB1E, 6 bytes

#āpÏðý


Try it online!

#         # split the input on spaces
ā        # push [1..length of the list of words]
p       # is prime?
Ï      # keep only words where the above check is true
ðý    # join with spaces

• Wow. What could you do with a kilobyte of 05AB1E code? Sep 19, 2019 at 15:19
• @JL2210 not that much. 05AB1E is really good at small challenges, but it doesn't scale well: no functions, limited number of variables, etc. Sep 19, 2019 at 15:25
• 3 bytes, just accepting the words Dec 12, 2020 at 10:18

# Perl 6, 22 bytes

*[grep &is-prime,2..*]


Try it online!

Takes input as a list of words and outputs the zero indexed list.

# Kotlin, 201 bytes

Input is zero indexed.

fun p(s:Int):MutableList<Int>{val l=MutableList(0){0}
o@
for(v in 2..s){for(e in l)if(v%e<1)continue@o
return l}
for(i in p(w.size))print("${w[i]} ")}  Try it online! • +1 for using a verbose language. Sep 21, 2019 at 5:03 # Jelly, 4 bytes LÆRị  A monadic Link accepting a list of words which yields a list of words. Try it online! (the footer calls the Link then formats, since a full-program implicitly smashes output) ### How? LÆRị - Link: list, W L - length (W) ÆR - inclusive prime range = [2,3,5,7,...,Prime <= length(W)] ị - index into (W)  Also 4: JẒƇị  # PHP, 167 bytes <?php$i=explode(' ',$argv);$l=count($i);unset($i);for($x=1;$x<$l;$x++){$y=$x+1;$z=2;while($z<$y){$t=$y/$z;if($t==(int)$t)unset($i[$x]);$z++;}}echo join(' ',$i);


Try it online!

### Ungolfed:

<?php

$input = explode(' ',$argv);
$length = count($input);
unset($input); for($x = 1; $x <$length; $x++) {$y = $x + 1;$z = 2;

while($z <$y) {
$test =$y / $z; if($test == (int) $test) { unset($input[$x]); }$z++;
}
}

echo join(' ', $input); ?>  • Using your own idea, I golfed it more to 127 bytes: Try it online!, I suspect that using other solutions that won't need unset it should be more golf-able. Sep 22, 2019 at 8:37 # Python 3, 125 107 bytes 107 bytes thanks to Black Owl Kai i=input().split();j=k=1 for c in i: if j>1: while k>2: k-=1 if j%k<1:k=0 if k:print(c) j+=1;k=j  Try it online! 120 bytes if it strictly follows rules. -25 bytes thanks to Black Owl Kai # Python 3, 145 120 bytes i=input().split();j=k=1;l=[] for c in i: if j>1: while k>2: k-=1 if j%k<1:k=0 if k:l+=[c] j+=1;k=j print(*l)  Try it online! • If a trailing space is acceptable, you can shorten your longer solution to the shorter one with print(c,end=' '). If this is not the case, you can at least shorten the last line to print(*l) Sep 21, 2019 at 20:46 • Also, you can delete line 3 if you change line 4 to if j>1 (in both versions) Sep 21, 2019 at 20:50 # Python 3, 90 bytes print(*[w for n,w in enumerate(input().split()[1:])if all((n+2)%i for i in range(2,n+2))])  Try it online! # Rust, 339 bytes First ever submission to Code Golf, but it works! use std::io;use std::io::BufRead;fn main(){println!("{}",io::BufReader::new(io::stdin().lock()).lines().flat_map(|s|s.unwrap().split_whitespace().map(|s|s.to_owned()).collect::<Vec<String>>()).enumerate().filter(|(x,_)|{if *x<2{return false}for i in 2..*x{if x%i==0{return false}};true}).map(|(_,y)|y).collect::<Vec<String>>().join(" "));}  This code is compressed down from this: use std::io; use std::io::BufRead; use std::io::BufReader; fn main() { let s = BufReader::new(io::stdin().lock()) .lines() .flat_map(|s| { s.unwrap() .split_whitespace() .map(|s| s.to_owned()) .collect::<Vec<String>>() }) .enumerate() .filter(|(x,_)| { if *x<2 { return false } for i in 2..*x { if x % i == 0 { return false } }; true }) .map(|(_,y)| y) .collect::<Vec<String>>() .join(" "); println!("{}", &s); }  • Welcome to PPCG! Well done! Oct 8, 2019 at 9:56 # Ruby-p -rprime, 36 bytes Replaces every word (and the space after it, if present) with the empty string if it is a non-prime word. i=0 gsub(/\S+ ?/){$&if(i+=1).prime?}


Try it online!

# C (gcc), 95 bytes

#define f(w,n)for(int i=0,j,p[n]={};++i<n;p[i]||printf("%s ",w[i]))for(j=i*i;j<n;j+=i)p[j]=i>1;


Try it online!

Sieve of E.

# R + gmp, 48 bytes

(W=scan(,'',,,,''))[gmp::isprime(1:length(W))>0]


Try it online!

This use gmp for the isprime builtin. This returns 0, 1 or 2, hence the test for > 0. scan takes the input as characters split on whitespace and quotes set to empty string.

# Vyxal, 8 bytes

⌈'&›¥æ;Ṅ


Try it Online!

⌈        # Split on spaces
'    ;  # Filter by
&›     # Increment register
¥æ   # Register prime?
Ṅ # Join on spaces