Код Гольф: Счастливое время!

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

Вызов

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

вход

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

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

Выбор ответа

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

Решение

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

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

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

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

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

33 ответа

Решение

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

постоянный ток - 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

Mathematica 115 108 107 102 100 99 91 87 символов


87 персонажей

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

- мистер Волшебник


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

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

Вызвать с%[7]

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

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

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

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

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

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

Изменить 3 - 102 символов /

Снова переработан цикл.

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

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

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

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

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

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

Переработано задание 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", число "Happy", а когда "4", это "Sad".

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

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

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

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

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

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

Переработана логика Loop Control

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

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

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

Заявление

NestWhile[Plus @@ (IntegerDigits@#^2) &, #, 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

Питон - 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, и он составляет чуть более половины размера!

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

С 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 за 145, из которых 1 указывает на счастье и грусть других.

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

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

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

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"

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

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

Рубин 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 happy prime $ ruby ​​happyprime.rb 2 грустный премьер


Не гольф:

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

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"

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

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


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

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

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

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

  • Обновление 5: заменено регулярное выражение на цикл 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-");
 }
}

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

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

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

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

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

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.

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

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/

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

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. Я также немного переработал командную строку и добавил функцию.

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

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

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

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

Python (285270269246241247240 237 символов, 21202118 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

Питон - 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]

PARI / GP

184 байта

Немного опоздал на участие, но вот короткий.

a(x,v=[])=s=0;while(x,s+=(x%10)^2;x\=10);for(k=1,length(v),if(v[k]==s,return("sad ")));return(if(s==1,"happy ",v=concat(v,s);a(s,v)));f(x)=print(a(x),if(!isprime(x),"non-",""),"prime")

Чтобы использовать это. Написать f(139)

Python 2.6, 300298 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'

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-строк)

Использует более стандартный традиционный 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/
Другие вопросы по тегам