Гипотеза Гольдбаха


15

Напишите программу, которая запрашивает у пользователя четное целое число больше 2.

Учитывая гипотезу Гольдбаха о том, что каждое четное целое число, большее 2, может быть выражено как сумма двух простых чисел, выведите два простых числа, которые при сложении вместе дают запрошенное четное число. Изменить: программа должна распечатать только пару простых чисел, а не все. Например:

4: 2 + 2

6: 3 + 3

8: 3 + 5

10: 5 + 5 или 3 + 7


«нужно только напечатать пару простых чисел» Значит ли это, что нам разрешено печатать больше пар?
Ayiko

Я полагаю, если это сокращает длину вашего кода, но это должно быть организовано
Rationality

Ответы:


11

APL, 34 или 44 байта

Первая версия имеет длину 34 символа и ограничена символами из исходных однобайтовых кодировок APL, например, поддерживаемых в Dyalog APL:

↑c/⍨n=+/¨c←,∘.,⍨v/⍨~v∊v∘.×v←1↓⍳n←⎕

Объяснение:

                               n←⎕   ⍝ ask for a number, store as n
                          v←1↓⍳n     ⍝ generate all integers from 2 to n
                      v∘.×v          ⍝ compute the product table of any two such integers
                v/⍨~v∊               ⍝ select those that don't appear in the product table 
         c←,∘.,⍨                     ⍝ generate all possible pairs of these primes
    n=+/¨c                           ⍝ check which pairs have a sum equal to n
↑c/⍨                                 ⍝ take the first that does

Вторая версия имеет длину всего 22 символа, потому что она использует πфункцию для проверки простых чисел, но она доступна только в NARS2000, который использует Unicode, поэтому число байтов равно 44 в UCS-2:

2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1

Объяснение:

                   ⎕    ⍝ ask for a number N
                  ⍳ -1  ⍝ generate all naturals from 1 to N-1
             (⍪,⌽)      ⍝ arrange it into a table of all pairs of naturals with sum N
     {∧/0π⍵}            ⍝ check which pairs are made of all primes
2⍴(⌿⍨       )           ⍝ return the first pair that does

Примеры

(⎕: запрос на ввод номера)

      2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1
⎕:
      4
2 2
      2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1
⎕:
      6
3 3
      2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1
⎕:
      8
3 5
      2⍴(⌿⍨{∧/0π⍵})(⍪,⌽)⍳⎕-1
⎕:
      124
11 113

Будет ли ¯2π⍳2πnработать в качестве основного генератора?
Оберон

@ Оберон, что πточно делает оператор?
Прим

Диадическое πпереключается с : ¯2πxвычисляет x-е простое число, ¯1πxпервое простое число меньше x, 0πxпроверяет x на простоту, 1πxпервое простое число больше x, 2πxявляется числом простых чисел меньше x, 10πxявляется числом делителей x, 11πxявляется суммой из всех делителей x, 12πxи 13πxявляются функции Мёбиуса и totient, соответственно. И последнее, но не менее важное: монадическое πxвозвращает простую факторизацию x.
Оберон

@ Оберон, это специфично для NARS2000, не так ли? Кажется, интересный переводчик. Я попробую это и пересмотрю свой ответ.
Tobia

@ Тобиа Это? Тогда извини. Я видел где-то ссылки, но они никогда не упоминали NARS2000. Хорошо знать.
Оберон

6

Python 2, 75 71 байт

n=input();k=m=1;p={0}
while{n-k,k}-p:m*=k*k;k+=1;p|={m%k*k}
print n-k,k

Проверьте это на Ideone .

Как это устроено

Мы используем следствие теоремы Вильсона :

следствие теоремы Вильсона

Во все времена переменная m равна квадрату факториала k - 1 ; k начинается со значения 1, а m со значения 0! ² = 1 . Множество p будет состоять из 0 и всех простых чисел вплоть до текущего значения k .

На каждой итерации мы сначала проверяем, принадлежат ли n - k и k к p , что верно тогда и только тогда, когда разность множеств {nk, k} и p пуста. Если это так, условие ложно, и цикл продолжается.

Обратите внимание, что k> 0 и {n - k, k} будут удовлетворять условию для некоторого положительного значения n - k (при условии, что гипотеза Гольдбаха верна), поэтому 0 в p не приведет к ложным срабатываниям.

В цикле мы обновляем k и m . Новое значение m равно m × k² = (k - 1)! ² × k² = k! ² , а новое значение k равно k + 1 , поэтому m = (k - 1)! ² сохраняется до и после обновление.

