Stringhe Primenarie


27

Una stringa Primenary ( binary-prime ) è una stringa che, quando scritta come una griglia binaria, ogni riga e colonna ha un totale primo.

È una spiegazione piuttosto vaga, quindi analizziamolo con un esempio funzionante ...


Per questo esempio useremo la stringa bunny:

Innanzitutto, trova il punto di codice ASCII di ciascun carattere e la sua rappresentazione binaria:

Char | ASCII | Binary

b      98      1100010
u      117     1110101
n      110     1101110
n      110     1101110
y      121     1111001

Prendi questi valori binari, dall'alto verso il basso, e disponili nella griglia (aggiungendo zeri iniziali se necessario):

1 1 0 0 0 1 0
1 1 1 0 1 0 1
1 1 0 1 1 1 0
1 1 0 1 1 1 0
1 1 1 1 0 0 1

Quindi, conta il numero di 1s in ciascuna riga e colonna:

1 1 0 0 0 1 0   > 3
1 1 1 0 1 0 1   > 5
1 1 0 1 1 1 0   > 5
1 1 0 1 1 1 0   > 5
1 1 1 1 0 0 1   > 5

v v v v v v v

5 5 2 3 3 3 2

Se, e solo se, ogni singolo totale è primo (come qui), allora la stringa è un primo binario valido.


La sfida

Il tuo compito è quello di creare una funzione o un programma che, quando viene data una stringa, restituisce / genera truthyse la stringa è primitiva, e in falsyaltro modo.

Regole / Dettagli

  • Si può presumere che i caratteri della stringa saranno sempre nell'intervallo ASCII 33-126(incluso).
  • La stringa non sarà vuota.
  • Una stringa primenaria non deve avere una lunghezza primi, ad esempio W1n*è valida, nonostante abbia 4 caratteri.
  • Questo è , quindi vince la risposta più breve (in byte), ma tutte le comunicazioni sono benvenute.
  • Le scappatoie standard sono vietate.

Casi test

'husband'     -> True
'HOTJava'     -> True
'COmPaTIBILE' -> True
'AuT0HACk'    -> True

'PPCW'        -> False
'code-golf'   -> False
'C++'         -> False
'/kD'         -> False

'HI'          -> False
'A'           -> False

C'è anche un esempio funzionante, ma incredibilmente dettagliato di Python su repl.it su cui puoi testare la tua soluzione.


Posso chiederti come hai scoperto che husbandera valido? O qualcuno di loro? Grande problema, però!
Gabriel Benamy,

3
@GabrielBenamy Sono contento che qualcuno abbia chiesto! Ho passato in rassegna un file di dizionario online , provando alcune maiuscole casuali di ogni lettera, a volte cambiando lettere per numeri, ecc. Poi ho dato un'occhiata all'elenco di
output e

Ogni input di 1-2 caratteri è garantito per la restituzione False, giusto?
mbomb007,

... perché 0e 1non sono primi, e ogni stringa di input di 1-2 caratteri contenente solo caratteri nell'intervallo dato è garantita per contenere almeno uno 0o 1come somma verticale. È necessario aggiungere alcune stringhe di caratteri 1 e 2 come casi di test.
mbomb007,

@ mbomb007 1 input di caratteri non possono avere numeri primi a colonna, quindi torneranno false. 2 input di caratteri potrebbero, ma non nell'intervallo ASCII che stiamo utilizzando, quindi per questo scenario hai ragione.
FlipTack

Risposte:


8

MATL, 10 byte

BtXsw!shZp

Provalo online!

Questa è la lingua ideale per il lavoro. È praticamente una traslitterazione letterale della specifica della sfida.

Bt % Converts input to binary matrix, duplicate
Xs  % Sum columns (alternative X version to prevent defaulting to sum along first non-singleton dimension, thanks @Jonathan Allan)
w! % Get the duplicate to the top of the stack, transpose
s  % Sum again
h  % Concatenate horizontally
Zp % Check primality element-wise. Display implicitly.

Dal momento che lo zero fa un falsy gamma MATL come da meta , nient'altro è necessario - in pratica, un implicito Aè chiamato ?(se).


adovrebbe essere falso, ma ritorna 1 1? (le sue colonne non si sommano ai numeri primi)
FlipTack

Penso BtXsw!shZpche risolverebbe questo problema e sarei un vincitore per 10.
Jonathan Allan,

@ Flp.Tck Dimenticato completamente il comportamento "tollerante" di MATLAB quando si lavora con i vettori di riga. Mi dispiace, risolto ora.
Sanchises,

Funziona ora :) (potrebbe essere utile aggiornare il collegamento di prova online)
FlipTack

