Code Golf: Happy Primes!

Сегодня воскресенье, время для игры в гольф с кодом!

Задача

Напишите кратчайший исходный код по количеству символов, чтобы определить, является ли входное число «счастливым простым», «грустным простым», «счастливым непростым» или «грустным непростым».

Input

Входными данными должно быть целое число, полученное из аргумента командной строки или стандартного ввода. Не беспокойтесь об обработке больших чисел, но сделайте это, если можете / хотите. Поведение будет неопределенным для входных значений меньше 1, но 1 дает определенный результат.

Выходные данные

Выходные данные должны вывести тип числа: «счастливое простое», «грустное простое», «счастливое непростое» или «грустное непростое». Завершающий символ новой строки необязательно .

Примеры

$ happyprime 139
happy prime
$ happyprime 2
sad prime
$ happyprime 440
happy non-prime
$ happyprime 78
sad non-prime

Определения

На всякий случай, если вашему мозгу нужно освежить память.

Счастливое число

Из Википедии,

Счастливое число определяется следующим процессом. Начиная с любого положительного целого числа , замените число суммой квадратов его цифр и повторяйте процесс до тех пор, пока число не станет равным 1 (где он будет оставаться), или он будет бесконечно повторяться в цикле , который не включает 1.Те числа , для которых этот процесс заканчивается на 1, являются счастливыми числами, а те, которые не заканчиваются на 1, являются несчастливыми числами (или грустными числами).

Например,

  • 139
  • 1 ^ 2 + 3 ^ 2 + 9 ^ 2 = 91
  • 9 ^ 2 + 1 ^ 2 = 82
  • 8 ^ 2 + 2 ^ 2 = 68
  • 6 ^ 2 + 8 ^ 2 = 100
  • 1 ^ 2 + 0 ^ 2 + 0 ^ 2 = 1

Простое число

простое число является целым числом больше, чем 1 и имеет ровно два делителя: 1 и себя.

Happy Prime

Счастливое простое число - это одновременно и счастливое, и простое число.

Выбор ответа

Очевидно, ответом будет самый короткий исходный код по количеству символов, который выводит указанные результаты во всех тестируемых мной случаях. Я отмечу ответ, как только появится следующая (решенная сообществом) задача по игре в гольф с кодом, чтобы мы могли сосредоточить всю нашу энергию на ней. :)

Решение