Затем мы выполняем объединение множеств, чтобы добавить значение m% k × k к p . По следствию из теоремы Вильсона это добавит 1 × k = k, если k простое, и 0 × k = 0, если нет.

Когда цикл заканчивается, мы печатаем последние значения n - k и k , которые будут простыми числами с суммой n .


Как же работает этот алгоритм генерации простых чисел?
Дрянная Монахиня

@ LeakyNun Я добавил объяснение.
Деннис

Ох ... это гений.
Дрянная Монахиня


4

PHP - 73 байта

<?for(;@($n%--$$n?:$o=&$argv[1]>$$n=++$n)||${++$b}^${--$o};);echo"$b+$o";

Ввод принимается в качестве аргумента командной строки.

Пример использования:

$ php goldbach.php 7098
19+7079

4

GolfScript 41 33 32

~(,2>.-1%]zip{{.,2>\{\%!}+,},!}?

Принимает аргумент командной строки, например

echo "14" | ruby golfscript.rb goldbach.gs
-> [2 12]

Находит все соответствующие разделы входного номера с помощью:

(,2>.-1%]zip  #If only zip were a one-character command!  It is so often useful.

и затем находит первый раздел, где никакие числа НЕ являются простыми с:

{np,!}? #For each partition, filter down to elements that are not prime, and only accept if there are no such results (since [] is falsey).

где составной проверочный блок np:

{.,2>\{\%!}+,}

этот блок фильтрует все числа, которые равномерно делят данное число. Если таких чисел нет (так что число простое), результат []будет неправильным в GolfScript.



3

R, 170 112 83 символов

a=scan();b=2:a;p=b[rowSums(!outer(b,b,`%%`))<2];q=p[(a-p)%in%p][1];cat(a,":",q,a-q)

Отступ:

a=scan() #Take user input as a numeric
b=2:a
p=b[rowSums(!outer(b,b,`%%`))<2] #Find all primes from 2 to user input
q=p[(a-p)%in%p][1] #Check which a-p also belong to p and takes the first one
cat(a,":",q,a-q)

Использование:

> a=scan();b=2:a;p=b[rowSums(!outer(b,b,`%%`))<2];q=p[(a-p)%in%p][1];cat(a,":",q,a-q)
1: 72
2: 
Read 1 item
72 : 5 67 

Старое решение на 112 символов, для потомков

a=scan();b=2:a;p=b[rowSums(!outer(b,b,`%%`))<2];w=which(outer(p,p,`+`)==a,T);cat(a,":",p[w[1,1]],p[w[1,2]])

Отступ:

a=scan()
b=2:a
p=b[rowSums(!outer(b,b,`%%`))<2]
w=which(outer(p,p,`+`)==a,T) #Find the index of valid combinations
cat(a,":",p[w[1,1]],p[w[1,2]]) #Prints the first valid combination

Это и безумно, и гениально!
Томас

3

Питон - 107

В основном улучшение второй части ответа нутрии (я запустил это на 2.7, но я думаю, что это также должно работать на 3.x)

p=lambda x:all(x%i!=0 for i in range(2,x))
n=input()
for i in range(2,n-1):
    if p(i)&p(n-i): print i,n-i

Символы новой строки и пробелы после :обязательных?
Мниип

Размер вкладки может быть уменьшен до пробела, а пространство до печати можно удалить (сбрасывает 4 байта).
clismique

3

JavaScript (ES6) (Regex), 105

a=/^(xx+?)(?!(xx+)\2+$)x*(?=\1$)(?!(xx+)\3+$)/.exec("x".repeat(prompt()));alert(a[1].length+"+"+a[0].length)

Теперь у вас есть регулярное выражение, которое проверяет гипотезу Гольдбаха, которая требует низких требований к специальным функциям (базовая обратная поддержка, положительный и отрицательный прогноз).

Это использует String.prototype.repeat() , что является частью предложения EcmaScript 6th edition. В настоящее время этот код работает только в Firefox.

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


2

Scala, 286 192 172 148 символов

Не самый быстрый, но это работает. Вызовите g (10), чтобы получить список пар Гольдбаха для 10.

def g(n:Int)={def p(n:Int,f:Int=2):Boolean=f>n/2||n%f!=0&&p(n,f+1)
s"$n : "+(for(i<-2 to n/2;j=n-i if p(i)&&p(j))yield s"$i + $j").mkString(" or ")}

Преобразование в C ++ является простым.


2

C - 139 129 знаков

