Happy numbers
From Wikipedia, the free encyclopedia:
You are encouraged to solve this task according to the task description, using any language you may know.
- A happy number is defined by the following process. Starting with any positive integer, replace the number by the sum of the squares of its digits, and repeat the process until the number equals 1 (where it will stay), or it loops endlessly in a cycle which does not include 1. Those numbers for which this process ends in 1 are happy numbers, while those that do not end in 1 are unhappy numbers.
Task: Find and print the first 8 happy numbers.
Ada
<lang Ada>with Ada.Text_IO; use Ada.Text_IO; with Ada.Containers.Ordered_Sets;
procedure Test_Happy_Digits is
function Is_Happy (N : Positive) return Boolean is package Sets_Of_Positive is new Ada.Containers.Ordered_Sets (Positive); use Sets_Of_Positive; function Next (N : Positive) return Natural is Sum : Natural := 0; Accum : Natural := N; begin while Accum > 0 loop Sum := Sum + (Accum mod 10) ** 2; Accum := Accum / 10; end loop; return Sum; end Next; Current : Positive := N; Visited : Set; begin loop if Current = 1 then return True; elsif Visited.Contains (Current) then return False; else Visited.Insert (Current); Current := Next (Current); end if; end loop; end Is_Happy; Found : Natural := 0;
begin
for N in Positive'Range loop if Is_Happy (N) then Put (Integer'Image (N)); Found := Found + 1; exit when Found = 8; end if; end loop;
end Test_Happy_Digits;</lang> Sample output:
1 7 10 13 19 23 28 31
ALGOL 68
<lang algol>INT base10 = 10, num happy = 8;
PROC next = (INT in n)INT: (
INT n := in n; INT out := 0; WHILE n NE 0 DO out +:= ( n MOD base10 ) ** 2; n := n OVER base10 OD; out
);
PROC is happy = (INT in n)BOOL: (
INT n := in n; FOR i WHILE n NE 1 AND n NE 4 DO n := next(n) OD; n=1
);
INT count := 0; FOR i WHILE count NE num happy DO
IF is happy(i) THEN count +:= 1; print((i, new line)) FI
OD</lang> Output:
+1 +7 +10 +13 +19 +23 +28 +31
AutoHotkey
<lang AutoHotkey>Loop {
If isHappy(A_Index) { out .= (out="" ? "" : ",") . A_Index i ++ If (i = 8) { MsgBox, The first 8 happy numbers are: %out% ExitApp } }
}
isHappy(num, list="") {
list .= (list="" ? "" : ",") . num Loop, Parse, num sum += A_LoopField ** 2 If (sum = 1) Return true Else If sum in %list% Return false Else Return isHappy(sum, list)
}</lang>
AWK
<lang awk>function is_happy(n) {
if ( n in happy ) return 1; if ( n in unhappy ) return 0; cycle[""] = 0 while( (n!=1) && !(n in cycle) ) { cycle[n] = n new_n = 0 while(n>0) { d = n % 10 new_n += d*d n = int(n/10) } n = new_n } if ( n == 1 ) { for (i_ in cycle) { happy[cycle[i_]] = 1 delete cycle[i_] } return 1 } else { for (i_ in cycle) { unhappy[cycle[i_]] = 1 delete cycle[i_] } return 0 }
}
BEGIN {
cnt = 0 happy[""] = 0 unhappy[""] = 0 for(j=1; (cnt < 8); j++) { if ( is_happy(j) == 1 ) { cnt++ print j } }
}</lang>
C
<lang c>#include <stdio.h>
- include <stdbool.h>
- include <stdlib.h>
- include <string.h>
- include <assert.h>
typedef struct list {
int val; struct list *next;
} list_t;
bool in_cycle(list_t *c, int n) {
for( ; c != NULL; c = c->next ) if ( n == c->val ) return true; return false;
}
void add_cycle(list_t **c, int n) {
list_t *p = malloc(sizeof(list_t)); assert(p!=NULL); p->val = n; p->next = NULL; if ( *c == NULL ) { *c = p; } else { p->next = *c; *c = p; }
}
void kill_cycle(list_t *c) {
list_t *t; for(;c!=NULL; c=t) { t = c->next; free(c); }
}
bool is_happy(int n) {
list_t *cycle = NULL; int new_n;
while( (n != 1) && !in_cycle(cycle, n) ) { add_cycle(&cycle, n); new_n = 0; while( n > 0 ) { int d = n % 10; new_n += d*d; n /= 10; } n = new_n; } kill_cycle(cycle); return (n == 1);
}
int main() {
int i; int cnt = 0; for(i=1; cnt < 8; i++) { if (is_happy(i)) { printf("%d\n", i); cnt++; } } return EXIT_SUCCESS;
}</lang>
C++
<lang cpp>#include <map>
- include <set>
bool happy(int number) {
static std::map<int, bool> cache;
std::set<int> cycle; while (number != 1 && !cycle.count(number)) { if (cache.count(number)) { number = cache[number] ? 1 : 0; break; } cycle.insert(number); int newnumber = 0; while (number > 0) { int digit = number % 10; newnumber += digit * digit; number /= 10; } number = newnumber; } bool happiness = number == 1; for (std::set<int>::const_iterator it = cycle.begin(); it != cycle.end(); it++) cache[*it] = happiness; return happiness;
}
- include <iostream>
int main() {
for (int i = 1; i < 50; i++) if (happy(i)) std::cout << i << std::endl; return 0;
}</lang>
Alternative version without caching:
<lang cpp>unsigned int happy_iteration(unsigned int n) {
unsigned int result = 0; while (n > 0) { unsigned int lastdig = n % 10; result += lastdig*lastdig; n /= 10; } return result;
}
bool is_happy(unsigned int n) {
unsigned int n2 = happy_iteration(n); while (n != n2) { n = happy_iteration(n); n2 = happy_iteration(happy_iteration(n2)); } return n == 1;
}
- include <iostream>
int main() {
unsigned int current_number = 1;
unsigned int happy_count = 0; while (happy_count != 8) { if (is_happy(current_number)) { std::cout << current_number << " "; ++happy_count; } ++current_number; } std::cout << std::endl;
}</lang>
Cycle detection in is_happy()
above is done using Floyd's cycle-finding algorithm.
Common Lisp
<lang lisp>(defun happyp (n &aux (seen ()))
(loop (when (= n 1) (return t)) (when (find n seen) (return nil)) (push n seen) (setf n (reduce #'+ (map 'list (lambda (c &aux (x (position c "0123456789"))) (* x x)) (format nil "~d" n))))))
(loop
with happy = 0 for n from 0 until (= 8 happy) when (happyp n) do (incf happy) and do (format t "~d~%" n))</lang>
E
<lang e>def isHappyNumber(var x :int) {
var seen := [].asSet() while (!seen.contains(x)) { seen with= x var sum := 0 while (x > 0) { sum += (x % 10) ** 2 x //= 10 } x := sum if (x == 1) { return true } } return false
}
var count := 0 for x ? (isHappyNumber(x)) in (int >= 1) {
println(x) if ((count += 1) >= 8) { break }
}</lang>
Forth
<lang forth>
- next ( n -- n )
0 swap begin 10 /mod >r dup * + r> ?dup 0= until ;
- cycle? ( n -- ? )
here dup @ cells + begin dup here > while 2dup @ = if 2drop true exit then 1 cells - repeat 1 over +! dup @ cells + ! false ;
- happy? ( n -- ? )
0 here ! begin next dup cycle? until 1 = ;
- happy-numbers ( n -- )
0 swap 0 do begin 1+ dup happy? until dup . loop drop ;
8 happy-numbers \ 1 7 10 13 19 23 28 31 </lang>
Haskell
<lang haskell>import Data.Char (digitToInt)
isHappy :: Integer -> Bool isHappy = p []
where p _ 1 = True p l n | n `elem` l = False | otherwise = p (n : l) (f n) f = sum . map ((^2) . digitToInt) . show
main = mapM_ print $ take 8 $ filter isHappy [1..]</lang>
J
<lang j>
8{. (#~1=+/@(*:@(,.&.":))^:(1&~:*.4&~:)^:_ "0) 1+i.100
1 7 10 13 19 23 28 31</lang>
This is a repeat while construction <lang j> f ^: cond ^: _ <input></lang> that produces an array of 1's and 4's, which is converted to 1's and 0's forming a binary array having a 1 for a happy number. Finally the happy numbers are extracted by a binary selector. <lang j> (binary array) # 1..100</lang>
So for easier reading the solution could be expressed as: <lang j> cond=: 1&~: *. 4&~: NB. not equal to 1 and not equal to 4
sumSqrDigits=: +/@(*:@(,.&.":))
sumSqrDigits 123 NB. test sum of squared digits
14
8{. (#~ 1 = sumSqrDigits ^: cond ^:_ "0) 1 + i.100
1 7 10 13 19 23 28 31</lang>
Java
<lang java5>import java.util.HashSet; public class Happy{
public static boolean happy(long number){ long m = 0; int digit = 0; HashSet<Long> cycle = new HashSet<Long>(); while(number != 1 && cycle.add(number)){ m = 0; while(number > 0){ digit = (int)(number % 10); m += digit*digit; number /= 10; } number = m; } return number == 1; }
public static void main(String[] args){ for(long num = 1,count = 0;count<8;num++){ if(happy(num)){ System.out.println(num); count++; } } }
}</lang>
JavaScript
<lang javascript>function happy(number) {
var m, digit ; var cycle = new Array() ;
while(number != 1 && cycle[number] != true) { cycle[number] = true ; m = 0 ; while (number > 0) { digit = number % 10 ; m += digit * digit ; number = (number - digit) / 10 ; } number = m ; } return (number == 1) ;
} ;
var cnt = 8 ; var number = 1 ;
while(cnt-- > 0) {
while(!happy(number)) number++ ; document.write(number + " ") ; number++ ;
}</lang>
Mathematica
Custom function HappyQ: <lang Mathematica>
AddSumSquare[input_]:=Append[input,Total[IntegerDigits[Last[input]]^2]] NestUntilRepeat[a_,f_]:=NestWhile[f,{a},!MemberQ[Most[Last[{##}]],Last[Last[{##}]]]&,All] HappyQ[a_]:=Last[NestUntilRepeat[a,AddSumSquare]]==1
</lang> Examples for a specific number: <lang Mathematica>
HappyQ[1337] HappyQ[137]
</lang> gives back: <lang Mathematica> True False </lang> Example finding the first 8: <lang Mathematica> m = 8; n = 1; i = 0; happynumbers = {}; While[n <= m,
i++; If[HappyQ[i], n++; AppendTo[happynumbers, i] ] ]
happynumbers </lang> gives back: <lang Mathematica> {1, 7, 10, 13, 19, 23, 28, 31} </lang>
Perl
<lang perl>use List::Util qw(sum);
sub is_happy ($)
{for (my ($n, %seen) = shift ;; $n = sum map {$_**2} split //, $n) {$n == 1 and return 1; exists $seen{$n} and return 0; $seen{$n} = 1;}}
for (my ($n, $happy) = (1, 0) ; $happy < 8 ; ++$n)
{is_happy $n or next; print "$n\n"; ++$happy;}</lang>
Python
<lang python>>>> def happy(n):
past = set() while True: total = sum(int(i)**2 for i in str(n)) if total == 1 or total in past: return total not in past n = total past.add(total)
>>> [x for x in range(1,500) if happy(x)][:8] </lang>
R
<lang R> is.happy <- function(n) {
stopifnot(is.numeric(n) && length(n)==1) getdigits <- function(n) { as.integer(unlist(strsplit(as.character(n), ""))) } digits <- getdigits(n) previous <- c() repeat { sumsq <- sum(digits^2, na.rm=TRUE) if(sumsq==1L) { happy <- TRUE break } else if(sumsq %in% previous) { happy <- FALSE attr(happy, "cycle") <- previous break } else { previous <- c(previous, sumsq) digits <- getdigits(sumsq) } } happy
} </lang> Example usage <lang R> is.happy(2) </lang>
[1] FALSE attr(,"cycle") [1] 4 16 37 58 89 145 42 20
<lang R>
- Find happy numbers between 1 and 50
which(apply(rbind(1:50), 2, is.happy)) </lang>
1 7 10 13 19 23 28 31 32 44 49
<lang R>
- Find the first 8 happy numbers
happies <- c() i <- 1L while(length(happies) < 8L) {
if(is.happy(i)) happies <- c(happies, i) i <- i + 1L
} happies </lang>
1 7 10 13 19 23 28 31
Ruby
Use of cache from Python <lang ruby>require 'set'
def happy?(n)
seen = Set[] state = while n>1 and not seen.include?(n) if $happy_cache[:happy].include?(n): break :happy elsif $happy_cache[:sad].include?(n): break :sad end seen << n n = sum_of_squares_of_digits(n) end state.nil? and state = n == 1 ? :happy : :sad $happy_cache[state] += seen state == :happy
end
def sum_of_squares_of_digits(n)
n.to_s.each_char.inject(0) {|sum,c| sum += (c.to_i)**2}
end
$happy_cache = Hash.new(Set[]) happy_numbers = [] i = 1 while happy_numbers.length < 8
happy_numbers << i if happy? i i += 1
end p happy_numbers p $happy_cache</lang>
[1, 7, 10, 13, 19, 23, 28, 31] {:happy=>[7, 49, 97, 130, 10, 13, 19, 82, 68, 100, 23, 28, 31], :sad=>[2, 4, 16, 37, 58, 89, 145, 42, 20, 3, 9, 81, 65, 61, 5, 25, 29, 85, 6, 36, 45, 41, 17, 50, 8, 64, 52, 11, 12, 14, 15, 26, 40, 18, 21, 22, 24, 27, 53, 34, 30]}
Smalltalk
In addition to the "Python's cache mechanism", the use of a Bag assures that found e.g. the happy 190, we already have in cache also the happy 910 and 109, and so on. <lang smalltalk>Object subclass: HappyNumber [
|cache negativeCache| HappyNumber class >> new [ |me| me := super new. ^ me init ] init [ cache := Set new. negativeCache := Set new. ]
hasSad: aNum [ ^ (negativeCache includes: (self recycle: aNum)) ] hasHappy: aNum [ ^ (cache includes: (self recycle: aNum)) ] addHappy: aNum [ cache add: (self recycle: aNum) ] addSad: aNum [ negativeCache add: (self recycle: aNum) ]
recycle: aNum [ |r n| r := Bag new. n := aNum. [ n > 0 ] whileTrue: [ |d| d := n rem: 10. r add: d. n := n // 10. ]. ^r ]
isHappy: aNumber [ |cycle number newnumber| number := aNumber. cycle := Set new. [ (number ~= 1) & ( (cycle includes: number) not ) ] whileTrue: [ (self hasHappy: number) ifTrue: [ ^true ] ifFalse: [ (self hasSad: number) ifTrue: [ ^false ]. cycle add: number. newnumber := 0. [ number > 0 ] whileTrue: [ |digit| digit := number rem: 10. newnumber := newnumber + (digit * digit). number := (number - digit) // 10. ]. number := newnumber. ] ]. (number = 1) ifTrue: [ cycle do: [ :e | self addHappy: e ]. ^true ] ifFalse: [ cycle do: [ :e | self addSad: e ]. ^false ] ]
].</lang>
<lang smalltalk>|happy| happy := HappyNumber new.
1 to: 30 do: [ :i |
(happy isHappy: i) ifTrue: [ i displayNl ]
].</lang>
Tcl
using code from Sum of squares#Tcl <lang tcl>proc is_happy n {
set seen [list] while {$n > 1 && [lsearch -exact $seen $n] == -1} { lappend seen $n set n [sum_of_squares [split $n ""]] } return [expr {$n == 1}]
}
set happy [list] set n -1 while {[llength $happy] < 8} {
if {[is_happy $n]} {lappend happy $n} incr n
} puts "the first 8 happy numbers are: [list $happy]"</lang>
the first 8 happy numbers are: {1 7 10 13 19 23 28 31}
Ursala
The happy function is a predicate testing whether a given number is happy, and first(p) defines a function mapping a number n to the first n positive naturals having property p. <lang Ursala>#import std
- import nat
happy = ==1+ ^== sum:-0+ product*iip+ %np*hiNCNCS+ %nP
first "p" = ~&i&& iota; ~&lrtPX/&; leql@lrPrX->lrx ^|\~& ^/successor@l ^|T\~& "p"&& ~&iNC
- cast %nL
main = (first happy) 8</lang> output:
<1,7,10,13,19,23,28,31>