@ Flp.Tkc Fatto. Grazie per una bella sfida!
Sanchises,

4

Gelatina , 13 12 11 byte

OBUZ;$S€ÆPẠ

TryItOnline! o tutti i casi di test

Come?

OBUZ;$S€ÆPẠ - Main link: word                  e.g. ha!
O           - cast to ordinals                 e.g. [104,97,33]
 B          - convert to binary                e.g. [[1,1,0,1,0,0,0],[1,1,0,0,0,0,1],[1,0,0,0,0,1]]
  U         - reverse each entry (say "b")     e.g. [[0,0,0,1,0,1,1],[1,0,0,0,0,1,1],[1,0,0,0,0,1]]
     $      - last two links as a monad
   Z        - transpose                        e.g. [[0,1,1],[0,0,0],[0,0,0],[1,0,0],[0,0,0],[1,1,1],[1,1]]
    ;       - concatenate with "b"             e.g. [[0,1,1],[0,0,0],[0,0,0],[1,0,0],[0,0,0],[1,1,1],[1,1],[0,0,0,1,0,1,1],[1,0,0,0,0,1,1],[1,0,0,0,0,1]]
      S€    - sum €ach                         e.g. [2,0,0,1,0,3,2,3,3,2]
        ÆP  - is prime (1 if prime, 0 if not)  e.g. [1,0,0,0,0,1,1,1,1,1]
          Ạ - all truthy?                      e.g. 0


3

Gelatina , 15 byte

O+⁹Bṫ€3µS€;SÆPP

Provalo online! oppure Verifica tutti i casi di test. .

Spiegazione

O+⁹Bṫ€3µS€;SÆPP  Main link. Input: string z
O                Ordinal, get ASCII value of each char
  ⁹              Nilad representing 256
 +               Add 256 to each ordinal value
   B             Binary digits of each
    ṫ€3          Tail, take each list of digits from the 3rd value to the end
                 These are the last seven digits of each
       µ         Start a new monadic chain
        S€       Sum each list of digits by rows
           S     Sum by column
          ;      Concatenate
            ÆP   Test if each is prime, 1 if true else 0
              P  Product

3

Mathematica, 75 byte

And@@Join@@PrimeQ@{+##&@@#,+##&@@@#}&@IntegerDigits[ToCharacterCode@#,2,7]&

Funzione senza nome che accetta una stringa come input e che restituisce Trueo False.

ToCharacterCode@#converte l'input nell'elenco dei suoi valori ASCII; IntegerDigits[...,2,7]trasforma ogni valore nella lista dei suoi bit, riempito alla lunghezza 7 se necessario. Quindi ora abbiamo un array 2D e vogliamo tutte le sue somme di riga e somme di colonna; ecco, lo spasmo dei personaggi {+##&@@#,+##&@@@#}&@...fa esattamente questo (applica la funzione +##&"somma tutti gli argomenti" all'elenco dei vettori nella prima coordinata utilizzando @@e a ciascun vettore come proprio elenco di numeri interi nella seconda coordinata utilizzando @@@) . Quindi controlliamo solo se i risultati sono PrimeQ, appiattiamo l'elenco con Join@@e prendiamo ilAnd di tutti quei valori.


2

Rubino -rprime , 100 byte

->s{a=s.bytes.map{|b|b.digits 2}
a.all?{|r|r.sum.prime?}&([0]*7).zip(*a).all?{|c|c.count(1).prime?}}

Provalo online!

Spiegazione

->s{
    a=s.bytes                       # Get byte values from string
             .map{|b|b.digits 2}    # For each, map it to its binary digits
                                    #   (least significant digits first)
a.all?{|r|r.sum.prime?}             # Each character has a prime number of 1's?
    &                               # Bit-and (because it saves bytes here)
    ([0]*7).zip(*a)                 # Zip bit array with an all-zero array
                                    #   (If we don't, then uneven array lengths
                                    #   cause some columns to not be returned.)
    .all?{|c|c.count(1).prime?}     # All columns have a prime number of 1's?
                                    #   (We use count instead of sum here because
                                    #   zip pads columns with trailing nils, which
                                    #   can't be added to numbers via sum.)
}

1

Perl, 151 121 111 + 3 = 114 byte

Corri con -lF. Il programma funzionerà correttamente solo per il primo input. Terminare il programma ed eseguire nuovamente per il prossimo input.

Grazie a @Dada per avermi fatto sapere che il //dopo Fera ridondante. Un byte aggiuntivo può essere rimosso (per 112) reindirizzando l'ingresso tramite via echo -n, ma ritengo che tecnicamente si stia aggiungendo più codice, quindi YMMV.

for$c(@a=map{sprintf"%07b",ord}@F){$b[$_].=substr$c,$_,1 for 0..6}s/0//g,$d|=/^1?$|^(11+?)\1+$/ for@a,@b;say!$d

Leggibile:

                                     #Implicitly split input into characters in @F array
for$c(@a=map{sprintf"%07b",ord}@F)  #Convert @F to 7-bit binary as @a, then loop through it                        
    $b[$_].=substr$c,$_,1 for 0..6   #Transpose @a's bits into @b
}
s/0//g,$d|=/^1?$|^(11+?)\1+$/ for@a,@b; #Remove any zeros, then run through composite regex
say!$d                          #If all composite regex checks fail, then it's fully prime.

