Подтвердить что ты не робот

Code Golf: Счастливые Primes!

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

Проблема

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

Ввод

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

Выход

Вывод должен печатать тип числа: "счастливое правое", "грустное простое", "счастливое не-простое" или "печальное не-простое". Конечная новая строка необязательна.

Примеры

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

Определения

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

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

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

A счастливое число определяется следующий процесс. Начиная с любого положительное целое число, замените число на сумму квадратов его цифр и повторить процесс до тех пор, пока число равно 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

Основной номер

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

Happy Prime

Счастливое правое число, следовательно, является числом, которое является счастливым и простым.

Выбор ответа

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

Решение

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

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

Многократное

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

dc - 98 символов

$ cat happyprimes
[happy][sad]?dsI[[I~d*rd0<H+]dsHxd4<h]dshx[r]sr1=rP[ ][ non-]_1lI[1-d2>rdlIr%0<p]dspx-2=rP[prime]p
$ echo 1  |dc happyprimes
happy non-prime
$ echo 139|dc happyprimes
happy prime
$ echo 2  |dc happyprimes
sad prime
$ echo 440|dc happyprimes
happy non-prime
$ echo 78 |dc happyprimes
sad non-prime

Ответ 3

Mathematica 115 108 107 102 100 99 91 87 Chars


87 символов

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

- Mr.Wizard


Да обезьяна узнала несколько трюков (91 символ)

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

Вызвать          % [7]

Изменить 5 - 99 символов /

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

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

Изменить 4 - 100 символов /

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

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

Редактировать 3 - 102 символа /

Переработал цикл снова.

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

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

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

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

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

Изменить 2 - 107 символов /

Переработано назначение "Сад/Счастливое"

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

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

Пояснение:

    NestWhile[Plus @@ ([email protected]#^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, но это дает нам только повышение эффективности, а не преимущество в гольф (я думаю).

Изменить 1 - 108 символов /

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


    h = Print[
        NestWhile[[email protected]@([email protected]#^2) &, #, #>4 &] /.{1 →"Happy ",_→"Sad "}
          , If[[email protected]#, "", "non-"]
          , "prime"] &

Оригинал - 115 символов /

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

Утверждение

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

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

Пример прогона

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

Looping (слегка изменяя оператор печати)

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

Ответ 4

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 размера!

Ответ 5

С#, 380 378 374 372 364 363 315 280 275 274 Chars

Заменив рекурсивную функцию вложенными циклами, я смог довести количество инсульта до респектабельного 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)
            );
    }
}

Ответ 6

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, но либо сама вызывает, либо выводит вывод, когда это делается. Рекурсивная функция суммирует квадратные цифры и определяет простоту в двух для циклов. Scanf возвращает 1, который помещается в качестве аргумента в h(), сохраняя один ; и один 1 (и за счет использования префикса ++p вместо postfix p++, который сделает p>C возможно вместо p>=C)

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

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

Ответ 7

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 (печально) является рекурсивной и получает список предыдущих чисел в цикле в качестве второго параметра. Primality тестируется inline с помощью тэга regexp.

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

Ответ 8

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"

Линейные разрывы являются необязательными.

Ответ 9

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

Ответ 10

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 счастливый премьер $ ruby ​​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 оставлен в качестве упражнения для читателя;)

Ответ 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

Ответ 12

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"

Ответ 13

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

Ответ 14

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


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

  • Обновить 2: заменить && на & (oops). Сохранено 1 char.

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

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

  • Обновление 5: заменено регулярное выражение для цикла и реорганизовано счастливым для небольших циклов. Сохранено 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-");
 }
}

Ответ 15

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

Ответ 16

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

Ответ 17

С++, 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.

Ответ 18

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

Ответ 19

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

Ответ 20

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 для последовательности простых чисел. Интересно, будет ли использование циклов для циклов короче рекурсии?

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

Предварительный гольф (несколько устаревший):

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

Ответ 21

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

Ответ 22

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 символов: - (

Ответ 23

Шаблоны 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

Ответ 24

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

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

В одной строке:

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/

Ответ 25

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

Избиение всех ответов Python в данный момент! SCNR.

$n=$s=<>;$s=0,s/\d/$s+=$&*$&/ge while($_=$s)>4;die$s>1?sad:happy,$","non-"x(1x$n)=~/^1$|(^11+)\1+$/,prime

Ответ 26

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'

Ответ 27

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

РЕДАКТИРОВАТЬ: Да, число увеличилось, появилась ошибка: -P

Ответ 28

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"

Принимает число из stdin и не сбрасывает с регулярными выражениями, как и другие ответы на python, хотя я должен признать, что это довольно круто. Я мог бы также сбрить 6 символов, используя backticks вместо str-функции, но позволяю играть хорошо.

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

EDIT 2: Очевидно, что python 2.6 позволяет print[1, 2] без пробела между ними.

EDIT 3: Используется другой расчет для счастливых номеров

Ответ 29

Python - 142 символа

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

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]

Ответ 30

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, ни здесь-строки)

Использует <<статический > <<статический > << → 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 символов (слегка плохо отформатированный вывод)

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

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/