Primenary Strings


27

Uma string Primenary ( binary-prime ) é aquela que, quando escrita como uma grade binária, cada linha e coluna tem um total primo.

Essa é uma explicação bastante vaga, então vamos descrevê-la com um exemplo bem trabalhado ...


Neste exemplo, usaremos a string bunny:

Primeiro, encontre o ponto de código ASCII de cada caractere e sua representação binária:

Char | ASCII | Binary

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

Pegue esses valores binários, de cima para baixo, e organize-os na grade (adicionando zeros à esquerda, se necessário):

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

Em seguida, conte o número de 1s em cada linha e coluna:

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 somente se, todo total for primo (como aqui), a sequência será um primo binário válido.


O desafio

Sua tarefa é criar uma função ou programa que, quando recebe uma string, retorna / sai truthyse a string for primenária ou falsynão.

Regras / Detalhes

  • Você pode assumir que os caracteres da string sempre estarão no intervalo ASCII 33-126(inclusive).
  • A cadeia não estará vazia.
  • Uma sequência primária não precisa ter um comprimento primo - por exemplo, W1n*é válida, apesar de ter 4 caracteres.
  • Isso é , então a resposta mais curta (em bytes) vence - mas todos os envios são bem-vindos.
  • As brechas padrão são proibidas.

Casos de teste

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

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

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

Há também um exemplo de Python funcional, mas incrivelmente detalhado, no repl.it, no qual você pode testar sua solução.


Posso perguntar como você descobriu que isso husbandera válido? Ou algum deles? Grande problema, no entanto!
Gabriel Benamy 6/11/2016

3
@GabrielBenamy Estou feliz que alguém perguntou! I loop através de um dicionário on-line de arquivos, tentar algumas capitalizações aleatórios de cada letra, às vezes alternando letras para números, etc. Então, eu tinha um olhar através da lista emitido e pegou um par de casos de teste que eu gostava
FlipTack

É garantido que cada entrada de 1-2 caracteres retorne False, correto?
mbomb007

... porque 0e 1não são primos, e cada string de entrada de 1-2 caracteres contendo apenas caracteres no intervalo especificado tem a garantia de conter pelo menos um 0ou 1como uma soma vertical. Você deve adicionar algumas cadeias de caracteres de 1 e 2 como casos de teste.
mbomb007

@ mbomb007 1 entradas de caracteres não podem ter números primos em colunas, portanto, elas retornarão false. 2 entradas de char poderiam, mas não no intervalo ASCII que estamos usando, portanto, para este cenário, você está correto.
FlipTack

Respostas:


8

MATL, 10 bytes

BtXsw!shZp

Experimente online!

Esta é a linguagem ideal para o trabalho. É praticamente uma transliteração literal da especificação do desafio.

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.

Como qualquer zero faz com que uma matriz MATL seja falsa conforme a meta , nada mais é necessário - basicamente, um implícito Aé chamado ?(if).


adeve ser falso, mas retorna 1 1? (suas colunas não somam primos)
FlipTack

Eu acho que BtXsw!shZpiria corrigir isso e ser um vencedor para 10.
Jonathan Allan

@ Flp.Tck Esqueci completamente o comportamento de "perdão" do MATLAB ao trabalhar com vetores de linha. Sinto muito, consertei agora.
Sanchises

Funciona agora :) (pode querer atualizar a experimentá-lo online link tho)
FlipTack

@ Flp.Tkc Concluído. Obrigado por um bom desafio!
Sanchises

4

Geléia , 13 12 11 bytes

OBUZ;$S€ÆPẠ

TryItOnline! ou todos os casos de teste

Quão?

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 bytes

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

Experimente online! ou Verifique todos os casos de teste. .

Explicação

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 bytes

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

Função sem nome pegando uma string como entrada e retornando Trueou False.

ToCharacterCode@#converte a entrada na lista de seus valores ASCII; IntegerDigits[...,2,7]transforma cada valor na lista de seus bits, preenchida com o comprimento 7, se necessário. Então agora temos uma matriz 2D e queremos todas as suas somas de linha e coluna; eis que o espasmo de caractere {+##&@@#,+##&@@@#}&@...faz exatamente isso (aplica a função +##&"somar todos os argumentos", à lista de vetores na primeira coordenada usando @@e a cada vetor como sua própria lista de números inteiros na segunda coordenada usando @@@) . Depois, apenas verificamos se os resultados são PrimeQ, achatamos a lista Join@@e obtemos Andtodos esses valores.


2

Ruby -rprime , 100 bytes

->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?}}

Experimente online!

Explicação

->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 bytes

Corra com -lF. O programa funcionará apenas corretamente para a primeira entrada. Encerre o programa e execute novamente para sua próxima entrada.

Agradeço a @Dada por me informar que o //depois Fera redundante. Um byte adicional pode ser removido (para 112), canalizando a entrada via echo -n, mas eu sinto que isso é tecnicamente adicionando mais código, então 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

Legível:

                                     #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
Uma versão que funciona apenas na primeira entrada é perfeitamente adequada; portanto, você pode colocar a versão de 141 bytes como a principal e sugerir a outra para usar em várias entradas.
Dada

Observe também que você pode omitir o //depois -Fe pode echo -nusar a entrada sem a nova linha final (com ) para se livrar da -lsinalização.
Dada

1

Python 3, 228 227 225 bytes

Não é uma ótima resposta, não fui capaz de jogar tanto quanto gostaria, mas passei tanto tempo nisso que acho que devo postar. Sugestões sobre o corte de bytes seriam muito apreciadas.

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

Editar 1: substituído e[0]%8==0por e[0]%8<1, perdendo um byte. Obrigado Flp.Tkc!