1
Una versione che funziona solo sul primo input va benissimo, quindi puoi mettere la versione a 141 byte come principale e suggerire che l'altra venga utilizzata su più input.
Dada,

Nota anche che puoi omettere il //dopo -F, e puoi prendere l'input senza la nuova riga finale (con echo -n) per sbarazzarti della -lbandiera.
Dada,

1

Python 3, 228 227 225 byte

Non è una grande risposta, non sono stato in grado di giocarci tanto quanto avrei voluto, ma ci ho passato tanto tempo e sento di doverlo pubblicare. I suggerimenti sul taglio dei byte sarebbero molto apprezzati.

r=range
n=[format(ord(c),"08b")for c in input()]
n=map(lambda s:s.count("1"),n+["".join([f[1]for f in filter(lambda e:e[0]%8<1,enumerate("X"*-~i+"".join(n)))][1:])for i in r(8)])
print(all(all(s%d for d in r(2,s))for s in n))

Modifica 1: sostituito e[0]%8==0con e[0]%8<1, perdendo un byte. Grazie Flp.Tkc!

Modifica 2: sostituendo (i + 1) con - ~ i, perdendo due byte aggiuntivi. Grazie Erik per aver rivelato quanto sia scarsa la mia conoscenza a livello di bit :) Durante il test di questa revisione, ho scoperto che kappaè valido ... fai di quello che vuoi.


1
potresti cambiare e[0]%8==0in e[0]%8<1?
FlipTack

@ Flp.Tkc Ottimo posto! Non c'è motivo per cui ciò non possa essere fatto.
FourOhFour

1
@ Flp.Tkc Non credo di poter salvare byte rendendolo una funzione. Mi piace come hai 404 rappresentanti a proposito :)
FourOhFour

Dovrebbe essere <1, no <0?
Limone distruttibile

@Distructible Watermelon yep fammi correggere.
FourOhFour

1

Groovy, 151 137 byte

{p={x->x<3||(2..(x**0.5)).every{x%it}};y={it.every{p(it.count("1"))}};x=it.collect{0.toString((int)it,2) as List};y(x)&&y(x.transpose())}

Nessun controllo di primalità in Groovy ...

p={x->x<3||(2..(x**0.5)).every{x%it}}; - Chiusura per test di primalità.

y={it.every{p(it.count("1"))}}; - Chiusura per garantire che tutti i conteggi di "1" per un array 2D binario passato siano primi.

x=it.collect{0.toString((int)it,2) as List}; - Copertura da stringa a matrice binaria.

y(x)&&y(x.transpose()) - Per tutte le somme validate per prime nella matrice principale e nella matrice trasposta, assicurarsi che ritornino vere.


1

Pyth , 37 byte

