Первичные Струны


27

Первичная ( двоичная-простая ) строка - это строка, которая при записи в виде двоичной сетки каждая строка и столбец имеет простое общее число.

Это довольно расплывчатое объяснение, поэтому давайте разберем его с проработанным примером ...


Для этого примера мы будем использовать строку bunny:

Сначала найдите кодовую точку ASCII каждого символа и его двоичное представление:

Char | ASCII | Binary

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

Возьмите эти двоичные значения сверху вниз и расположите их в сетке (при необходимости добавляя начальные нули):

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

Затем посчитайте количество 1s в каждой строке и столбце:

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

Если и только если каждое отдельное общее число является простым (например, здесь), тогда строка является допустимым двоичным простым числом.


Соревнование

Ваша задача - создать функцию или программу, которая при задании строки возвращает / выводит, truthyесли строка является основной, и в falsyпротивном случае.

Правила / Подробнее

  • Вы можете предположить, что символы строки всегда будут в диапазоне ASCII 33-126(включительно).
  • Строка не будет пустой.
  • Primenary строка не не должна иметь основную длину - например, W1n*действует, несмотря на наличие 4 -х символов.
  • Это , поэтому выигрывает самый короткий ответ (в байтах) - но все предложения приветствуются.
  • Стандартные лазейки запрещены.

Тестовые случаи

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

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

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

Существует также рабочий, но невероятно подробный пример Python на repl.it, с которым вы можете протестировать свое решение.


Могу я спросить, как вы обнаружили, что husbandэто действительно? Или любой из них? Большая проблема, хотя!
Габриэль Бенами

3
@GabrielBenamy Я рад, что кто-то спросил! Я просматривал файл онлайн-словаря , пробуя несколько случайных заглавных букв каждой буквы, иногда меняя буквы на цифры и т. Д. Затем я просмотрел список
вывода

Каждый ввод 1-2 символов гарантированно вернет False, правильно?
mbomb007

... потому что 0и 1не являются простыми, и каждая входная строка из 1-2 символов, содержащая только символы в данном диапазоне, гарантированно содержит по крайней мере один 0или 1в виде вертикальной суммы. Вы должны добавить несколько строк из 1 и 2 символов в качестве тестовых случаев.
mbomb007

@ mbomb007 1 символьные входы не могут иметь простые числа по столбцам, поэтому они будут возвращаться false. Могут быть введены 2 символьных входа, но не в диапазоне ASCII, который мы используем, поэтому для этого сценария вы правы.
FlipTack

Ответы:


8

MATL, 10 байт

BtXsw!shZp

Попробуйте онлайн!

Это идеальный язык для работы. Это в значительной степени буквальная транслитерация спецификации вызова.

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.

Так как любой ноль приводит к ошибочности массива MATL в соответствии с мета , больше ничего не требуется - в основном, Aвызывается неявное ?(если).


aдолжен быть ложным, но возвращается 1 1? (его столбцы не складываются в простые числа)
FlipTack

Я думаю, BtXsw!shZpчто это исправить и стать победителем на 10.
Джонатан Аллан

@ Flp.Tck Полностью забыл о «прощающем» поведении MATLAB при работе с векторами строк. Извините, исправил это сейчас.
Sanchises

Работает сейчас :) (возможно, вы захотите обновить его, попробуйте ссылку онлайн)
FlipTack

@ Flp.Tkc Готово. Спасибо за хороший вызов!
Sanchises

4

Желе , 13 12 11 байт

OBUZ;$S€ÆPẠ

TryItOnline! или все тестовые случаи

Как?

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

Желе , 15 байт

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

Попробуйте онлайн! или Проверьте все контрольные примеры. ,

объяснение

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 байт

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

Безымянная функция принимает строку в качестве ввода и возвращает TrueилиFalse .

ToCharacterCode@#преобразует ввод в список его значений ASCII; IntegerDigits[...,2,7]превращает каждое значение в список его битов, дополняемый до длины 7, если необходимо. Итак, теперь у нас есть двумерный массив, и нам нужны все суммы строк и столбцов; и вот, символ-спазм {+##&@@#,+##&@@@#}&@...делает именно это (он применяет +##&функцию «суммировать все аргументы» к списку векторов в первой координате, используя @@, и к каждому вектору как свой собственный список целых чисел во второй координате, используя @@@) , Затем мы просто проверяем, есть ли результаты PrimeQ, сглаживаем список Join@@и берем Andвсе эти значения.


2

Рубин -rprime , 100 байт

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

Попробуйте онлайн!

объяснение

->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 байт

Бежать с -lF . Программа будет работать правильно только для первого входа. Завершите программу и снова запустите ваш следующий ввод.

Спасибо @Dada за то, что дали мне знать, что //после Fбыли излишни. Дополнительный байт можно удалить (для 112), отправив входные данные через via echo -n, но я чувствую, что это технически добавляет больше кода, так что 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

Удобочитаемый:

                                     #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
Версия, которая работает только с первым входом, прекрасно работает, поэтому вы можете поместить версию с 141 байтом в качестве основной и предложить другую для использования на нескольких входах.
Дада

Также обратите внимание, что вы можете опустить //после -F, и вы можете взять ввод без окончательного перевода строки (с echo -n), чтобы избавиться от -lфлага.
Дада

1

Python 3, 228 227 225 байт

Не очень хороший ответ, я не мог играть в гольф столько, сколько хотел бы, но я потратил так много времени на это, я чувствую, что должен опубликовать это. Предложения по сокращению байтов будут с благодарностью.

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

Редактировать 1: заменить e[0]%8==0на e[0]%8<1, теряя байт. Спасибо Flp.Tkc!

