Сегодня воскресенье, время для игры в гольф с кодом!
Напишите кратчайший исходный код по количеству символов, чтобы определить, является ли входное число «счастливым простым», «грустным простым», «счастливым непростым» или «грустным непростым».
Входными данными должно быть целое число, полученное из аргумента командной строки или стандартного ввода. Не беспокойтесь об обработке больших чисел, но сделайте это, если можете / хотите. Поведение будет неопределенным для входных значений меньше 1, но 1 дает определенный результат.
Выходные данные должны вывести тип числа: «счастливое простое», «грустное простое», «счастливое непростое» или «грустное непростое». Завершающий символ новой строки необязательно .
$ happyprime 139
happy prime
$ happyprime 2
sad prime
$ happyprime 440
happy non-prime
$ happyprime 78
sad non-prime
На всякий случай, если вашему мозгу нужно освежить память.
Из Википедии,
Счастливое число определяется следующим процессом. Начиная с любого положительного целого числа , замените число суммой квадратов его цифр и повторяйте процесс до тех пор, пока число не станет равным 1 (где он будет оставаться), или он будет бесконечно повторяться в цикле , который не включает 1.Те числа , для которых этот процесс заканчивается на 1, являются счастливыми числами, а те, которые не заканчиваются на 1, являются несчастливыми числами (или грустными числами).
Например,
простое число является целым числом больше, чем 1 и имеет ровно два делителя: 1 и себя.
Счастливое простое число - это одновременно и счастливое, и простое число.
Очевидно, ответом будет самый короткий исходный код по количеству символов, который выводит указанные результаты во всех тестируемых мной случаях. Я отмечу ответ, как только появится следующая (решенная сообществом) задача по игре в гольф с кодом, чтобы мы могли сосредоточить всю нашу энергию на ней. :)
Что ж, похоже, что в городе появился новый код для гольфа, и с момента публикации этого вопроса прошла около недели, поэтому я отметил самый короткий исходный код как ответ (gnibbler's 64 символа Решение Golfscript ). Тем не менее, мне понравилось как решение для 99 символов Mathematica от Belisarius, так и решение для загадочных 107 символов dc от Nabb.
Всем остальным, отличная работа! На моем компьютере никогда не было столько языковых сред программирования. Я надеюсь, что каждый научился новым пакостям для своего любимого языка.
Я повторно опубликовал часть кода, созданного в ходе этого конкурса, в качестве примера сценария, который я написал для тестирования различных программ по сравнению с эталонной реализацией для автоматической оценки . README в этом каталоге объясняет, откуда берется исходный код, и заявляет, что весь код повторно используется под лицензией CC BY-SA 2.5 (как указано в правовом разделе SO ). Каждый каталог помечен вашим отображаемым именем во время отправки.
Если у вас есть проблема с повторным использованием вашего кода таким образом или с указанием авторства, дайте мне знать, и я исправлю ошибку.
~:@.{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">
В отличие от предыдущего ответа, здесь не используется регулярное выражение.
Я уверен, что есть способ сократить мою функцию 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'
#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.
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
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
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 символов: - (
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"")
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
Пробелы, новые строки и комментарии добавлены для удобства чтения
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'])
Автор заменив рекурсивную функцию вложенными циклами, я смог довести количество штрихов до приличных 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)
);
}
}
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 символа, но я предпочитаю его не использовать.
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 на данный момент!
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 размера!
Обновление 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-");
}
}
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
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]
Достаточно девяти итераций. Спасибо @Nabb, @mjschultz
h = Print[
If[Nest[Plus @@ (IntegerDigits@#^2) &, #, 9] > 1, "Sad ", "Happy "]
, If[PrimeQ@#, "", "non-"], "prime"] &
То же самое, что и Edit 3, заменяя 10^2 на 99 (разрешая 84 цифры для входных значений) ... Спасибо, @Greg
h = Print[
If[Nest[Plus @@ (IntegerDigits@#^2) &, #, 99] > 1, "Sad ", "Happy "]
, If[PrimeQ@#, "", "non-"], "prime"] &
Переработал цикл еще раз.
Интересно, что глубина рекурсии до достижения 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
Переработано задание 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, но это дает нам только повышение эффективности, а не преимущество в гольфе (я полагаю).
Переработана логика управления контуром
h = Print[
NestWhile[Plus@@(IntegerDigits@#^2) &, #, #>4 &] /.{1 → "Happy",_→"Sad"}
, If[PrimeQ@#, "", "не"]
, "prime"] &
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
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
Запускается с файлом 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/ /
Использует более стандартный традиционный 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/ /
Немного более короткая версия, не учитывает форматирование вывода (с дополнительными пробелами и новой строкой между счастливым / грустным и (не-) основной).
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/
Я экспериментировал с этой идеей, но это оказалось слишком долго. Возможно, кто-нибудь найдет способ сделать его короче. Может, на Руби получится лучше. В любом случае, должно быть интересно понять, как это работает :)
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]
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: Использовано другое вычисление для счастливых чисел
Победа над всеми ответами 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
$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
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 ()
рекурсивным.
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)])
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"
Переносы строк необязательны.
(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")))
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"
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
оставлен читателю в качестве упражнения ;)
Проверка простых чисел выполняется от 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/