L.AmP_sdb=sMM.[L\0lh.MlZQ=.BMQ&yZy.TZ

Provalo online!


                                 Code | Explanation
--------------------------------------+----------------------------------------------------------------
L.AmP_sdb=sMM.[L\0lh.MlZQ=.BMQ&yZy.TZ | Full code
L                                     | Define function y(b):
   m    b                             |   For each d in b:
    P_sd                              |     Is the sum of the elements of the list prime?
 .A                                   |   Return whether all elements of the resulting list are truthy
                         =   Q        | Assign the following to Q:
                          .BMQ        |   The list of binary strings for each character in the input
         =             Z              | Assign the following to Z:
               L             Q        |   For every element in Q:
             .[ \0                    |     Pad with 0 on the left
                  lh.MlZQ             |     To the length of the longest element in Q
            M                         |   For each element in the resulting list:
          sM                          |     Convert each character to an integer
                              &yZ     | Print y(Z) AND
                                 y.TZ |   y( <Transpose of Z> )

1

Brachylog , 14 byte

ạḃᵐB↔ᵐz₁,B+ᵐṗᵐ

Provalo online!

Output in caso di successo o fallimento. (In caso di successo, un elenco di tutte le somme di colonne e righe è disponibile tramite la variabile di output.

   B              The variable B is
ạ                 the codepoints of the input
 ḃᵐ               converted to lists of binary digits,
    ↔ᵐ            which with each list reversed
      z₁          then zipped without cycling
        ,B        and concatenated with B
          +ᵐ      has elements which all sum to
            ṗᵐ    prime numbers.

1

O5AB1E, 12 byte

Çžy+bø€SOp¦W

Provalo online!

Questo è il mio primo codice golf quindi andate piano :)

Ç              % Converts the implicit input into ascii values
 žy+           % Adds 128 to each value, inspired by Emigna as a way to pad zeros
    b          % Convert all values into bits
     ø         % Transpose
      €SO      % Sum each string of binary digits created
         p¦    % Check if each element is prime and cut the first element out (adding 128 makes it equal to the number of characters)
           W   % Take the minimum value to effectively "and" all the elements

Ciò produce un risultato vuoto per l'inserimento di una sola lettera. Non sono esperto di O5AB1E ma se questo è un valore falso, va bene.
Sanchises,

1

Python 3 , 209 189 180 171 160 byte

Grazie calamari per -9 byte :)

def p(s):n=s.count('1');return(n>1)*all(n%i for i in range(2,n))
def f(s):t=[f'{ord(c):07b}'for c in s];return all(map(p,t+[[u[j]for u in t]for j in range(7)]))

Provalo online!


Mi piace come hai riscritto la dichiarazione di stampa del test case :)
movatica, il

Sì, sono un ossessivo compulsivo di fumo sulle stringhe f ... Inoltre, non è equivalente se rimuovi t+nella dichiarazione della mappa?
Ripristina Monica il

No, perché il controllo primo deve coprire sia le righe che le colonne nella matrice di bit. tha tutte le righe, mentre [[t[i][j]..i..]..j..]è trasposta t, ovvero le colonne. Se esiste un modo più breve per trasporre la matrice, possiamo salvare più byte :)
movatica,

Funziona quando lo provo , conosci una stringa che la rompe?
Ripristina Monica il

Sì. beezzdovrebbe restituire false, ma non lo è. È perché il controllo primo è rotto, restituisce Trueper 4 bit. Prova print(p('1111')). Risolto il problema ora. Tutti i casi di test non hanno riguardato questo, perché tutti i personaggi usati sono primitivi.
movatica,

1

K (oK) , 40 33 byte

Soluzione:

&/{2=+/d=_d:x%!x}'+/'m,+m:(7#2)\'

Provalo online!

Spiegazione:

La metà sta creando la matrice, l'altra metà è il controllo di primalità.

&/{2=+/d=_d:x%!x}'+/'m,+m:(7#2)\' / the solution
                                ' / apply to each (')
                               \  / decode
                          (   )   / do this together
                           7#2    / 7#2 => 2 2 2 2 2 2 2
                        m:        / save as m
                       +          / transpose
                     m,           / append to m
                  +/'             / sum (+/) each (')
                 '                / apply to each
  {             }                 / lambda taking implicit x
              !x                  / range 0..x
            x%                    / x divided by ...
          d:                      / save as d
         _                        / floor
       d=                         / equal to d?
     +/                           / sum (+/)
   2=                             / equal to 2?
&/                                / minimum

0

PHP, 173 byte

for($r=1;$b=substr_count($t[$i]=sprintf('%07b',ord($argv[1][$i++])),1);)$r&=$b==2|$b%2&$b>2;for(;$k++<7;){for($b=$j=0;$t[++$j];$b+=$t[$j][$k-1]);$r&=$b==2|$b%2&$b>2;}echo$r;

Provalo online


0

JavaScript, 234 byte

f=z=>(z=[...z].map(v=>v.charCodeAt(0))).map(v=>v.toString(2).replace(/0/g,"").length).every((p=v=>{for(i=2;i<v;i++){if(v%i===0){return 0}};return v>1}))&&[...""+1e6].map((v,i)=>z.reduce((a,e)=>!!(e&Math.pow(2,i))+a,0)).every(v=>p(v))

Otteniamo i valori orizzontali convertendo il numero in binario, rimuovendo gli zeri usando una sostituzione di stringa e quindi contando gli 1. Le somme verticali sono ottenute eseguendo il loop da 1 a 7 e usando un AND bit a bit con 2 elevato all'ennesima potenza.


Math.pow(2,i)può essere ridotto ad (1<<i)assumere i<32, forse salvando 7 byte, forse non però.
Naruyoko,

0

Clojure, 180 byte

#(let[S(for[i %](for[j[1 2 4 8 16 32 64]](min(bit-and(int i)j)1)))A apply](not-any?(fn[i](or(= i 1)(seq(for[d(range 2 i):when(=(mod i d)0)]d))))(into(for[s S](A + s))(A map + S))))

Potrebbe esserci un modo più breve di generare elenchi di bit e anche il test di primalità.


0

Perl 5 -MList::Util=all,sum -pF , 96 92 byte

$_=all{//;all{$'%$_}2..$_-1}(map{$_=sprintf'%07b',ord;y/1//}@F),map{sum map{s/.//;$&}@F}0..6

Provalo online!


0

Python 3, 164 byte

import numpy;a=numpy.array([list(f'{ord(_):07b}')for _ in input()]).astype(int);print(all([(v>1)*all(v%i for i in range(2,v))for v in set(a.sum(0))|set(a.sum(1))]))

0

Ruby 2.7 -rprime, 95 byte

->s{a=s.bytes.map{[*@1.digits(2),0][..6]}
(a.map(&:sum)+a.transpose.map(&:sum)).all?(&:prime?)}

Nessun collegamento TiO perché TiO esegue ancora Ruby 2.5.5. 😭

Spiegazione

Abbastanza semplice. La prima riga ottiene le cifre binarie di ciascun personaggio come un array completato da sette cifre, il che dovrebbe essere davvero più semplice:

a = s.bytes.map { [*@1.digits(2), 0][..6] }

@1Dai un'occhiata a quel parametro numerico a blocchi ( ) e all'intervallo di inizio ( ..6) hotness .

La seconda riga somma le righe e le colonne e verifica se sono tutti primi:

(a.map(&:sum) + a.transpose.map(&:sum)).all?(&:prime?)

0

JavaScript (Node.js) , 149 146 ... 134 130 129 byte

x=>[...x].map(y=>a=[...a.map(n=>y.charCodeAt()&2**i++?++z&&-~n:n,z=i=0),z],a=[...Array(7)])&&!a.some(n=>(P=r=>n%--r?P(r):~-r)(n))

Provalo online!

Spiegazione

x=>                        // Main function:
 [...x].map(               //  For each y in x:
  y=>
   a=[...a.map(            //   For each i in range(0, len(a)):
    n=>                   
     y.charCodeAt()&2**i++ //    If y AND 2**i is not zero:
     ?++z&&-~n:n,          //     z = z + 1; a[i] = a[i] + 1 (1 if a[i] is undefined)
    z=i=0                  //   Initially z = 0
   ),z],                   //   Then push z at the end of a
  a=[...Array(7)]          //  Initially a = [undefined] * 7
 )&&!a.some(               //  Then for each n in a:
  n=>(
   P=r=>                   //   Composite function:
    n%--r?                 //    If n % (r - 1) == 0 or r == 1:
     P(r)                  //     Return P(r - 1)
    :~-r                   //    Else: Return r - 2
  )(n)                     //   Starting from r = n
 )                         //  Return whether the composite function returns 0 for all n.

Come funziona !?

  • y.charCodeAt()&2**i
    • Abbiamo bisogno di questo codice per restituire il bit corrispondente di y.charCodeAt() if0 <= i < 7 e 0 altrimenti.
    • quando i < 7 , il codice apparentemente funziona come al solito.
    • quando 7 <= i <= 32 , poiché il bit corrispondente diy.charCodeAt() è comunque 0, il risultato è 0 come previsto.
    • quando 32 < i < 1024 , da alloraint32(2**i) == 0 , il risultato è 0 come previsto.
    • Quando 1024 <= i, abbiamo 2**i == Infinity, e da allora int32(Infinity) == 0, il risultato è 0 come previsto.
  • (P=r=>n%--r?P(r):~-r)(n)
    • Per semplicità lo lasciamo R = --r = r - 1 .
    • Questa funzione di supporto termina quando n % R == 0on % R is NaN .
      • n % R == 0: Rè un fattore din .
        • Se R == 1, allora nè primo perché non tutti 1 < R < npossono dividersin . Restituisce 0 (falsa).
        • Se R == -1alloran == 0 . Ritorna -2 (verità).
        • Altrimenti, torna R - 1dove R - 1 > 0(verità).
      • n % R is NaN: Calcolo modulare non valido.
        • Se R == 0: n == 1. Ritorna -1 (verità).
        • Se n is NaN: R is NaN. Ritorna -1 (verità).
    • Di conseguenza, solo quando R == 1questa funzione può restituire un valore errato, indica che nè primo.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.