Правка 2: замена (i + 1) на - ~ i, потеря двух дополнительных байтов. Спасибо Эрику за то, что он показал, насколько плохи мои знания на уровне битов :). Тестируя эту ревизию, я обнаружил, что kappaэто действительно так ...


1
Вы могли бы изменить e[0]%8==0на e[0]%8<1?
FlipTack

@ Flp.Tkc Хорошее место! Нет никаких причин, почему это нельзя сделать.
FourOhFour

1
@ Flp.Tkc Не думаю, что смогу сохранить байты, сделав это функцией. Мне нравится, что у вас 404 представителя, кстати :)
FourOhFour

Предполагается <1, не так <0ли?
Разрушаемый Лимон

@ Разрушаемый Арбуз, да, позволь мне исправить это.
FourOhFour

1

Groovy, 151 137 байт

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

Никакой проверки на простоту в заводной ...

p={x->x<3||(2..(x**0.5)).every{x%it}}; - Закрытие для тестирования простоты.

y={it.every{p(it.count("1"))}}; - Закрытие, чтобы гарантировать, что все значения «1» для переданного двоичного двумерного массива являются простыми.

x=it.collect{0.toString((int)it,2) as List}; - Покрытие из строки в двоичный массив.

y(x)&&y(x.transpose()) - Для всех простых проверенных сумм в основной матрице и транспонированной матрице убедитесь, что они возвращают true.


1

Pyth , 37 байт

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

Попробуйте онлайн!


                                 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

Брахилог , 14 байт

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

Попробуйте онлайн!

Выходы через успех или неудачу. (В случае успеха, список всех сумм столбцов и строк доступен через выходную переменную.

   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 байтов

Çžy+bø€SOp¦W

Попробуйте онлайн!

Это мой первый код для гольфа, так что будьте спокойны :)

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

Это приводит к пустому результату для ввода одной буквы. Я не очень хорошо разбираюсь в O5AB1E, но если это неверное значение, это нормально.
Санчиз

1

Python 3 , 209 189 180 171 160 байтов

Спасибо кальмар за -9 байт :)

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

Попробуйте онлайн!


Мне нравится, как вы переписали тестовое заявление на печать :)
movatica

Да, я немного навязчиво склонен к f-строкам ... Кроме того, разве это не эквивалентно, если вы удалите t+в выражении map?
Восстановить Монику

Нет, потому что первичная проверка должна охватывать как строки, так и столбцы в битовой матрице. tимеет все строки, а [[t[i][j]..i..]..j..]транспонирован t, то есть столбцы. Если есть более короткий способ транспонирования матрицы, мы можем сохранить больше байтов :)
movatica

Это работает, когда я пытаюсь это сделать. Знаете ли вы строку, которая нарушает ее?
Восстановить Монику

Да. beezzдолжен вернуть false, но не возвращает. Это потому, что основная проверка не пройдена, она возвращает True4 бита. Попробуй print(p('1111')). Исправлено сейчас. Все тестовые случаи не покрывали это, потому что все используемые символы являются основными.
моватика

1

K (ок) , 40 33 байта

Решение:

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

Попробуйте онлайн!

Объяснение:

Половина создает матрицу, другая половина проверяет первичность.

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

JavaScript, 234 байта

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

Мы получаем горизонтальные значения, конвертируя число в двоичное, удаляя нули с помощью замены строки, а затем считая 1. Вертикальные суммы получаются путем циклического перехода от 1 до 7 и использования побитового И с 2, повышенными до n-й степени


Math.pow(2,i)можно сократить до (1<<i)предположения i<32, возможно, сэкономив 7 байт, а может и нет.
Наруёко

0

Clojure, 180 байт

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

Там может быть более короткий способ создания списков битов, а также тест на простоту.



0

Python 3, 164 байта

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 байт

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

Нет ссылки на TiO, потому что TiO по-прежнему работает на Ruby 2.5.5. 😭

объяснение

Довольно просто Первая строка получает двоичные цифры каждого символа в виде массива, дополненного семью цифрами, что на самом деле должно быть проще:

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

Проверьте , что номером блока параметров ( @1) и beginless диапазон ( ..6) жаркость .

Вторая строка суммирует строки и столбцы и проверяет, все ли они простые:

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

0

JavaScript (Node.js) , 149 146 ... 134 130 129 байт

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

Попробуйте онлайн!

объяснение

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.

Как это вообще работает !?

  • y.charCodeAt()&2**i
    • Нам нужен этот код , чтобы вернуть соответствующий бит , y.charCodeAt()если0 <= i < 7 и 0 в противном случае.
    • когда i < 7 код, по-видимому, работает как обычно.
    • когда 7 <= i <= 32 , так как соответствующий битy.charCodeAt() равен 0, результат равен 0, как и ожидалось.
    • когда 32 < i < 1024 , так какint32(2**i) == 0 , результат равен 0, как и ожидалось.
    • Когда 1024 <= i, 2**i == Infinityи с тех пор int32(Infinity) == 0, результат равен 0, как и ожидалось.
  • (P=r=>n%--r?P(r):~-r)(n)
    • Для простоты мы позволим R = --r = r - 1 .
    • Эта вспомогательная функция завершается, когда n % R == 0илиn % R is NaN .
      • n % R == 0: Rявляется факторомn .
        • Если R == 1, тогда nпрост, потому что все 1 < R < nне могут разделить n. Вернуть 0 (ложь).
        • Если R == -1тогда n == 0. Вернуть -2 (правда).
        • В противном случае вернитесь R - 1туда , где R - 1 > 0(правда).
      • n % R is NaN: Неверный модульный расчет.
        • Если R == 0: n == 1. Вернуть -1 (правда).
        • Если n is NaN: R is NaN. Вернуть -1 (правда).
    • В результате, только когда R == 1эта функция может вернуть ложное значение, указывая, что nэто простое число.
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.