49

日曜日、コードゴルフのラウンドです!

チャレンジ

入力数値が「ハッピー素数」、「サッド素数」、「ハッピー非素数」、「サッド非素数」のいずれであるかを判断するために、文字数で最短のソース コードを記述します。

入力

入力は、コマンド ライン引数または stdin からの整数である必要があります。大きな数を扱うことを心配する必要はありませんが、できる/したい場合はそうしてください。入力値が 1 未満の場合の動作は未定義ですが、1 には明確な結果があります。

出力

出力は、数値のタイプを出力する必要があります: 「幸せな素数」、「悲しい素数」、「幸せな非素数」、または「悲しい非素数」。末尾の改行はオプションです。

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

定義

脳にリフレッシュが必要な場合に備えて。

ハッピーナンバー

ウィキペディアから、

ハッピーナンバーは以下のプロセスで定義されます。任意の正の整数から始めて、数値をその桁の 2 乗の合計で置き換え、数値が 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より大きい整数で、正確に 2 つの約数 (1 とそれ自体) があります。

ハッピープライム

したがって、幸せな素数は、幸せで素数でもある数です。

回答の選択

明らかに、答えは、私がテストしたすべてのケースで指定された結果を出力する、文字数による最短のソース コードになります。次の (コミュニティが決定した) コード ゴルフ チャレンジが来たら、答えをマークします。:)

決断

さて、町に新しいコード ゴルフがあるようで、この質問が投稿されてから約 1 週間が経過したので、最短のソース コードを回答としてマークしました (gnibbler の 64 文字のGolfscriptソリューション)。そうは言っても、 belisarius による99 文字のMathematicaソリューションと Nabb による不可解な 107 文字のdcソリューションの両方を楽しみました。

他の皆さん、おつかれさまでした!私のコンピューターには、これほど多くのプログラミング言語環境がありませんでした。誰もがお気に入りの言語の新しい汚いトリックを学んでくれたことを願っています。

再利用

自動採点のリファレンス実装に対してさまざまなプログラムをテストするために書いたスクリプトの例として、このコンテストで作成されたコードの一部を再公開しました。そのディレクトリの README には、ソース コードの入手元が説明されており、すべてのコードが CC BY-SA 2.5 ライセンスの下で再利用されていることが記載されています (SO の法的なセクションに記載されているとおり)。各ディレクトリには、送信時の表示名が付けられます。

あなたのコードがこのように再利用されたり、帰属に問題がある場合は、お知らせください。エラーを修正します。

4

33 に答える 33

67

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
于 2010-08-23T01:45:21.870 に答える
29

Mathematica 115 108 107 102 100 99 91 87 文字


87文字

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

-- ミスターウィザード


Da monkey はいくつかのトリックを学びました (91 文字)

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

%[7] で呼び出す

編集 5 - 99 文字/

9回の繰り返しで十分です。ありがとう@Nabb、@mjschultz

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

編集 4 - 100 文字/

編集 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桁未満の数字の場合(この制限は、OPの「大きな数字の処理について心配しないでください」の考慮事項にかなり適していると思います)、次のコードが機能します

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」の場合は数字が「嬉しい」、結果が「4」の場合は「悲しい」ということになります。

結果が「2」の場合、次の反復で SAD サイクルに入る (2^2 = 4) ため、その数値も SAD です。

結果が 3 の場合、サイクルは 3->9->81->65->61->37->58->89->145-> .... (SAD ループに入る)。

したがって、結果が 4 以下の場合は再帰を停止できます。これは、"1" の結果のみがハッピー ナンバーにつながることがわかっているためです。

おそらく、他のソリューションがこの事実を利用する可能性があります。

実際、結果 5 と 6 も SAD の数値につながりますが、それは効率の向上のみをもたらし、ゴルフの利点にはなりません (私は推測します)。

編集 1 - 108 文字/

ループ制御ロジックを作り直しました

    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]

