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.

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


11

Ruby, 77 karakter

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

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.


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

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


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

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.


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.


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.


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.


4

Befunge, 109

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

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

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  

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

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"

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



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

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


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


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


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


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


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

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



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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.