5
\$\begingroup\$

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.

Task

The original cipher looks like this:

Please read primes elephant help you me like cold

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

read primes help me

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

13 Answers 13

3
\$\begingroup\$

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.

\$\endgroup\$
2
\$\begingroup\$

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
\$\endgroup\$
3
  • \$\begingroup\$ Wow. What could you do with a kilobyte of 05AB1E code? \$\endgroup\$
    – S.S. Anne
    Commented Sep 19, 2019 at 15:19
  • 3
    \$\begingroup\$ @JL2210 not that much. 05AB1E is really good at small challenges, but it doesn't scale well: no functions, limited number of variables, etc. \$\endgroup\$
    – Grimmy
    Commented Sep 19, 2019 at 15:25
  • \$\begingroup\$ 3 bytes, just accepting the words \$\endgroup\$
    – Razetime
    Commented Dec 12, 2020 at 10:18
1
\$\begingroup\$

Perl 6, 22 bytes

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

Try it online!

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

\$\endgroup\$
1
\$\begingroup\$

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
l.add(v)}
return l}
fun main(){var w=readLine()!!.split(" ")
for(i in p(w.size))print("${w[i]} ")}

Try it online!

\$\endgroup\$
1
  • 1
    \$\begingroup\$ +1 for using a verbose language. \$\endgroup\$ Commented Sep 21, 2019 at 5:03
1
\$\begingroup\$

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ẒƇị
\$\endgroup\$
1
\$\begingroup\$

PHP, 167 bytes

<?php $i=explode(' ',$argv[1]);$l=count($i);unset($i[0]);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[1]);
$length = count($input);
unset($input[0]);

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);

?>
\$\endgroup\$
1
  • 1
    \$\begingroup\$ 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. \$\endgroup\$
    – Night2
    Commented Sep 22, 2019 at 8:37
1
\$\begingroup\$

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!

\$\endgroup\$
2
  • \$\begingroup\$ 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) \$\endgroup\$
    – Kateba
    Commented Sep 21, 2019 at 20:46
  • \$\begingroup\$ Also, you can delete line 3 if you change line 4 to if j>1 (in both versions) \$\endgroup\$
    – Kateba
    Commented Sep 21, 2019 at 20:50
1
\$\begingroup\$

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!

\$\endgroup\$
1
\$\begingroup\$

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);
}
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to PPCG! Well done! \$\endgroup\$ Commented Oct 8, 2019 at 9:56
0
\$\begingroup\$

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!

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

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.

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

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.

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

Vyxal, 8 bytes

⌈'&›¥æ;Ṅ

Try it Online!

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

Your Answer

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

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