Что ж, похоже, что в городе появился новый код для гольфа, и с момента публикации этого вопроса прошла около недели, поэтому я отметил самый короткий исходный код как ответ (gnibbler's 64 символа Решение Golfscript ). Тем не менее, мне понравилось как решение для 99 символов Mathematica от Belisarius, так и решение для загадочных 107 символов dc от Nabb.

Всем остальным, отличная работа! На моем компьютере никогда не было столько языковых сред программирования. Я надеюсь, что каждый научился новым пакостям для своего любимого языка.

Повторное использование

Я повторно опубликовал часть кода, созданного в ходе этого конкурса, в качестве примера сценария, который я написал для тестирования различных программ по сравнению с эталонной реализацией для автоматической оценки . README в этом каталоге объясняет, откуда берется исходный код, и заявляет, что весь код повторно используется под лицензией CC BY-SA 2.5 (как указано в правовом разделе SO ). Каждый каталог помечен вашим отображаемым именем во время отправки.

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

49
задан 8 revs, 2 users 98% 23 May 2017 в 01:55
поделиться

29 ответов

GolfScript - 64 символа (работает для 1)

~:@.{0\`{15&.*+}/}*1=!"happy sad "6/=@,{@\)%!},,2=4*"non-prime">

Эта программа выполняет n итераций для определения счастья числа, что очень расточительно для больших чисел, но code-golf не о сохранении ресурсов, кроме персонажей. Также неэффективен простой тест - деление n на все значения от 1 до n включительно и проверка наличия ровно двух значений с нулевым остатком. Таким образом, хотя это теоретически верно, работа с действительно большими числами нецелесообразна на реальных компьютерах

GolfScript - 63 символа (не выполняется для 1)

~:@9{0\`{15&.*+}/}*1=!"happy sad "6/=@,2>{@\%!},!4*"non-prime">
19
ответ дан 7 November 2019 в 11:11
поделиться

Python 2.6, 300 298 294 символа

В отличие от предыдущего ответа, здесь не используется регулярное выражение.

Я уверен, что есть способ сократить мою функцию h (x) , но я все еще изучаю Python, поэтому понятия не имею.

p (x) возвращает True, если это не простое число. h (x) возвращает True, если все в порядке. Я сделал t = True , чтобы сократить количество символов при проверке истинности.

x=input()
def p(x):
 if x==1 or 1 in [1 for i in range(2,x) if x%i==0]: return True
def h(x):
 l=[]
 while x not in l:
  l.append(x)
  x=sum([int(i)**2 for i in str(x)])
 if 1 in l: return True
if h(x):print'happy',
elif not h(x):print'sad',
if p(x):print'non-prime'
elif not p(x):print'prime'
1
ответ дан 7 November 2019 в 11:11
поделиться

C ++, 258 231 230 227 символов

#include<iostream>
#define w while
int m,n,i,j,t=10;int main(){w(std::cin>>n){j=0,m=n;w(n>1){i=0;do i+=n%t*(n%t);w(n/=t);n=n*n+i;n=++j&0xFFFF?n:0;}i=1;w(m%++i&&j>1);std::cout<<(n?"happy":"sad")<<(i-m?" non-":" ")<<"prime\n";}}

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

РЕДАКТИРОВАТЬ

В общем, привели в порядок, думаю, сейчас он почти на пределе, без полной переписывания.

Также забыл добавить, что это предполагает, что не существует чисел с последовательностью более 0xFFFF, что является довольно разумным предположением.

РЕДАКТИРОВАТЬ 2

исправлена ​​ошибка. переставлен, чтобы удалить излишние вызовы std :: cout.

3
ответ дан 7 November 2019 в 11:11
поделиться

Perl, 135C

sub h{my$s;$s+=$_**2for split//,pop;($s-4)?($s-1)?&h($s):1:0}$a=pop;
print h($a)?happy:sad,$",(1x$a)=~/^1?$|^(11+?)\1+$/&&"non-",prime

Комбинированный C и Perl

3
ответ дан 7 November 2019 в 11:11
поделиться

Python (285 270 269 246 241 247 240 237 символов, 21 20 21 18 19 строк)

n=input()
s='prime'
for i in range(2,n):
    if n%i==0: 
        s='non'+s
        break
f=list(str(n))
g=set()
while n!=1:
    n=sum([int(z)**2 for z in f])
    if n in g:
        s='sad '+s
        break
    else:
        f=list(str(n))
        g.add(n)
else:
    s='happy '+s
print s

EDIT: Да, число увеличилось, был баг :-P

1
ответ дан 7 November 2019 в 11:11
поделиться

Scala, 253 247 246

object H{def main(a:Array[String]){var s=Set(0)
val n=a(0)toInt
def r(m:Int):String={val k=""+m map(c=>c*(c-96)+2304)sum;if(k<2)"happy"else if(s(k))"sad"else{s+=k;r(k)}}
printf("%s %sprime",r(n),if(n<2|(2 to n-1 exists(n%_==0)))"non-"else"")}}

Вероятно, есть место для улучшений. Проклятый тест на 1 как неосновной стоит 6 символов: - (

2
ответ дан 7 November 2019 в 11:11
поделиться

F #, 249 символов

let n=stdin.ReadLine()|>int
let rec s x=seq{yield x;yield!string x|>Seq.sumBy(fun c->(int c-48)*(int c-48))|>s}
printfn"%s %sprime"(if s n|>Seq.take 99|>Seq.exists((=)1)then"happy"else"sad")(if[2..n/2]|>Seq.exists(fun d->n%d=0)then"non-"else"")
2
ответ дан 7 November 2019 в 11:11
поделиться

MATLAB - 166 символов

function happyprime(a)
h={'non-prime','prime'};
h=h{isprime(str2num(a))+1};
for i=1:99
   a=num2str(sum(str2num((a)').^2));
end
s={'Sad ','Happy '};
[s{(str2num(a)==1)+1},h]

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

happyprime 139
ans =
Happy prime
3
ответ дан 7 November 2019 в 11:11
поделиться

MATLAB 7.8.0 (R2009a) - 120 символов

Пробелы, новые строки и комментарии добавлены для удобства чтения

n=input('');
s=n;
c={'happy ','sad ','non-'};
while s>6,
  s=int2str(s)-48;
  s=s*s';                    %'# Comment to fix code highlighting
end;
disp([c{[s<2 s>1 ~isprime(n)]} 'prime'])
7
ответ дан 7 November 2019 в 11:11
поделиться

C #, 380 378 374 372 364 363 315 280 275 274 символа

Автор заменив рекурсивную функцию вложенными циклами, я смог довести количество штрихов до приличных 280 (на 100 меньше, чем в оригинале).

class P{static void Main(string[]a){var s=new System.Collections.Generic.HashSet<int>();int n=int.Parse(a[0]),p=n>1?4:0,c,d=1;for(;++d<n;)if(n%d<1)p=0;for(;n>1&s.Add(n);n=c)for(c=0;n>0;c+=d*d,n/=10)d=n%10;System.Console.Write((n>1?"sad":"happy")+" non-prime".Remove(1,p));}}

Вот он с пробелами:

class P
{
    static void Main(string[] a)
    {
        var s = new System.Collections.Generic.HashSet<int>();
        int n = int.Parse(a[0]),
            p = n > 1 ? 4 : 0,
            c,
            d = 1;
        // find out if the number is prime
        while (++d < n)
            if (n % d < 1)
                p = 0;
        // figure out happiness
        for (; n > 1 & s.Add(n); n = c)
            for (c = 0; n > 0; c += d * d, n /= 10)
                d = n % 10;

        System.Console.Write(
            (n > 1 ? "sad" : "happy")
            + " non-prime".Remove(1,p)
            );
    }
}
12
ответ дан 7 November 2019 в 11:11
поделиться

Python 2.6: 194 180 символов, 4 строки

import re
s=lambda n,l:0if n==1 else n in l or s(sum(int(a)**2for a in str(n)),l+[n])
n=input()
print['happy','sad'][s(n,[])],'non-'*bool(re.match(r'1?$|(11+?)\1+$','1'*n))+'prime'

Возможность лексера разделить 0if и 2for на два токена каждый была для меня приятным сюрпризом :) (хотя она не работает с else )

Функция s (печально) является рекурсивной и получает список предыдущих чисел в цикле в качестве второго параметра. Примитивность тестируется на лету с помощью трюка с регулярным выражением .

Используя устаревший синтаксис `n` вместо str (n) , можно дополнительно уменьшить количество символов на 4 символа, но я предпочитаю его не использовать.

9
ответ дан 7 November 2019 в 11:11
поделиться

VBA 245 символов

Хороший стартер, обрежет, если позволит время. Это только моя вторая попытка в гольф-коде!

Public Sub G(N)
Dim Z, D, X, O
X = N
Z = N
Do Until Z = 1 Or X > N Or X = 0
    X = 0
    For D = 1 To Len(CStr(Z))
        X = X + CLng(Mid(CStr(Z), D, 1) ^ 2)
    Next D
    Z = X
Loop
If Z = 1 Then O = "Happy" Else O = "Sad"
D = 2
Do
    If N / D = Int(N / D) Then O = O & " Not Prime": Debug.Print O: Exit Sub
    D = D + 1
Loop While D < N
O = O & " Prime"
Debug.Print O
End Sub
3
ответ дан 7 November 2019 в 11:11
поделиться

Python - 127 символов

Превосходство обоих ответов perl на данный момент!

l=n=input()
while l>4:l=sum(int(i)**2for i in`l`)
print['sad','happy'][l<2],'non-prime'[4*all(n%i for i in range(2,n))*(n>1):]

Я также перенес этот ответ на GolfScript , и он чуть больше 1/2 размера!

13
ответ дан 7 November 2019 в 11:11
поделиться

Java: 294 286 285 282 277 262 260 символов


  • Обновление 1 : заменено BigInteger # isProbablePrime () на регулярное выражение . Сохранено 8 символов.

  • Обновление 2 : заменено && на & (упс). Сохранен 1 симв.

  • Обновление 3 : немного отредактирован s . Сохранено 3 символа.

  • Обновление 4 : тест на n! = 1 оказался лишним. Сохранено 5 символов.

  • Обновление 5 : регулярное выражение заменено на цикл for и переработаны маленькие биты цикла for. Сохранено 15 символов.

  • Обновление 6 : заменено int / Integer на long / Long . Сохранено 2 символа.


import java.util.*;class H{public static void main(String[]a){long n=new Long(a[0]),p=n>1?1:0,s,d=1;while(++d<n)if(n%d<1)p=0;for(Set c=new HashSet();c.add(n);n=s)for(s=0;n>0;s+=d*d,n/=10)d=n%10;System.out.printf("%s %sprime",n>1?"sad":"happy",p>0?"":"non-");}}

С символами новой строки:

import java.util.*;
class H{
 public static void main(String[]a){
  long n=new Long(a[0]),p=n>1?1:0,s,d=1;
  while(++d<n)if(n%d<1)p=0;
  for(Set c=new HashSet();c.add(n);n=s)for(s=0;n>0;s+=d*d,n/=10)d=n%10;
  System.out.printf("%s %sprime",n>1?"sad":"happy",p>0?"":"non-");
 }
}
4
ответ дан 7 November 2019 в 11:11
поделиться

Haskell 172

h s n|n`notElem`s=h(n:s)$sum[read[k]^2|k<-show n]|1`elem`s="happy "|0<1="sad "
c n|n<2||any((0==).mod n)[2..n-1]="non-"|0<1=[]
y n=h[]n++c n++"prime"
main=readLn>>=putStr.y
5
ответ дан 7 November 2019 в 11:11
поделиться

Mathematica 115 108 107 102 100 99 91 87 Chars


87 символов

Print[If[Nest[Tr[IntegerDigits@#^2]&,#,9]>1,Sad,Happy],If[PrimeQ@#," "," non-"],prime]&

-- Mr.Wizard


Da monkey learned a few tricks (91 chars)

 Print[
       If[Nest[Plus@@(IntegerDigits@ #^2) &, #, 9] > 1, Sad, Happy ],
       If[PrimeQ@#, " ", " non-"], prime
      ] &

Invoke with %[7]

Edit 5 - 99 Chars/

Достаточно девяти итераций. Спасибо @Nabb, @mjschultz

h = Print[
    If[Nest[Plus @@ (IntegerDigits@#^2) &, #, 9] > 1, "Sad ", "Happy "]
   , If[PrimeQ@#, "", "non-"], "prime"] &

Edit 4 - 100 Chars/

То же самое, что и Edit 3, заменяя 10^2 на 99 (разрешая 84 цифры для входных значений) ... Спасибо, @Greg

h = Print[
    If[Nest[Plus @@ (IntegerDigits@#^2) &, #, 99] > 1, "Sad ", "Happy "]
   , If[PrimeQ@#, "", "non-"], "prime"] &

Edit 3 - 102 Chars/

Переработал цикл еще раз.

Интересно, что глубина рекурсии до достижения 1 ограничена (15 + количество цифр аргумента). См. здесь

Таким образом, для чисел с количеством цифр менее 85 (я думаю, что этот предел вполне соответствует пожеланию OP "Не беспокойтесь о работе с большими числами") работает следующий код

h = Print[
    If[Nest[Plus @@ (IntegerDigits@#^2) &, #, 10^2] > 1, "Sad ", "Happy "]
   , If[PrimeQ@#, "", "non-"], "prime"] &

Я заменил "NestWhile" на более короткий "Nest", и поэтому, вместо указания условия остановки рекурсии, достаточно жестко закодировать желаемую глубину рекурсии (10^2).

Это не очень эффективно, но такова жизнь гольфиста :D

Правка 2 - 107 Chars/

Переработано задание Sad/Happy

h = Print[
     If[NestWhile[Plus @@ (IntegerDigits@#^2) &, #, # > 4 &] > 1,"Sad ","Happy "]
    ,If[PrimeQ@#, "", "non-"]
    , "prime"] &

Все пробелы/новые строки, кроме литералов, необязательны и добавлены для удобочитаемости

Объяснение:

Рекурсия

    NestWhile[Plus @@ (IntegerDigits@#^2) &, #, # > 4 &]

Рекурсия применяет "функцию" [Сложить сумму квадратов цифр], пока результат не станет 4 или меньше. Функция обладает тем свойством, что она останавливается на "1", или входит в цикл {4, 16, 37, 58, 89, 145, 42, 20, 4, ...}.

Таким образом, когда результат равен "1", число "Счастливое", а когда результат равен "4", оно "Печальное".

Если результат "2", то число также является SAD, потому что оно войдет в цикл SAD на следующей итерации (2^2 = 4).

Если результат равен 3, то цикл будет 3->9->81->65->61->37->58->89->145-> ..... (Входит в цикл SAD).

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

Возможно, другие решения могут воспользоваться этим фактом.

На самом деле, результаты 5 и 6 также приводят к числам SAD, но это дает нам только повышение эффективности, а не преимущество в гольфе (я полагаю).

Edit 1 - 108 Chars/

Переработана логика управления контуром

 h = Print[
 NestWhile[Plus@@(IntegerDigits@#^2) &, #, #>4 &] /.{1 → "Happy",_→"Sad"}
 , If[PrimeQ@#, "", "не"]
 , "prime"] &

Оригинал - 115 Chars/

h = Print[
    If[NestWhile[Plus @@ (IntegerDigits@#^2) &, #, Unequal, All] == 1
        ,"Happy ", "Sad "],      
    If[PrimeQ@#, "", "non-"], "prime"] &

Оператор

NestWhile[Plus @@ (IntegerDigits@#^2) &, #, Unequal, All]

выполняет рекурсивное применение сумм цифр, возведенных в квадрат, пока не повторится некоторое значение. Часть "Unequal,All" выполняет сравнение по всему предыдущему списку значений. Наконец, возвращается повторяющееся значение, которое для "Счастливых чисел" равно "1".

Образец выполнения

h[7]
Happy prime
h[2535301200456458802993406410753]
Sad non-prime

Циклическая работа (незначительное изменение оператора Print)

1 Happy non-prime
2 Sad prime
3 Sad prime
4 Sad non-prime
5 Sad prime
6 Sad non-prime
7 Happy prime
8 Sad non-prime
9 Sad non-prime
10 Happy non-prime
11 Sad prime
12 Sad non-prime
13 Happy prime
29
ответ дан 7 November 2019 в 11:11
поделиться

J: 113 символов

h=.1=$:@([:+/[:*:@"."0":)`]@.(e.&1 4)
1!:2&2;(({&('sad ';'happy '))@h,({&('non-prime';'prime'))@(1&p:))".(1!:1]3)

$ echo -n 7 | jc happy.ijs
happy prime
$ echo -n 139 | jc happy.ijs
happy prime
$ echo -n 2 | jc happy.ijs
sad prime
$ echo -n 440 | jc happy.ijs
happy non-prime
$ echo -n 78 | jc happy.ijs
sad non-prime
4
ответ дан 7 November 2019 в 11:11
поделиться

GNU sed, 146 125 символов

Запускается с файлом sed -rf. Использование -r сохраняет 5 обратных косых черт.

Требуется bc , printf и оболочка с поддержкой здесь-строк.

h
s/^/printf %*s /e
s/^ $|^(  +)\1+$/non-/
s/ *$/prime/
x
:a
s/./+&*&/g
s//bc<<</e
tb
:b
s/^1$/happy/
s/^4$/sad/
Ta
G
s/\n/ /

GNU sed, 155 141 символ (не требуется ни printf, ни here-strings)

Использует более стандартный традиционный yes и head вместо printf .

h
:a
s/./+&*&/g
s/.*/echo 0&|bc/e
tb
:b
s/^1$/happy/
s/^4$/sad/
Ta
x
s/^/yes|head -/e
s/\n//g
s/^y$|^(yy+)\1+$/non-/
s/y*$/prime/
x
G
s/\n/ /

GNU sed, 134 115 символов (вывод с плохим форматированием)

Немного более короткая версия, не учитывает форматирование вывода (с дополнительными пробелами и новой строкой между счастливым / грустным и (не-) основной).

h
:a
s/./+&*&/g
s//bc<<</e
tb
:b
s/^1$/happy/
s/^4$/sad/
Ta
p
g
s/^/printf %*s /e
s/^ $|^(  +)\1+$/non-/
s/$/prime/
1
ответ дан 7 November 2019 в 11:11
поделиться

Python - 142 символа

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

n=input();L=[n];print"%s non-prime"[4*([1for f in range(1,n)if L.append(sum(int(x)**2for x in`L[-1]`))or n%f<1]==[1]):]%['sad','happy'][1in L]
1
ответ дан 7 November 2019 в 11:11
поделиться

Python, 169 168 158 157 166 164 162 символа, 4 строки

l=n=input()
while l>4:l=sum(int(i)**2for i in str(l))
print['sad','happy'][l==1and str(n)!=1],
print['non-',''][n!=1 and sum(n%i==0for i in range(1,n))<2]+"prime"

Берет число из стандартного ввода и не сбрасывает с регулярными выражениями, такими как другой ответ Python, хотя я должен признать, что это довольно круто. Я мог бы также сократить 6 символов, используя обратные кавычки вместо str-функции, но давайте поиграемся.

РЕДАКТИРОВАТЬ: Исправлена ​​ошибка, из-за которой 1 было простым числом, что увеличивало количество символов на 10. Я полагаю, что для этого должен быть более краткий способ, чем мой.

РЕДАКТИРОВАТЬ 2: Очевидно, python 2.6 позволяет печатать [1, 2] без пробела между ними.

РЕДАКТИРОВАТЬ 3: Использовано другое вычисление для счастливых чисел

1
ответ дан 7 November 2019 в 11:11
поделиться

Perl, 113 109 105 символов

Победа над всеми ответами Python на данный момент! ГКНР.

$n=$s=<>;$s=0,s/\d/$s+=$&*$&/ge while($_=$s)>4;die$s>1?sad:happy,$","non-"x(1x$n)=~/^1$|(^11+)\1+$/,prime
2
ответ дан 7 November 2019 в 11:11
поделиться

PHP 217 символов

$t=$argv[1];for($z=$t-1,$p=1;$z&&++$p<$t;)$z=$t%$p;$f=array(1);while(!in_array($t,$f,1)){$f[]=$t;$t=array_reduce(str_split($t),function($v,$c){return $v+=$c*$c;});}print($t<2?"happy ":"sad ").(!$z?"non-":"")."prime";

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

$ php -r '$t=$argv[1];for($z=$t-1,$p=1;$z&&++$p<$t;)$z=$t%$p;$f=array(1);while(!in_array($t,$f,1)){$f[]=$t;$t=array_reduce(str_split($t),function($v,$c){return $v+=$c*$c;});}print($t<2?"happy ":"sad ").(!$z?"non-":"")."prime";' 139
happy prime
2
ответ дан 7 November 2019 в 11:11
поделиться

C, 188 187 185 184 180 172 171 165

h(c,C,r,p){for(;C>1&&C%++p;);for(;c;c/=10)r+=c%10*(c%10);r&~5?h(r,C,0,1):printf(
"%s %sprime",r-1?"sad":"happy",p>=C&C>1?"":"non-");}main(c){h(c,c,0,scanf("%d",&c));}

$ ./a.out
139
happy prime

$ ./a.out
2
sad prime

$ ./a.out
440
happy non-prime

$ ./a.out
78
sad non-prime

Это один рекурсивная функция, которая никогда не возвращает return , но либо вызывает себя, либо выводит результат по завершении. Рекурсивная функция суммирует квадраты цифр и определяет простоту двух циклов for. Scanf возвращает 1 , который помещается в качестве аргумента в h () , сохраняя один ; и один 1 (и по цене из-за необходимости использовать префикс ++ p вместо постфикса p ++ , что сделало бы возможным p> C вместо p> = C )

r & ~ 5 равно 0 для 1 4 5 , из которых 1 указывает на счастье, а остальные - на печаль.

Следующая попытка: отбросить h () и сделать main () рекурсивным.

9
ответ дан 7 November 2019 в 11:11
поделиться

Python 2.6

happy.py: 280 314 333 символов, 14 строк.

import re
def q(z):
 while z!=1:z=sum((int(a)**2 for a in `z`));yield z
def h(g):
 l=[]
 while 1:
  try:z=g.next()
  except:return 'happy '
  if z in l:return 'sad '
  l.append(z)
p=lambda n:not re.match(r'^1$|^(11+?)\1+$','1'*n)
n=int(input())
print h(q(n))+'non-prime'[4*p(n):]

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

$ echo 139 | python happy.py
happy prime
$ echo 2 | python happy.py
sad prime
$ echo 440 | python happy.py
happy non-prime
$ echo 1234567 | python happy.py
sad non-prime

-

Читаемая версия:

import re, sys

def happy_generator(z):
    while z != 1:
        z = sum((int(a)**2 for a in str(z)))
        yield z

def is_happy(number):
    last = []
    hg = happy_generator(number)
    while True:
        try:
            z = hg.next()
        except StopIteration:
            return True

        if z in last:
            return False
        last.append(z)

def is_prime(number):
    """Prime test using regular expressions :)"""
    return re.match(r'^1?$|^(11+?)\1+$', '1'*number) is None

n = int(sys.argv[1])

print "%s %sprime" % (('sad','happy')[is_happy(n)], ('non-','')[is_prime(n)])
4
ответ дан 7 November 2019 в 11:11
поделиться

Perl, 140 символов

sub h{$_==1&& happy||$s{$_}++&& sad
||do{$m=0;$m+=$_**2for split//;$_=$m;&h}}$n=$_=pop;
die h,$",(1x$n)=~/^1?$|^(11+?)\1+$/&&"non-","prime\n"

Переносы строк необязательны.

8
ответ дан 7 November 2019 в 11:11
поделиться

Clojure, 353 318 298 261 230 символов

(defn h[x m](cond(= x 1)"happy "(m x)"sad ":else(recur(reduce +(for[n(map #(-(int %)48)(str x))](* n n)))(assoc m x 1))))(println(let [x (read)](str(h x{})(if(re-matches #"^1$|^(11+)?\1+"(apply str(repeat x\1)))"non-""")"prime")))

ptimac:clojure pti$ clj  happy.clj 139
CP=/Users/pti/playpen/clojure:/Users/pti/Library/Clojure/lib/clojure.jar:/Users/pti/Library/Clojure/lib/jline.jar:/Users/pti/Library/Clojure/lib/clojure-contrib.jar
happy prime
ptimac:clojure pti$ clj  happy.clj 440
CP=/Users/pti/playpen/clojure:/Users/pti/Library/Clojure/lib/clojure.jar:/Users/pti/Library/Clojure/lib/jline.jar:/Users/pti/Library/Clojure/lib/clojure-contrib.jar
happy non-prime
ptimac:clojure pti$ clj  happy.clj 2
CP=/Users/pti/playpen/clojure:/Users/pti/Library/Clojure/lib/clojure.jar:/Users/pti/Library/Clojure/lib/jline.jar:/Users/pti/Library/Clojure/lib/clojure-contrib.jar
sad prime
ptimac:clojure pti$ clj  happy.clj 78
CP=/Users/pti/playpen/clojure:/Users/pti/Library/Clojure/lib/clojure.jar:/Users/pti/Library/Clojure/lib/jline.jar:/Users/pti/Library/Clojure/lib/clojure-contrib.jar
sad non-prime

Я полагаюсь на clojure contrib для последовательности простых чисел. Интересно, будет ли использование циклов for короче, чем рекурсия?

Я читал о проверке простых чисел в регулярном выражении. Это потрясающе и удаляет 30 символов и мою зависимость от clojure.contrib. Я также провел рефакторинг синтаксического анализа командной строки и встроил функцию.

Pre golf(несколько устаревшее):

(defn h[x m]
  (cond
   (= x 1) "happy "
   (m x) "sad "
   :else (recur
               (reduce +
                 (for [n (map #(- (int %) 48) (str x))] (* n n))) 
               (assoc m x 1))))

    (println
      (let [x (read)]
        (str
           (h x{})
           (if (re-matches #"^1$|^(11+)?\1+"(apply str(repeat x \1)))
             "non-"
             "")
           "prime")))
2
ответ дан 7 November 2019 в 11:11
поделиться

Javascript 244 250

function h(n){p=n=n<2?10:n;a=",";w="";s=[];while((y=a+s.join(a)+a).indexOf(a+n+a)<0){s.push(n);k=""+n;n=0;for(i=0;i<k.length;)c=k.charAt(i++),n+=c*c}w+=y.indexOf(",1,")<0?"sad ":"happy ";for(i=2;i<p;)p=p%i++?p:0;w+=p?"":"non-";return w+"prime"}

Приведенный выше код должен работать в браузерах без дополнительных причудливых функций и возможностей (таких как Array.prototype.indexOf и [] нотация для строк), но я не тестировал его вне Firefox.

Имейте в виду, что все, кроме n, являются глобальными переменными (я просто шучу).

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

h(139) // returns "happy prime"
5
ответ дан 7 November 2019 в 11:11
поделиться

Ruby 1.9

169 168 146 символов

 h={1=>'happy'};s=->x{y=0;(y+=(x%10)**2;x/=10)while x>0;h[y]||(h[y]='sad';s[y])}
 $><<s[n=$*[0].to_i]+" #{'non-'if '1'*n=~/^1?$|^(11+?)\1+$/}prime"

Если мы используем p вместо $><<, код сокращается на 2 символов

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

$ ruby ​​happyprime.rb 139 счастливый премьер $ рубиновый happyprime.rb 2 sad prime


Не в гольфе:

hash = {1->'happy'}
is_happy = lambda do |number|
  #sum = number.scan(/\d/).reduce(0){|acum, digit| acum + digit.to_i ** 2 }
  sum=0; 
  while (number > 0)
      sum+= (number%10)**2
      number/=10
  end
  return hash[sum] if hash[sum] # If 1, or if cycled and hash contains the number already
  h[sum] = 'sad'
  return is_happy.call(sum)
end
number = ARGV[0].to_i
string = ""
string += is_happy.call(number) # either 'happy' or 'sad'
string += is_prime(number) ? " non-prime" : "prime"
puts string

где метод is_prime оставлен читателю в качестве упражнения ;)

5
ответ дан 7 November 2019 в 11:11
поделиться

Javascript, 192 190 185 182 165 158 символов

Проверка простых чисел выполняется от 2 до квадратного корня из Н. Я потратил там несколько символов...

В одну строку:

for(x=2,y=m=n=prompt();x*x<y&&n%x++;);for(s={};!s[m];m=p)for(s[m]=1,p=0;m;m=(m-=k=m%10)/10,p+=k*k);alert((m-1?'sad':'happy')+(n-1&&x*x>y?' ':' non-')+'prime')

Отформатировано:

// Getting the number from the input and checking for primeness
// (ie. if after the loop x>y => n is prime)
for (x=2, y=m=n=prompt(); x*x<y && n%x++;)

// Checking for happiness
// the loop is broken out of if m is already encountered
// the m==1 after the loop indicates happy number
for(s={}; !s[m]; m=p)
    for (s[m]=1, p=0; m; m=(m -= k=m%10)/10, p+=k * k);

alert((m-1 ? 'sad' : 'happy') + (n-1 && x*x>y ? ' ' : ' non-') + 'prime')

Проверить: http://jsfiddle.net/TwxAW/6/

2
ответ дан 7 November 2019 в 11:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: