Bir numaranın mutlu olup olmadığını mı arıyorsunuz?


21

Mutlu bir sayı aşağıdaki işlem ile tanımlanır. Olumlu bir tamsayı ile başlayarak, sayıyı basamaklarının karelerinin toplamı ile değiştirin ve sayı 1'e (burada kalacağı yere kadar) eşit olana kadar işlemi tekrarlayın veya 1'i içermeyen bir döngüde bitmeden durur. Bu sayılar Bunun için 1'de bitenler mutlu sayılardır, 1'de bitmeyenler mutsuz sayılardır (ya da üzgün sayılardır). Bir sayı verilirse, mutlu ya da mutsuz olup olmadığını yazdırın.

Sample Inputs
7
4
13

Sample Outputs
Happy
Unhappy
Happy

Not: Programınız 1.000.000.000'in altındaki herhangi bir sayı için 10 saniyeden fazla sürmemelidir.

Yanıtlar:


8

Golfscript - 34 karakter

~{0\`{48-.*+}/}9*1="UnhH"3/="appy"

Temelde bu ve bu aynı .

9 yinelemenin nedeni bu yorumlarda açıklanmaktadır (bu teorik olarak yaklaşık 10^10^10^974( A001273 ) 'e kadar doğru değerleri verir ).


11

Ruby, 77 karakter

a=gets.to_i;a=eval"#{a}".gsub /./,'+\&**2'until a<5
puts a<2?:Happy: :Unhappy

Tamam, bu yüzden nasıl çalıştığını anlıyorum (kelimenin tam anlamıyla her sayıyı almak, bölmek ve her basamağın karesini eklemek), ama (a <5) 'in durma koşulu olan ve mutlu olup olmadığına karar vermek için (a <2) kullanarak ya da değil? Geçerliliği sorgulamıyorum, sadece mantığı.
Bay Llama,

2
Yani aynıdır a <= 4ve a <= 1. Döngünün içinde 1 varsa, mutlu olur ve içinde 4 varsa, mutlu olmaz. Mutsuz döngüsü hakkında wikipedia bölümüne bakın . Yani değeri a4 ya da daha az olduğunda, o olup olmadığını kontrol eder - bunun sonucu sizin cevabınızdır.
Casey,

8

C - 115

char b[1<<30];a;main(n){for(scanf("%d",&n);b[n]^=1;n=a)for
(a=0;a+=n%10*(n%10),n/=10;);puts(n-1?"Unhappy":"Happy");}

Bu , döngüde hangi sayılarla karşılaşıldığını takip etmek için bitmap olarak 2 30 baytlık (1 GB) bir dizi kullanır . Linux'ta, bu aslında işe yarıyor ve verimli bir şekilde çalışıyor, bellek devredışı bırakma özelliği etkinleştirilmişse (genellikle varsayılan olarak). Aşırı taahhüt ile, dizinin sayfaları talep üzerine tahsis edilir ve sıfırlanır.

Bu programı Linux'ta derlemenin bir gigabayt RAM kullandığını unutmayın.


1
Bu problem için neden bu kadar fazla belleğe ihtiyaç duyuyorsunuz?
Peter Olson

1
@Peter: Yaklaşımın (naif olarak) izin verilen giriş aralığındaki herhangi bir sayı için 1 ila 1,000,000,000 arasında bir döngü yakalaması olduğunu düşünüyorum. Ancak, mutlu sayı teorisi ışığında, gerekli olan tek kontrolün, 4 numaralı sayıya ulaşılması gerektiğidir, çünkü gerçekleşecek olan tek döngü budur.
mellamokb

Merak ediyorum: neden derlemek bu kadar RAM gerektiriyor?
Peter Taylor

1
MSVC 10 ile Windows 7'de iyi çalıştığı görülüyor. Derleme sırasında kayda değer miktarda bellek tüketmiyor ve yalnızca sayfa dosyasındaki diziyi işaretliyor (bellek devirmek için önerdiğiniz hikayeden çok daha güvenli bir şey;;) .
Joey

1
Bu yaklaşımın saflığını seviyorum. Ve döngüler için kötüye kullanılması çok güzel.
dmckee

6

Haskell - 77

f 1="Happy"
f 4="Unhappy"
f n=f$sum[read[c]^2|c<-show n]
main=interact$f.read

6

Golfscript, 49 43 41 40 39 karakter

~{0\10base{.*+}/.4>}do(!"UnhH"3/="appy"

Her mutlu sayı 1'e yakınlaşır; her mutsuz sayı 4 içeren bir çevrime yaklaşır. Bu gerçeği kullanmaktan başka, bu ancak zorlukla golf oynamaktadır.

(Ruby çözümünden bir numara attığım ve 6 karakter biriktirdiğim Ventero sayesinde).


5

eTeX, 153

\let~\def~\E#1{\else{\fi\if1#1H\else Unh\fi appy}\end}~\r#1?{\ifnum#1<5
\E#1\fi~\s#1{0?}}~\s#1{+#1*#1\s}~~{\expandafter\r\the\numexpr}\message{~\noexpand

etex filename.tex 34*23 + 32/2 ?(Sonunda soru işareti dahil) olarak adlandırılır . İfadedeki boşluklar önemli değil.

EDIT: 123'e düştüm , ama şimdi çıktı dvi (derlenmişse etex) veya pdf (derlenmişse pdfetex). TeX dizgi dili olduğu için, bunun adil olduğunu düşünüyorum.

\def~{\expandafter\r\the\numexpr}\def\r#1?{\ifnum#1<5 \if1#1H\else
Unh\fi appy\end\fi~\s#1{0?}}\def\s#1{+#1*#1\s}~\noexpand

4

Python - 81 karakter

n=input()
while n>4:n=sum((ord(c)-48)**2for c in`n`)
print("H","Unh")[n>1]+"appy"

Ventero ve Peter Taylor'dan alınan bazı ilham kaynakları.


2
Bir yapmanın daha iyi int(c)daha ord(c)-48....
st0le

4

Javascript ( 94 92 87 86)

do{n=0;for(i in a){n+=a[i]*a[i]|0}a=n+''}while(n>4);alert(['H','Unh'][n>1?1:0]+'appy')

İstenilen sayıya a ile giriş yapılır.

Mellamokb için kredi.


1 karakter n==4?h="Unh":n==1?h="H":a=n+""}alert(h+"appy")
tasarruf edin

@mella Teşekkürler. Ben de değiştirerek başka kömürü tıraş ||etmek |.
Peter Olson

8 karakter kaydet: Kaldır n==4?h.... Koşulları ile döngü yaparken yapmak için ... değiştirin while(n>4). O zaman bunun yerine bu son ifadeyi kullanın:alert(["H","Unh"][n>1?1:0]+"appy")
mellamokb

@Mella Clever, beğendim.
Peter Olson

@Mella n, döngüden önce tanımlanmalı, tekrar etmemeyi düşünmeye çalışıyorumn=0;
Peter Olson

4

Python (98, ancak paylaşılmayacak kadar berbat)

f=lambda n:eval({1:'"H"',4:'"Unh"'}.get(n,'f(sum(int(x)**2for x in`n`))'))
print f(input())+"appy"

Yol, rekabetçi olmak için çok uzun, ama belki bir gülmek için iyi. Python'da "tembel" değerlendirme yapar. Gerçekten şimdi Haskell girişine oldukça benzer, bunun hakkında bir tılsım olmadan düşünüyorum.


4

dc - 47 karakter

[Unh]?[[I~d*rd0<H+]dsHxd4<h]dshx72so1=oP[appy]p

Kısa açıklama:

I~: Bölüm 10'a bölünürken bölümü ve kalanı al: Kalanı
d*kare.
0<H: Bölüm 0'dan büyükse, tekrarlı şekilde tekrarlayın.
+: Özyinelemeli yığını küçültürken değerleri toplayın.

4<h: Değer 4'ten büyük iken kareler toplamını bitini tekrarlayın.


4

Befunge, 109

1 <= n <= 10 9 -1 için doğru değerleri döndürür .

v v              <   @,,,,,"Happy"<      >"yppahnU",,,,,,,@
>&>:25*%:*\25*/:#^_$+++++++++:1-!#^_:4-!#^_10g11p

3

J, 56

'Happy'"_`('Unhappy'"_)`([:$:[:+/*:@:"."0@":)@.(1&<+4&<)

Soru belirsiz olduğundan bağımsız bir komut dosyası yerine bir fiil.

Kullanımı:

   happy =: 'Happy'"_`('Unhappy'"_)`([:$:[:+/*:@:"."0@":)@.(1&<+4&<)
happy =: 'Happy'"_`('Unhappy'"_)`([:$:[:+/*:@:"."0@":)@.(1&<+4&<)
   happy"0 (7 4 13)
