Temukan apakah suatu angka bahagia atau tidak?

21

Nomor bahagia ditentukan oleh proses berikut. Dimulai dengan bilangan bulat positif, gantilah angka dengan jumlah kuadrat digitnya, dan ulangi prosesnya sampai angka sama dengan 1 (di mana ia akan tinggal), atau loop tanpa henti dalam siklus yang tidak termasuk 1. Angka-angka itu di mana proses ini berakhir dengan 1 adalah angka-angka bahagia, sedangkan yang tidak berakhir dalam 1 adalah angka-angka yang tidak bahagia (atau angka sedih). Diberi nomor cetak apakah itu bahagia atau tidak bahagia.

Sample Inputs
7
4
13

Sample Outputs
Happy
Unhappy
Happy

Catatan: Program Anda tidak boleh lebih dari 10 detik untuk angka di bawah 1.000.000.000.

fR0DDY
sumber

Jawaban:

8

Golfscript - 34 karakter

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

Pada dasarnya sama dengan ini dan ini .

Alasan untuk 9 iterasi dijelaskan dalam komentar ini (ini secara teoritis mengembalikan nilai yang benar hingga sekitar 10^10^10^974( A001273 )).

Nabb
sumber
11

Ruby, 77 karakter

a=gets.to_i;a=eval"#{a}".gsub /./,'+\&**2'until a<5
puts a<2?:Happy: :Unhappy
Ventero
sumber
Ok, jadi saya agak mengerti bagaimana ini bekerja (Secara harfiah mengambil setiap angka, membelahnya dan menambahkan kuadrat dari setiap digit), tetapi ada apa dengan kondisi berhenti (a <5) dan menggunakan (a <2) untuk memutuskan apakah itu bahagia atau tidak? Saya tidak mempertanyakan validitas, hanya logika.
Tn. Llama
2
Itu sama dengan a <= 4dan a <= 1. Jika siklus memiliki 1 di dalamnya maka ia bahagia, dan jika memiliki 4 di dalamnya, maka ia tidak bahagia. Lihat bagian wikipedia tentang siklus tidak bahagia. Jadi begitu nilai a4 atau kurang, dia memeriksa apakah a - hasil dari itu adalah jawaban Anda.
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");}

Ini menggunakan array 2 30 -byte (1GB) sebagai bitmap untuk melacak nomor mana yang telah ditemukan dalam siklus. Di Linux, ini benar-benar berfungsi, dan efisien, asalkan overcommitting memori diaktifkan (yang biasanya secara default). Dengan overcommitting, halaman array dialokasikan dan diunggulkan sesuai permintaan.

Perhatikan bahwa mengkompilasi program ini di Linux menggunakan satu gigabyte RAM.

Joey Adams
sumber
1
Mengapa Anda membutuhkan jumlah memori yang hampir sama untuk masalah ini?
Peter Olson
1
@ Peter: Saya kira pendekatannya adalah (secara naif) menangkap siklus untuk angka apa pun dalam rentang input yang diizinkan dari 1 hingga 1.000.000.000. Tetapi saya setuju bahwa berdasarkan teori angka bahagia, satu-satunya pemeriksaan yang diperlukan adalah jika angka 4 tercapai, karena itulah satu-satunya siklus yang akan terjadi.
mellamokb
Saya ingin tahu: mengapa kompilasi membutuhkan banyak RAM?
Peter Taylor
1
Tampaknya berfungsi dengan baik pada Windows 7 dengan MSVC 10. Tidak mengkonsumsi jumlah memori yang menonjol saat mengkompilasi dan hanya menandai array dalam file halaman (sesuatu yang terdengar jauh lebih aman daripada cerita yang Anda tautkan tentang overcommitting memori menyarankan ;-)) .
Joey
1
Saya suka kenaifan dari pendekatan ini. Dan penyalahgunaan untuk loop itu indah.
dmckee
6

Haskell - 77

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

Golfscript, 49 43 41 40 39 karakter

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

Setiap nomor senang berkumpul menjadi 1; setiap angka yang tidak bahagia konvergen ke siklus yang mengandung 4. Selain mengeksploitasi fakta itu, ini hampir tidak golf sama sekali.

(Terima kasih kepada Ventero, dari solusi Ruby yang mana saya telah membuat trik dan menyelamatkan 6 karakter).

Peter Taylor
sumber
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

Disebut sebagai etex filename.tex 34*23 + 32/2 ?(termasuk tanda tanya di bagian akhir). Spasi dalam ekspresi tidak masalah.