a,b;i(x,y){return x>y?x%y?i(x,y+1):0:x>1;}main(){scanf("%i",&a);for(b=a/2;b-->1;)i(b,2)&&i(a-
b,2)&&printf("%i:%i+%i\n",a,b,a-b);}

Вы можете побрить 8 символов, удалив intобъявления в вашей функции i. Вы можете сохранить еще 2 символа, удалив ifи добавив еще один двойной амперсанд:i(b,2)&&i(a-b,2)&&printf(...)
Джош

Благодарность! Не думал об этом &&. (Я никогда не привыкну к глушению типа аргумента ...)
Оберон

Я люблю ваше использование вложенной троичной.
Джош

2

newLISP - 169 148 символов

(define(p n)(=(length(factor n))1))
(define(g n)(when(even? n)(for(i 3 n 2)
(and(p i)(p(- n i))(println n {: } i { }(- n i))))))
(g(int(read-line)))

включает в себя код для его запуска. Результаты чрезмерно щедры ...

72: 5 67
72: 11 61
72: 13 59
72: 19 53
72: 29 43
72: 31 41
72: 41 31
72: 43 29
72: 53 19
72: 59 13
72: 61 11
72: 67 5

2

Шалфей, 60

Схожи по баллам и ощущениям с решением res , но я думаю, что это достаточно отличается для публикации.

i=n=input()
while not{i,n-i}<set(primes(n)):i-=1
print i,n-i

2

Шалфей , 65 62

n=input()
i=0
p=is_prime
while p(i)*p(n-i)==0:i+=1
print i,n-i

С указанным выше в файле goldbach.sage, выполните его с Sage, работающим в терминале:

sage: %runfile goldbach.sage 

Спасибо @boothby за p=is_primeидею.


Вы можете уменьшить это до 62, установив p=is_prime.
Boothby

2

Haskell, 97C

g n=head[(a,b)|let q=p n,a<-q,b<-q,a+b==n]
p n=filter c[2..n]
c p=null[x|x<-[2..p-1],p`mod`x==0]

Объяснение:

  • gэто функция "goldbach". призваниеg n дает вам пару простых чисел, которые складываются в n.
  • pэто функция, которая генерирует список простых чисел меньше, чем n.
  • c является основной функцией проверки, используемой для определения p .

Пример работы:

*Main> g 4
(2,2)
*Main> g 6
(3,3)
*Main> g 8
(3,5)
*Main> g 10
(3,7)
*Main> g 12
(5,7)
*Main> map g [4,6..100]
[(2,2),(3,3),(3,5),(3,7),(5,7),(3,11),(3,13),(5,13),(3,17),(3,19),(5,19),(3,23),(5,23),(7,23),(3,29),(3,31),(5,31),(7,31),(3,37),(5,37),(3,41),(3,43),(5,43),(3,47),(5,47),(7,47),(3,53),(5,53),(7,53),(3,59),(3,61),(5,61),(7,61),(3,67),(5,67),(3,71),(3,73),(5,73),(7,73),(3,79),(5,79),(3,83),(5,83),(7,83),(3,89),(5,89),(7,89),(19,79),(3,97)]

2

Mathematica 56

Это возвращает все решения для входного целого числа.