Edição 2: substituindo (i + 1) por - ~ i, perdendo dois bytes adicionais. Obrigado Erik por expor o quão ruim é meu conhecimento em nível de bit :) Ao testar esta revisão, descobri que kappaé válido ... faça disso o que quiser.


1
você poderia mudar e[0]%8==0para e[0]%8<1?
FlipTack 06/11

@ Flp.Tkc Bom local! Não há razão para que isso não possa ser feito.
FourOhFour

1
@ Flp.Tkc Acho que não poderia salvar bytes, tornando-o uma função. Eu gosto de como você tem 404 rep btw :)
FourOhFour

Deveria ser <1, não é <0?
Destructible Lemon

@ Melancia destrutível sim, deixe-me corrigir isso.
FourOhFour

1

Groovy, 151 137 bytes

{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())}

Nenhuma verificação de primalidade no groovy ...

p={x->x<3||(2..(x**0.5)).every{x%it}}; - Fechamento para teste de primalidade.

y={it.every{p(it.count("1"))}}; - Fechamento para garantir que todas as contagens de "1" para uma matriz 2D binária passada sejam primárias.

x=it.collect{0.toString((int)it,2) as List}; - Coversion de string para array binário.

y(x)&&y(x.transpose()) - Para todas as somas validadas pelo prime na matriz principal e na matriz transposta, verifique se elas retornam verdadeiras.


1

Pitão , 37 bytes

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

Experimente 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

Braquilog , 14 bytes

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

Experimente online!

Saídas por sucesso ou fracasso. (No caso de êxito, uma lista de todas as somas de colunas e linhas está disponível através da variável de saída.

   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 bytes

Çžy+bø€SOp¦W

Experimente online!

Este é o meu primeiro código de golfe, então vá com calma :)

Ç              % 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

Isso produz um resultado vazio para uma única entrada de letra. Eu não sou muito versado em O5AB1E, mas se esse é um valor falsey, tudo bem.
Sanchises

1

Python 3 , 209 189 180 171 160 bytes

Lula Thanx por -9 bytes :)

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

Experimente online!


Eu gosto de como você reescreveu a declaração de impressão do caso de teste :)
movatica

Sim, eu sou um obsessivo compulsivo em relação às strings-f ... Além disso, não é equivalente se você remover t+na declaração do mapa?
Restabelecer Monica

Não, porque a verificação principal precisa cobrir linhas e colunas na matriz de bits. ttem todas as linhas, enquanto [[t[i][j]..i..]..j..]é a transposta t, ou seja, as colunas. Se houver uma maneira mais curta de transpor a matriz, podemos salvar mais bytes :)
movatica

Está funcionando quando eu tento , você conhece uma string que a quebra?
Reintegrar Monica

Sim. beezzdeve retornar false, mas não. É porque o cheque principal está quebrado, ele retorna Truepara 4 bits. Tente print(p('1111')). Corrigido agora. Todos os casos de teste não cobriram isso, porque todos os caracteres usados ​​são primários.
movatica

1

K (oK) , 40 33 bytes

Solução:

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

Experimente online!

Explicação:

Metade está criando a matriz, a outra metade é a verificação de primalidade.

&/{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 bytes

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;

Teste on-line


0

JavaScript, 234 bytes

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

Obtemos os valores horizontais convertendo o número em binário, removendo os zeros usando uma substituição de cadeia e depois contando os 1s. As somas verticais são obtidas pelo loop de 1 a 7 e usando um AND bit a bit com 2 elevados à enésima potência.


Math.pow(2,i)pode ser reduzido para (1<<i)supor i<32, talvez economizando 7 bytes, talvez não.
Naruyoko 26/06

0

Clojure, 180 bytes

#(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))))

Pode haver uma maneira mais curta de gerar listas de bits e também o teste de primalidade.



0

Python 3, 164 bytes

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 bytes

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

Nenhum link de TiO porque o TiO ainda executa o Ruby 2.5.5. 😭

Explicação

Bem simples. A primeira linha obtém os dígitos binários de cada caractere como uma matriz preenchida com sete dígitos, o que realmente deve ser mais fácil:

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

Confira esse parâmetro bloco numerado ( @1) e gama beginless ( ..6) gostosura .

A segunda linha soma as linhas e colunas e testa se todas são primos:

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

0

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

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

Experimente online!

Explicação

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.

Como isso funciona !?

  • y.charCodeAt()&2**i
    • Precisamos desse código para retornar o bit correspondente de y.charCodeAt()if0 <= i < 7 e 0 caso contrário.
    • Quando i < 7 , aparentemente, o código funciona normalmente.
    • Quando 7 <= i <= 32, desde que o bit correspondente y.charCodeAt()seja 0, o resultado será 0 conforme o esperado.
    • Quando 32 < i < 1024, desde então int32(2**i) == 0, o resultado é 0 como esperado.
    • Quando 1024 <= i, temos 2**i == Infinitye, desde então int32(Infinity) == 0, o resultado é 0 como esperado.
  • (P=r=>n%--r?P(r):~-r)(n)
    • Por simplicidade, deixamos R = --r = r - 1.
    • Esta função auxiliar termina quando n % R == 0oun % R is NaN .
      • n % R == 0: Ré um fator de n.
        • Se R == 1, então né primo, porque 1 < R < nnem todos podem dividir n. Retorno 0 (falso).
        • Se R == -1então n == 0. Retorno -2 (verdade).
        • Caso contrário, retorne para R - 1onde R - 1 > 0(verdade).
      • n % R is NaN: Cálculo modular inválido.
        • Se R == 0:n == 1. Retorno -1 (verdade).
        • Se n is NaN: R is NaN. Retorno -1 (verdade).
    • Como resultado, somente quando R == 1essa função pode retornar um valor falso, indicando que né primo.
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.