ある値が繰り返されるまで、二乗した数字の和を再帰的に適用します。"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
于 2010-08-23T01:18:05.403 に答える
19

GolfScript-64文字(1で動作)

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

このプログラムはn、数字の幸福を判断するために反復を行います。これは、大きな数字の場合は非常に無駄ですが、コードゴルフは文字以外のリソースを節約することではありません。プライムテストも同様に非効率的です。からのnすべての値で除算し、余りがゼロの値が正確に2つあることを確認します。したがって、理論的には正しいのですが、実際のコンピューターで実際に多数を実行することは実用的ではありません。1n

GolfScript-63文字(1で失敗)

~:@9{0\`{15&.*+}/}*1=!"happy sad "6/=@,2>{@\%!},!4*"non-prime">
于 2010-08-24T13:22:26.677 に答える
13

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 強になりました。

于 2010-08-23T18:13:59.680 に答える
12

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)
            );
    }
}
于 2010-08-23T01:47:12.323 に答える
9

C 、188187185184180172171165 _ _ _ _ _ _

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これは、を発行することはないが、それ自体を呼び出すか、実行時に出力を出力する再帰関数の1つです。再帰関数は、2乗の数字を合計し、2つのforループの素数を決定します。scanfは1、引数として置かれたものを返し、 1つとh()1つを節約します(そして、postfixの代わりにprefixを使用する必要があり、代わりに可能になります);1++pp++p>Cp>=C

r&~50ため1 4 5のものであり、そのうちの1幸福と他の悲しみを示しています。

次の試み:ドロップh()してmain()再帰的にします。

于 2010-08-23T00:16:35.437 に答える
9

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'

lexer がそれぞれ 2 つのトークンに分割できること0if2for、私にとってうれしい驚きでした :) (ただし、これは機能しませんelse)

関数s(sad) は再帰的で、2 番目のパラメーターとしてサイクル内の前の数値のリストを受け取ります。素数性は、 regexp トリックを使用してインラインでテストされます。

の代わりに非推奨の`n`構文を使用str(n)すると、文字数をさらに 4 文字減らすことができますが、私は使用しないことにしました。

于 2010-08-23T02:52:31.583 に答える
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"

改行はオプションです。

于 2010-08-23T01:23:20.520 に答える
7

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'])
于 2010-08-23T19:06:56.083 に答える
5

Ruby 1.9

169168146 文字_

 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.rb139ハッピープライム$rubyhappyprime.rb2悲しいプライム


ゴルフ以外:

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メソッドが読者の練習問題として残されている場合;)

于 2010-08-22T23:43:57.750 に答える
5

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"
于 2010-08-23T04:52:12.077 に答える
5

ハスケル 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
于 2010-08-23T03:30:10.917 に答える
4

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)])
于 2010-08-23T00:13:23.167 に答える
4

Java :294 286 285 282 277262260 文字


  • アップデート1 :正規表現に置き換えられましBigInteger#isProbablePrime()た。8文字節約しました。

  • アップデート2 : (oops)に置き換えられまし&&た。&1文字保存しました。

  • アップデート3s :少しリファクタリング。3文字保存しました。

  • アップデート4:テストn!=1は不要でした。5文字保存しました。

  • アップデート5:正規表現をforループに置き換え、幸せなforループを少しリファクタリングしました。15文字節約しました。

  • アップデート6:に置き換えられましint/Integerlong/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-");
 }
}
于 2010-08-23T00:57:18.803 に答える
4

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
于 2010-08-23T22:03:11.907 に答える
3

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 への過剰な呼び出しを削除するために再配置されました。

于 2010-08-23T06:01:35.497 に答える
3

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
于 2010-08-23T17:35:49.517 に答える
3

パール、135℃

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

CPerlの組み合わせ

于 2010-08-23T02:01:06.310 に答える
3

VBA 245 文字

良いスターターです。時間が許せばトリミングします。コードゴルフは2回目!

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
于 2010-08-23T14:43:45.187 に答える
2

Javascript 、192190185182165158 文字_ _ _

プライムチェックは、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/

于 2010-08-24T12:02:54.317 に答える
2

スカラ、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 文字かかります :-(

于 2010-08-23T07:37:47.663 に答える
2

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"")
于 2010-08-23T02:26:45.830 に答える
2

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
于 2010-08-24T00:25:11.147 に答える
2

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
于 2010-08-24T19:11:39.620 に答える
2

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")))
于 2010-08-23T01:56:27.770 に答える
1

GNU sed、146125文字

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を使用します。headprintf

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/
于 2010-08-25T17:40:58.407 に答える
1

Python 2.6、300 298294文字

これは正規表現を使用しないという点で前の回答とは異なります。

関数を短くする方法はあると思い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'
于 2010-08-23T01:36:22.457 に答える
1

パイソン (285 270 269 246 241 247 240237文字、21 20 21 1819行)

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

于 2010-08-23T02:34:09.127 に答える
1

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の回答のように正規表現をいじくり回しませんが、それはかなりクールだと認めざるを得ません。str 関数の代わりにバッククォートを使用して 6 文字を削減することもできますが、うまくやりましょう。

編集: 1 が素数であるというバグを修正しました。これにより、charcount が 10 増えました。

編集 2:どうやら、python 2.6 ではprint[1, 2]、2 つの間にスペースを入れなくてもかまいません。

編集 3:ハッピー ナンバーに別の計算を使用

于 2010-08-23T14:08:04.293 に答える
1

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]
于 2010-08-25T01:30:46.670 に答える
1

パリ/グランプリ

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)

于 2010-10-18T12:51:43.493 に答える
0

ラケット、286 文字

唯一の問題は、1 が素数であることです。

(define d
  (lambda (n)
    (cond
      ((= n 0) 0)
      ((+
       (expt (modulo n 10) 2)
       (d (floor (/ n 10)))
       ))
      )
    )
  )

(define dd
  (lambda (n l)
    (cond
      ((= n 1) "happy ")
      ((for/or ([v l]) (= n v)) "sad ")
      ((dd (d n) (cons n l)))
      )
    )
  )

(define cg
  (lambda (n)
    (display (dd n '()))
    (display
    (if
     (for/and
       ([i (in-range 2 (floor (+ (sqrt n) 1)))]) (> (modulo n i) 0))
       "prime" "non-prime"
     ))
    )
  )
于 2010-09-18T21:16:10.693 に答える
0

JavaScript - 171 (Closure Compiler Compressed)

この楽しい課題を見つけました。これは JavaScript では 171 文字です。

function h(a){for(b=2,c="";b<a;b++)a%b||(c="non-");c+="prime";for(b={};;){if(a==1)return"happy "+c;if(b[a])return"sad "+c;b[a]=1;for(e=0;a;){d=a%10;e+=d*d;a=(a-d)/10}a=e}}

ソース コードを圧縮するために、Closure CompilerAdvanced Mode で実行しました。起源:

function h(num)
{
    // Check for prime-ness
    // Save the word "prime" by attaching a "non-" in front if it has a factor
    // Notice that we are not concerned with performance here, otherwise should
    // break when a factor is found and should only go up to Math.sqrt(num)

    for (var x=2, prime=""; x < num; x++) {
        if (!(num % x)) prime="non-";
    }

    // Create "prime" or "non-prime"

    prime += "prime";

    // Keep all visited numbers in a hash

    var visited = {};

    while(true) {
        // If the number is one, then happy
        if (num == 1) return "happy " + prime;

        // Otherwise put it into the hash
        if (visited[num]) return "sad " + prime;
        visited[num] = 1;

        // Recalculate the new number by shifting through each digit
        var sum = 0;
        while (num) {   // Stop when num -> 0 (i.e. no more digits)
            var digit = num % 10;
            sum += digit * digit;
            num = (num - digit)/10; // Shift by one digit
        }

        num = sum;
    }
}
于 2011-04-26T08:36:03.570 に答える