Select[Tuples[Prime@Range@PrimePi[n = Input[]], 2], Tr@# == n &]

Например, когда вводится 1298…

{{7, 1291}, {19, 1279}, {61, 1237}, {67, 1231}, {97, 1201}, {127, 1171}, {181, 1117}, {211, 1087}, { 229, 1069}, {277, 1021}, {307, 991}, {331, 967}, {379, 919}, {421, 877}, {439, 859}, {487, 811}, {541, 757}, {547, 751}, {571, 727}, {607, 691}, {691, 607}, {727, 571}, {751, 547}, {757, 541}, {811, 487} , {859, 439}, {877, 421}, {919, 379}, {967, 331}, {991, 307}, {1021, 277}, {1069, 229}, {1087, 211}, { 1117, 181}, {1171, 127}, {1201, 97}, {1231, 67}, {1237, 61}, {1279, 19}, {1291, 7}}

Как написано, он возвращает каждое решение дважды.

Union[Sort/@ %]

{{7, 1291}, {19, 1279}, {61, 1237}, {67, 1231}, {97, 1201}, {127, 1171}, {181, 1117}, {211, 1087}, { 229, 1069}, {277, 1021}, {307, 991}, {331, 967}, {379, 919}, {421, 877}, {439, 859}, {487, 811}, {541, 757}, {547, 751}, {571, 727}, {607, 691}}


Вход 2, спросите оракула, останавливается ли он, докажите / опровергните гипотезу о двух простых числах, выиграйте
Filipq

1

Юлия, 62 символа (85 с подсказкой)

julia> g(n)=collect(filter((x)->sum(x)==n,combinations(primes(n),2)))
g (generic function with 1 method)

julia> g(88)
4-element Array{Array{Int64,1},1}:
 [5,83] 
 [17,71]
 [29,59]
 [41,47]

Это не подсказывает пользователю (как требуется), не так ли?
Res

Нет, не заметил этого. Было бы добавить много символов прямо сейчас, Джулия. g(int(readline(STDIN)))
gggg

1

БРГ , 31

Для вашего калькулятора TI-84

`A:.5A→B@%;A,4)4$~B+1,B-1#~B,B&

Нет простых встроенных модулей.

Пример работает

?4
               2
               2
?6
               3
               3
?8
               3
               5
?10
               5
               5

1

JavaScript, 139 137 136

a=prompt();function b(n){for(i=2;i<n;i++)if(n%i<1)return;return 1}for(c=2,r=1;c<a&&r;c++)if(b(c)&&b(a-c))alert(a+": "+c+" + "+(a-c)),r=0

Я думаю, что вы можете сбрить еще 2 return;return 0;
символа

1

Python 3 - 150 143 персонажа

Старая версия (150 символов):

p=lambda n:0 in[n % i for i in range(2,n)]
n=int(input())
[print('%d+%d'%(a, b))for b in range(2,n)for a in range(2,n)if not(a+b!=n or p(a) or p(b))]

Новая версия (благодаря ProgramFOX):

p=lambda n:0 in[n%i for i in range(2,n)]
n=int(input())
[print('%d+%d'%(a,b))for b in range(2,n)for a in range(2,n)if not((a+b!=n)|p(a)|p(b))]

Он печатает каждую комбинацию, например:
4 2 + 2
10 7 + 3 5 + 5 3 + 7


| может безопасно использоваться с логическим типом, так (a+b!=n)|p(a)|p(b)
n̴̖̋h̷͉̃a̷̭̿h̸̡̅ẗ̵̨́d̷̰̀ĥ̷̳

Еще короче, используя: print([(a,b)for b in range(2,n)for a in range(2,n)if not((a+b!=n)|p(a)|p(b))])(печатает список кортежей, чья сумма равна n). Экономит 8 байт.
agtoever

Также использование r=range(2,n)и ссылки rсохраняют еще несколько.
agtoever

1

q [116 символов]

y where all each{{2=count where 0=(x mod)each til x+1}each x}each y:{a where x=sum each a:a cross a:til x}"I"$read0 0

Нет встроенной функции, чтобы найти простое число.

вход

72

Выход

5  67
11 61
13 59
19 53
29 43
31 41
41 31
43 29
53 19
59 13
61 11
67 5

1

Питон - 206

Немного опоздал на вечеринку, но я практикую свои навыки игры в гольф.

Я фактически закодировал это прежде, чем нашел этот вопрос! Так что у меня нет прекрасной лямбды, которую используют другие решения Python.

import math
def p(n):
    if n%2==0&n>2:return False
    for i in range(3,n):
        if n%i==0:return False
    return True 
X=int(input())
for i in range(2,X):
    if p(i)&p(X-i):print i,X-i;break

1

J - 35 32 символа

«Подскажите пользователю» - проклятие каждого игрока в гольф. Там идут все мои с трудом заработанные персонажи!

p:(n,n)#:i.&n,+/~p:i.n=:".1!:1]1

Разъяснение:

  • ".1!:1]1- прочитать строку ( 1!:1) из ввода (дескриптор файла 1) и преобразовать его в число (". ).
  • p:i.n=:- Присвойте этот номер переменной n, а затем возьмите первыйn простые числа.
  • +/~- Сделайте сложение стола, nширокий иn высокий.
  • i.&n, - превратить таблицу в один список, а затем найти индекс первого появления n , который существует, если гипотеза Гольдбаха верна.
  • p:(n,n)#: - Получить строку и столбец из индекса и взять соответствующие простые числа.

Использование:

   p:(n,n)#:i.&n,+/~p:i.n=:".1!:1]1
666
5 661
   p:(n,n)#:i.&n,+/~p:i.n=:".1!:1]1
1024
3 1021

Если бы подсказка не была обязательной, вот глагол из 25 символов:

(,~p:@#:]i.~&,+/~@:p:@i.)


1

Юлия, 50 49 байтов

~=primes;n=ARGS[]|>int
(n-~n)∩~n|>extrema|>show

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

Если бы функция была приемлемой, код можно было бы сократить до 32 байт :

~=primes
!n=(n-~n)∩~n|>extrema

Как это устроено

~=primesсоздает псевдоним для встроенной функции простых чисел, которая возвращает список всех простых чисел вплоть до своего аргумента. n=ARGS[]|>intразбирает первый аргумент командной строки, так как сохраняет его в n .

Чтобы найти подходящую пару простых чисел, мы сначала вычисляем вышеупомянутый простой диапазон с помощью ~n. Тогда, n-~nдает все различия этих простых чисел и п .

Пересекая ( ) результат с самим простым диапазоном, мы убеждаемся, что остальные простые числа p таковы, что n - p также простое число.

Наконец, extremaпринимает самое низкое и самое высокое простое в пересечении, поэтому их сумма должна быть n .


0

SQL, 295 284

В postgresql:

create function c(c int) returns table (n int, m int) as $$ 
with recursive i(n) as
(select 2 union all select n+1 from i where n<c), 
p as (select * from i a where not exists 
(select * from i b where a.n!=b.n and mod(a.n,b.n)=0))
select * from p a, p b where a.n+b.n=c 
$$ language sql;

Должен быть в состоянии сделать это в половине пространства, хотя, если бы не такие вещи, как «нет левого внешнего соединения в рекурсии», «нет подзапроса в рекурсии» ...

Вот вывод:

postgres=# select c(10);
   c   
-------
 (3,7)
 (5,5)
 (7,3)
(3 rows)

postgres=# select c(88);
   c    
---------
 (5,83)
 (17,71)
 (29,59)
 (41,47)
 (47,41)
 (59,29)
 (71,17)
 (83,5)
(8 rows)

0

Партия - 266

@echo off&setLocal enableDelayedExpansion&for /L %%a in (2,1,%1)do (set/aa=%%a-1&set c=&for /L %%b in (2,1,!a!)do set/ab=%%a%%%%b&if !b!==0 set c=1
if !c! NEQ 1 set l=!l!%%a,)&for %%c in (!l!)do for %%d in (!l!)do set/ad=%%c+%%d&if !d!==%1 set o=%%c + %%d
echo !o!

Изложите аккуратно -

@echo off
setLocal enableDelayedExpansion
for /L %%a in (2,1,%1) do (
    set /a a=%%a-1
    set c=
    for /L %%b in (2,1,!a!) do (
        set /a b=%%a%%%%b
        if !b!==0 set c=1
    )
    if !c! NEQ 1 set l=!l!%%a,
)
for %%c in (!l!) do for %%d in (!l!) do (
    set /a d=%%c+%%d
    if !d!==%1 set o=%%c + %%d
)
echo !o!

0

Perl 5, 58 байт

57, плюс 1 для -nE

/^(11+?)(?!(11+)\2+$)1*(?=\1$)(?!(11+)\3+$)/;say for$1,$&

Вход и выход в унарном виде. Пример:

$ perl -nE'/^(11+?)(?!(11+)\2+$)1*(?=\1$)(?!(11+)\3+$)/;say for$1,$&'
1111111111
111
1111111

Шапка-наконечник.


0

Oracle SQL 11.2, 202 байта

WITH v(x,y,s)AS(SELECT LEVEL,LEVEL,0 FROM DUAL CONNECT BY LEVEL<=:1 UNION ALL SELECT x,y-1,s+SIGN(MOD(x,y))FROM v WHERE y>1),p AS(SELECT x FROM v WHERE x-s=2)SELECT a.x,b.x FROM p a,p b WHERE:1=a.x+b.x;   

Un-golfed

WITH v(x,y,s) AS
(
  SELECT LEVEL,LEVEL,0 FROM DUAL CONNECT BY LEVEL<=:1 
  UNION ALL 
  SELECT x,y-1,s+SIGN(MOD(x,y))FROM v WHERE y>1
)
,p AS (SELECT x FROM v WHERE x-s=2)
SELECT a.x,b.x 
FROM p a,p b 
WHERE :1=a.x+b.x;   

0

Python 3, 107 байт

b=lambda x:all(x%y for y in range(2,x))
g=lambda x,i=2:((i,x-i)if b(i)&b(x-i)else g(x,i+1))if(i<x)else 0

b (x) - это критерий простоты для x, а g (x) просматривает числа, чтобы найти два подходящих простых числа.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.