happy"0 (7 4 13)
Happy  
Unhappy
Happy  

3

Scala, 145 karakter

def d(n:Int):Int=if(n<10)n*n else d(n%10)+d(n/10)
def h(n:Int):Unit=n match{
case 1=>println("happy")
case 4=>println("unhappy")
case x=>h(d(x))}

1
(n*n)Gibi daha kısa olmaz mıydı n*n yoksa boşluk bir if ifadesini ayırmak için yeterli değil elsemi?
Peter Taylor

Evet, yaptım Peter.
kullanıcı bilinmeyen

Desen eşleşmesi olmadan 126 bayt kuyruk özyinelemeli versiyonu:def h(s: String):String=if(s=="1")"H"else if(s=="4")"Unh"else h(s.map(_.asDigit).map(a=>a*a).sum+"");print(h(readLine)+"appy")
6infinity8

@ 6infinity8: Neden yeni bir cevap olarak göndermiyorsunuz?
kullanıcı bilinmeyen

İlk gönderi eski; Sadece çözümünüzü geliştirmeye çalışıyordum.
6infinity8

3

J (50)

'appy',~>('Unh';'H'){~=&1`$:@.(>&6)@(+/@:*:@:("."0)@":)

Eminim ki bunu daha da kısaltabileceğimden daha yetenekli bir J-er. Ben göreceli bir yeniyim.

Yeni ve geliştirilmiş:

('Unhappy';'Happy'){~=&1`$:@.(>&6)@(+/@:*:@:("."0)@":)

Ɐɔıʇǝɥʇuʎ’lar sayesinde daha yeni ve daha da gelişmiş:

(Unhappy`Happy){~=&1`$:@.(>&6)@(+/@:*:@:("."0)@":)

1
'Appy' bölümünü bölmeyerek bir karakter elde edebilirsiniz. Ayrıca parantezlerin etrafındaki parantezleri de kaldırabileceğinizi düşünüyorum ("." 0) - zarflar bağlanmalardan daha sıkı bağlanır.
Jesse Millikan

Parantezleri çıkaramıyorum ("."0). Bu bir rütbe hatası veriyor, ancak 'Happy' bölümünü bölmezsem ve sonucu kutuda bırakırsam, bir karakteri kaydedebilirim.
Gregory Higley

Parantezleri dışarıda bırakmamamın nedeni ("."0), bağlaçların bağlı oldukları fiillerin tümü için geçerli olması, istediğim şey değil. Söylersem +/@:("."0)@":, bu çok farklı +/@:"."0@:, ki aslında (+/@:".)"0@:.
Gregory Higley

1
Devasa nekro, ancak değiştirerek 4 karakter kurtarabilecek 'Unhappy';'Happy'ile Unhappy`Happy.
14'te

@ ʇǝɥʇıʇǝɥʇuʎs Çalışıyor, ancak dizelerin alıntılarını `ile atlayabildiğiniz yer nerede belgeleniyor?
Gregory Higley

2

Python (91 karakter)

a=lambda b:b-1and(b-4and a(sum(int(c)**2for c in`b`))or"Unh")or"H";print a(input())+"appy"

2

Ortak Lisp 138

(format t"~Aappy~%"(do((i(read)(loop for c across(prin1-to-string i)sum(let((y(digit-char-p c)))(* y y)))))((< i 5)(if(= i 1)"H""Unh"))))

Daha okunabilir:

(format t "~Aappy~%"
        (do
          ((i (read)
              (loop for c across (prin1-to-string i)
                    sum (let
                          ((y (digit-char-p c)))
                          (* y y)))))
          ((< i 5) (if (= i 1) "H" "Unh"))))

Hemen "Mutlu" ya da "Mutsuz" u geri döndürmek daha kısa (do)olurdu, ama tartışmalı olarak bu bütün bir program olarak sayılmaz.



2

Jöle , 17 bayt (yarışmaz *)

* Dil sonrası tarih mücadelesi

D²SµÐLỊị“¢*X“<@Ḥ»

Çevrimiçi deneyin!

Nasıl?

D²SµÐLỊị“¢*X“<@Ḥ» - Main link: n
   µÐL            - loop while the accumulated unique set of results change:
D                 -   cast to a decimal list
 ²                -   square (vectorises)
  S               -   sum
                  - (yields the ultimate result, e.g. n=89 yields 58 since it enters the
                  -  "unhappy circle" at 145, loops around to 58 which would yield 145.)
      Ị           - insignificant? (abs(v)<=1 - in this case, 1 for 1, 0 otherwise)
        “¢*X“<@Ḥ» - dictionary lookup of ["Happy", "Unhappy"] (the central “ makes a list)
       ị          - index into
                  - implicit print

1

Perl 5 - 77 Bayt

{$n=$_*$_ for split//,$u{$n}=$n;exit warn$/.'un'[$n==1].'happy'if$u{$n};redo}

$ n giriş değeridir


1

05AB1E , 21 bayt

'ŽØs[SnOD5‹#}≠i„unì}™

Çevrimiçi deneyin ya da ilk 100 test vakasını doğrulayın .

Açıklama:

Her sayı sonunda sonuçta 1veya ile sonuçlanır 4, bu yüzden süresiz olarak döngü kurarız ve sayı 5'in altına düşer düşmez dururuz.

'ŽØ                    '# Push string "happy"
   s                    # Swap to take the (implicit) input
    [       }           # Loop indefinitely
     S                  #  Convert the integer to a list of digits
      n                 #  Square each
       O                #  Take the sum
        D5‹#            #  If this sum is smaller than 5: stop the infinite loop
             i    }    # If the result after the loop is NOT 1:
               unì     #  Prepend string "un" to string "happy"
                       # Convert the string to titlecase (and output implicitly)

Bunun neden 'ŽØolduğunu anlamak için bu 05AB1E ipucumun (bkz . Sözlük nasıl kullanılır? )"happy" .


0

C ++ 135, 2 Satır

#include<iostream>
int n,i,j;int main(){for(std::cin>>n;n>1;n=++j&999?n*n+i:0)for(i=0;n/10;n/=10)i+=n%10*(n%10);std::cout<<(n?"H":"Unh")<<"appy";}

Bu, burada yaptığımın değiştirilmiş bir versiyonudur:

/programming/3543811/code-golf-happy-primes/3545056#3545056


Ne &999yapmak Ve eğer jbir çöp değerse nasıl çalışır ?
David diyor Reinstate Monica,

@ Dgrin91, bunu 3 yıl önce yazdım, bu yüzden tam olarak nasıl çalıştığını hatırlayamıyorum. & 999'un ifadesini yaptığı if(j==999){n = 0;}else{n=n*n +i;}, j'nin bir çöp değeri olmaması gerektiğini, küresellerin sıfır başlatıldığını düşünüyorum.
Scott Logan,

0

Evet, bu zorluğun üç yılı var; evet, zaten kazanan bir cevabı var; ama sıkıldım ve başka bir meydan okuma için bunu yaptığım için, buraya koyabileceğimi düşündüm. Sürpriz sürpriz, uzun - ve ...

Java - 280 264 bayt

import java.util.*;class H{public static void main(String[]a){int n=Integer.parseInt(new Scanner(System.in).nextLine()),t;while((t=h(n))/10!=0)n=t;System.out.print(t==1?"":"");}static int h(int n){if(n/10==0)return n*n;else return(int)Math.pow(n%10,2)+h(n/10);}}

Ungolfed:

import java.util.*;

class H {

    public static void main(String[] a) {
        int n = Integer.parseInt(new Scanner(System.in).nextLine()), t;
        while ((t = h(n)) / 10 != 0) {
            n = t;
        }
        System.out.print(t == 1 ? "" : "");
    }

    static int h(int n) {
        if (n / 10 == 0) {
            return n * n;
        } else {
            return (int) Math.pow(n % 10, 2) + h(n / 10);
        }
    }
}


0

Clojure, 107 97 bayt

Güncelleme: Gereksiz letciltleme kaldırıldı .

#(loop[v %](case v 1"Happy"4"Unhappy"(recur(apply +(for[i(for[c(str v)](-(int c)48))](* i i))))))

Orijinal:

#(loop[v %](let[r(apply +(for[i(for[c(str v)](-(int c)48))](* i i)))](case r 1"Happy"4"Unhappy"(recur r))))

Yuvalanmış ilk kez kullanma for : o


0

R, 117 91 bayt

Giuseppe sayesinde -16 bayt

a=scan();while(!a%in%c(1,4))a=sum((a%/%10^(0:nchar(a))%%10)^2);`if`(a-1,'unhappy','happy')

1
Kullanım strtoiyerine as.numericve pasteyerine as.character, bunlarla kısa yaklaşım yoktur basamak olsun . Kullanırsanız `if`(a-1,"unhappy","happy")bunun yerine başka bir byte kaydetmeniz gerekir. Sonunda, bunu bir kaç bayt daha daha fazla tıraş etmek için anonim yapabilirsiniz.
Giuseppe



-1

C: 1092 karakter

#include <iostream>
using namespace std ;
int main ()
{
    int m , a[25] , kan=0 , y , z=0  , n , o=0, s , k=0 , e[25]  ;
    do {
m :
        for ( int j=1 ; j <10000 ; j++ )
        {   
n:
            for (int i=0 ; j!=0 ; i++ )
            {
                a[i]=j%10 ;
                j/=10 ;
                kan++ ;
            }
            for ( int i=0 ; i<kan ; i++ )
            {
                y=a[i]*a[i] ;
                z+=y ;
            }
            k+=1 ;
            if (z==1)
            {
              cout<<j<<endl;
               o++ ;
            }

            else 
            {   
                 for (int f=0 ; f<k ; f++ )
                 {
                     e[f]=z ;
                 }
                 for ( int f=0 ; f=k-1 ; f++ )
                 {
                     for ( int p=f+1 ; p <k-1 ; p++ )
                     {
                         if(e[f]=e[p])
                             goto m ;
                         else { j=z ; goto n ; } 
                     }
                 }
            }
        }
    }while(o!=100) ;
    return 0 ;
}

6
Programming Puzzles & Code Golf'a hoş geldiniz @jannat. Golf kodunun mümkün olan en kısa kodu yazmanın zor olduğunu lütfen unutmayın. Bu, burada kasıtsız ve neredeyse okunamayan bir kod yazdığımızı ve kodlarımızı mümkün olduğunca kısaltmak için dil sözdiziminin sınırlarını zorladığımız anlamına gelir .
Manat çalışması

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.