EDIT: Saya turun ke 123 , tapi sekarang outputnya adalah dvi (jika dikompilasi dengan etex) atau pdf (jika dikompilasi dengan pdfetex). Karena TeX adalah bahasa penyusunan huruf, saya kira itu adil.

\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
Bruno Le Floch
sumber
4

Python - 81 karakter

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

Beberapa inspirasi diambil dari Ventero dan Peter Taylor.

Juan
sumber
2
lebih baik melakukan int(c)daripada 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')

Input disediakan dengan mengatur a ke nomor yang diinginkan.

Kredit untuk mellamokb.

Peter Olson
sumber
Simpan 1 char:n==4?h="Unh":n==1?h="H":a=n+""}alert(h+"appy")
mellamokb
@ mella, terima kasih. Saya juga mencukur char lain dengan mengganti ||ke |.
Peter Olson
Simpan 8 karakter: Hapus n==4?h.... Ubah untuk melakukan ... sambil mengulang dengan kondisi while(n>4). Kemudian gunakan pernyataan terakhir ini sebagai gantinya:alert(["H","Unh"][n>1?1:0]+"appy")
mellamokb
@ Mella Pintar, saya menyukainya.
Peter Olson
@ Mella n perlu didefinisikan sebelum loop sementara, saya mencoba memikirkan bagaimana untuk tidak mengulangin=0;
Peter Olson
4

Python (98, tapi terlalu kacau untuk tidak berbagi)

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

Mungkin terlalu lama untuk bersaing, tetapi mungkin bagus untuk tertawa. Itu evaluasi "malas" dengan Python. Benar-benar sangat mirip dengan entri Haskell sekarang yang saya pikirkan, hanya tanpa pesona.


sumber
4

dc - 47 karakter

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

Deskripsi singkat:

I~: Dapatkan hasil bagi dan sisanya saat membaginya dengan 10
d*.: Kuadratkan sisanya.
0<H: Jika hasil bagi lebih besar dari 0, ulangi secara rekursif.
+: Jumlahkan nilai saat menyusutkan tumpukan rekursif.

4<h: Ulangi jumlah sum-of-kuadrat sementara nilainya lebih besar dari 4.

Nabb
sumber
4

Befunge, 109

Mengembalikan nilai yang benar untuk 1 <= n <= 10 9 -1.

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

J, 56

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

Kata kerja alih-alih skrip mandiri karena pertanyaannya ambigu.

Pemakaian:

   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  
Jesse Millikan
sumber
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))}
Pengguna tidak diketahui
sumber
1
Tidak (n*n)akan lebih pendek n*n , atau apakah spasi tidak cukup untuk memisahkan ekspresi if dari else?
Peter Taylor
Ya, saya melakukannya, Peter.
pengguna tidak diketahui
Ini adalah versi rekursif 126 byte, tanpa pencocokan pola: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: Mengapa Anda tidak mempostingnya sebagai jawaban baru?
pengguna tidak diketahui
Posting awal sudah tua; Saya hanya berusaha meningkatkan solusi Anda.
6infinity8
3

J (50)

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

Saya yakin J-er lebih kompeten daripada saya bisa membuat ini lebih pendek. Saya seorang newb relatif.

Baru dan ditingkatkan:

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

Lebih baru dan lebih ditingkatkan, terima kasih kepada ɐɔıʇǝɥʇuʎs:

(Unhappy`Happy){~=&1`$:@.(>&6)@(+/@:*:@:("."0)@":)
Gregory Higley
sumber
1
Anda bisa mendapatkan karakter dengan tidak membagi 'appy'. Saya pikir Anda juga dapat menghapus tanda kurung di sekitar d ("." 0) - adverb mengikat lebih ketat dari kata sambung.
Jesse Millikan
Saya tidak bisa menghapus tanda kurung di sekitar ("."0). Itu menghasilkan kesalahan peringkat, tetapi jika saya tidak membagi 'Happy' dan membiarkan hasilnya dalam kotak, saya dapat menyimpan karakter.
Gregory Higley
Alasan saya tidak bisa meninggalkan tanda kurung di sekitar ("."0)adalah bahwa kata sambung berlaku untuk seluruh kata kerja kereta sebelumnya yang dilampirkan, yang bukan yang saya inginkan. Jika saya katakan +/@:("."0)@":, itu sangat berbeda dari +/@:"."0@:yang sebenarnya (+/@:".)"0@:.
Gregory Higley
1
Sebuah necro besar, tetapi Anda bisa menghemat 4 karakter dengan mengganti 'Unhappy';'Happy'dengan Unhappy`Happy.
ɐɔıʇǝɥʇu
@ ɐɔıʇǝɥʇu Itu berhasil, tetapi di mana didokumentasikan bahwa Anda dapat melewatkan kutipan string dengan `?
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"
marinus
sumber
2

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

Lebih mudah dibaca:

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

Akan lebih pendek untuk hanya mengembalikan "Happy" atau "Unhappy" langsung dari (do), tetapi bisa dibilang itu tidak akan dihitung sebagai keseluruhan program

daniero
sumber
2

K, 43

{{$[4=d:+/a*a:"I"$'$x;unhappy;d]}/x;`happy}
tmartin
sumber
2

Jelly , 17 byte (tidak bersaing *)

* Bahasa tantangan pasca-tanggal

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

Cobalah online!

Bagaimana?

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
Jonathan Allan
sumber
1

Perl 5 - 77 Bytes

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

$ n adalah nilai input

Kaundur
sumber
1

05AB1E , 21 byte

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

Cobalah secara online atau verifikasi 100 kasus uji pertama .

Penjelasan:

Setiap angka pada akhirnya akan menghasilkan salah satu 1atau 4, jadi kami mengulang tanpa batas, dan berhenti segera setelah angka di bawah 5.

'ŽØ                    '# 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)

Lihat ini ujung 05AB1E saya (bagian Cara menggunakan kamus? ) Untuk memahami mengapa 'ŽØadalah "happy".

Kevin Cruijssen
sumber
0

C ++ 135, 2 Baris

#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";}

Ini adalah versi modifikasi dari yang saya lakukan di sini:

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

Scott Logan
sumber
Apa yang &999dilakukan? Dan bagaimana cara kerjanya jika jnilai sampah?
David mengatakan Reinstate Monica
@ Dgrin91, saya menulis ini 3 tahun lalu, jadi saya tidak ingat persis cara kerjanya. Saya pikir & 999 membuat pernyataan if(j==999){n = 0;}else{n=n*n +i;}, j seharusnya tidak menjadi nilai sampah, global nol diinisialisasi.
Scott Logan
0

Ya, tantangan ini memiliki tiga tahun; ya, sudah memiliki jawaban pemenang; tetapi karena aku bosan dan melakukan ini untuk tantangan lain, kupikir aku mungkin memasangnya di sini. Kejutan mengejutkan, panjang - dan ...

Java - 280 264 byte

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

Tidak Disatukan:

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);
        }
    }
}
Rodolfo Dias
sumber
0

C # 94 byte

int d(int n)=>n<10?n*n:(d(n%10)+d(n/10));string h(int n)=>n==1?"happy":n==4?"unhappy":h(d(n));

Untuk nomor apa pun (as int), h()akan mengembalikan nilai yang benar. Anda dapat mencoba kode di .NetFiddle .

Kudos kepada pengguna yang tidak diketahui untuk algoritme asli .

aloisdg kata Reinstate Monica
sumber
0

Clojure, 107 97 byte

Pembaruan: Menghapus letikatan yang tidak perlu .

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

Asli:

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

Pertama kali menggunakan bersarang for: o

NikoNyrh
sumber
0

R, 117 91 byte

-16 byte terima kasih kepada Giuseppe

a=scan();while(!a%in%c(1,4))a=sum((a%/%10^(0:nchar(a))%%10)^2);`if`(a-1,'unhappy','happy')
Andrew Haynes
sumber
1
Gunakan strtoialih-alih as.numericdan pastealih-alih as.character, tetapi ada pendekatan yang lebih pendek untuk mendapatkan digit . Jika Anda menggunakan `if`(a-1,"unhappy","happy")itu harus menyimpan byte lain. Akhirnya, Anda dapat membuat anonim ini untuk mengurangi beberapa byte lagi.
Giuseppe
0

Python 2 , 71 byte

f=lambda n:n>4and f(sum(int(d)**2for d in`n`))or("H","Unh")[n>1]+"appy"

Cobalah online!

... atau, untuk jumlah byte yang sama:

f=lambda n:n>4and f(eval('**2+'.join(`n*10`)))or("H","Unh")[n>1]+"appy"

Cobalah online!

FlipTack
sumber
-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 ;
}
jannat
sumber
6
Selamat datang di Programming Puzzles & Code Golf, @jannat. Harap dicatat bahwa golf kode adalah tantangan untuk menulis kode sesingkat mungkin. Itu artinya, di sini kita menulis kode yang tidak terindentasi dan hampir tidak dapat dibaca dan memaksakan batas sintaksis bahasa untuk mempersingkat kode kita mungkin.
manatwork
xkcd.com/292
aditsu