Happy numbers: Difference between revisions
→{{header|UNIX Shell}}: Add bash works-with |
→{{header|Liberty BASIC}}: Add Logo |
||
Line 1,013:
</lang>
=={{header|Logo}}==
=={{header|Liberty BASIC}}==
<lang lb>
|
Revision as of 01:00, 19 May 2011
![Task](http://static.miraheze.org/rosettacodewiki/thumb/b/ba/Rcode-button-task-crushed.png/64px-Rcode-button-task-crushed.png)
You are encouraged to solve this task according to the task description, using any language you may know.
From Wikipedia, the free encyclopedia:
- 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.
ActionScript
<lang ActionScript>function sumOfSquares(n:uint) { var sum:uint = 0; while(n != 0) { sum += (n%10)*(n%10); n /= 10; } return sum; } function isInArray(n:uint, array:Array) { for(var k = 0; k < array.length; k++) if(n == array[k]) return true; return false; } function isHappy(n) { var sequence:Array = new Array(); while(n != 1) { sequence.push(n); n = sumOfSquares(n); if(isInArray(n,sequence))return false; } return true; } function printHappy() { var numbersLeft:uint = 8; var numberToTest:uint = 1; while(numbersLeft != 0) { if(isHappy(numberToTest)) { trace(numberToTest); numbersLeft--; } numberToTest++; } } printHappy();</lang>
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 algol68>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
APL
<lang APL>
∇ HappyNumbers arg;⎕IO;∆roof;∆first;bin;iroof
[1] ⍝0: Happy number [2] ⍝1: http://rosettacode.org/wiki/Happy_numbers [3] ⎕IO←1 ⍝ Index origin [4] ∆roof ∆first←2↑arg,10 ⍝ [5] [6] bin←{ [7] ⍺←⍬ ⍝ Default left arg [8] ⍵=1:1 ⍝ Always happy! [9] [10] numbers←⍎¨1⊂⍕⍵ ⍝ Split numbers into parts [11] next←+/{⍵*2}¨numbers ⍝ Sum and square of numbers [12] [13] next∊⍺:0 ⍝ Return 0, if already exists [14] (⍺,next)∇ next ⍝ Check next number (recursive) [15] [16] }¨iroof←⍳∆roof ⍝ Does all numbers upto ∆root smiles? [17] [18] ⎕←~∘0¨∆first↑bin/iroof ⍝ Show ∆first numbers, but not 0
∇
</lang>
HappyNumbers 100 8 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>
BBC BASIC
<lang bbcbasic> number% = 0
total% = 0 REPEAT number% += 1 IF FNhappy(number%) THEN PRINT number% " is a happy number" total% += 1 ENDIF UNTIL total% = 8 END DEF FNhappy(num%) LOCAL digit&() DIM digit&(10) REPEAT digit&() = 0 $$^digit&(0) = STR$(num%) digit&() AND= 15 num% = MOD(digit&())^2 + 0.5 UNTIL num% = 1 OR num% = 4 = (num% = 1)</lang>
Output:
1 is a happy number 7 is a happy number 10 is a happy number 13 is a happy number 19 is a happy number 23 is a happy number 28 is a happy number 31 is a happy number
Brat
<lang brag>include :set
happiness = set.new 1 sadness = set.new
sum_of_squares_of_digits = { num |
num.to_s.dice.reduce 0 { sum, n | sum = sum + n.to_i ^ 2 }
}
happy? = { n, seen = set.new |
when {true? happiness.include? n } { happiness.merge seen << n; true } { true? sadness.include? n } { sadness.merge seen; false } { true? seen.include? n } { sadness.merge seen; false } { true } { seen << n; happy? sum_of_squares_of_digits(n), seen }
}
num = 1 happies = []
while { happies.length < 8 } {
true? happy?(num) { happies << num }
num = num + 1
}
p "First eight happy numbers: #{happies}" p "Happy numbers found: #{happiness.to_array.sort}" p "Sad numbers found: #{sadness.to_array.sort}"</lang> Output:
First eight happy numbers: [1, 7, 10, 13, 19, 23, 28, 31] Happy numbers found: [1, 7, 10, 13, 19, 23, 28, 31, 49, 68, 82, 97, 100, 130] Sad numbers found: [2, 3, 4, 5, 6, 8, 9, 11, 12, 14, 15, 16, 17, 18, 20, 21, 22, 24, 25, 26, 27, 29, 30, 34, 36, 37, 40, 41, 42, 45, 50, 52, 53, 58, 61, 64, 65, 81, 85, 89, 145]
C
<lang c>#include "stdio.h"
- include "stdlib.h"
int is_in(int item, int arr[], int arr_len) {
int i; for (i = 0; i < arr_len; i++) if (arr[i] == item) return 1; // found return 0;
}
int is_happy(int n) {
#define SEEN_LEN 100 static int seen[SEEN_LEN]; int n_seen = 0;
while (!is_in(n, seen, n_seen)) { if (n_seen >= SEEN_LEN) { fprintf(stderr, "Error: out of seen[]\n"); exit(EXIT_FAILURE); } seen[n_seen] = n; n_seen++;
int tot = 0; while (n) { int digit = n % 10; n /= 10; tot += digit * digit; } n = tot; }
return n == 1; #undef SEEN_LEN
}
int main() {
int to_show = 8;
int n_shown = 0; int n = 1; while (n_shown < to_show) { if (is_happy(n)) { printf("%d ", n); n_shown++; } n++; } printf("\n");
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.
C#
<lang csharp> using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace HappyNums {
class Program { public static bool ishappy(int n) { List<int> cache = new List<int>(); int sum = 0; while (n != 1) { if (cache.Contains(n)) { return false; } cache.Add(n); while (n != 0) { int digit = n % 10; sum += digit * digit; n /= 10; } n = sum; sum = 0; } return true; }
static void Main(string[] args) { int num = 1; List<int> happynums = new List<int>();
while (happynums.Count < 8) { if (ishappy(num)) { happynums.Add(num); } num++; } Console.WriteLine("First 8 happy numbers : " + string.Join(",", happynums)); } }
} </lang>
First 8 happy numbers : 1,7,10,13,19,23,28,31
Clojure
<lang clojure>(defn- digit-to-num [d] (Character/digit d 10)) (defn- square [n] (* n n))
(defn happy? [n]
(loop [n n, seen #{}] (cond (= n 1) true (seen n) false :else (recur (reduce + (map (comp square digit-to-num) (str n))) (conj seen n)))))
(def happy-numbers (filter happy? (iterate inc 1)))
(println (take 8 happy-numbers))</lang>
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>
D
<lang d>import std.stdio, std.algorithm, std.range;
bool isHappy(int n) {
int[int] past;
while (true) { int total = 0; while (n > 0) { total += (n % 10) ^^ 2; n /= 10; } if (total == 1) return true; if (total in past) return false; n = total; past[total] = 0; }
}
void main() {
auto h = filter!isHappy(iota(int.max)); writeln(take(h, 8));
}</lang>
Output:
[1, 7, 10, 13, 19, 23, 28, 31]
dc
<lang dc>[lcI~rscd*+lc0<H]sH [0rsclHxd4<h]sh [lIp]s_ 0sI[lI1+dsIlhx2>_z8>s]dssx</lang> Output:
1 7 10 13 19 23 28 31
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>
Erlang
<lang Erlang>-module(tasks). -export([main/0]). -import(lists, [map/2, member/2, sort/1, sum/1]).
is_happy(X, XS) ->
if
X == 1 -> true; X < 1 -> false; true -> case member(X, XS) of true -> false; false -> is_happy(sum(map(fun(Z) -> Z*Z end, [Y - 48 || Y <- integer_to_list(X)])), [X|XS]) end
end.
main(X, XS) ->
if
length(XS) == 8 -> io:format("8 Happy Numbers: ~w~n", [sort(XS)]); true -> case is_happy(X, []) of true -> main(X + 1, [X|XS]); false -> main(X + 1, XS) end
end.
main() ->
main(0, []).
</lang>
Command: <lang Bash>erl -run tasks main -run init stop -noshell</lang> Output: <lang Bash>8 Happy Numbers: [1,7,10,13,19,23,28,31]</lang>
In a more functional style (assumes integer_to_list/1 will convert to the ASCII value of a number, which then has to be converted to the integer value by subtracting 48):
<lang Erlang> -module(tasks).
-export([main/0]).
main() -> io:format("~w ~n", [happy_list(1, 8, [])]).
happy_list(_, N, L) when length(L) =:= N -> lists:reverse(L); happy_list(X, N, L) -> Happy = is_happy(X), if Happy -> happy_list(X + 1, N, [X|L]); true -> happy_list(X + 1, N, L) end.
is_happy(1) -> true; is_happy(4) -> false; is_happy(N) when N > 0 -> N_As_Digits = [Y - 48 || Y <- integer_to_list(N)], is_happy(lists:foldl(fun(X, Sum) -> (X * X) + Sum end, 0, N_As_Digits)); is_happy(_) -> false. </lang>
F#
This requires the F# power pack to be referenced and the 2010 beta of F# <lang fsharp>open System.Collections.Generic open Microsoft.FSharp.Collections
let answer =
let sqr x = x*x // Classic square definition let rec AddDigitSquare n = match n with | 0 -> 0 // Sum of squares for 0 is 0 | _ -> sqr(n % 10) + (AddDigitSquare (n / 10)) // otherwise add square of bottom digit to recursive call let dict = new Dictionary<int, bool>() // Dictionary to memoize values let IsHappy n = if dict.ContainsKey(n) then // If we've already discovered it dict.[n] // Return previously discovered value else let cycle = new HashSet<_>(HashIdentity.Structural) // Set to keep cycle values in let rec isHappyLoop n = if cycle.Contains n then n = 1 // If there's a loop, return true if it's 1 else cycle.Add n |> ignore // else add this value to the cycle isHappyLoop (AddDigitSquare n) // and check the next number in the cycle let f = isHappyLoop n // Keep track of whether we're happy or not cycle |> Seq.iter (fun i -> dict.[i] <- f) // and apply it to all the values in the cycle f // Return the boolean
1 // Starting with 1, |> Seq.unfold (fun i -> Some (i, i + 1)) // make an infinite sequence of consecutive integers |> Seq.filter IsHappy // Keep only the happy ones |> Seq.truncate 8 // Stop when we've found 8</lang>
Factor
<lang factor>USING: combinators kernel make math sequences ;
- squares ( n -- s )
0 [ over 0 > ] [ [ 10 /mod sq ] dip + ] while nip ;
- (happy?) ( n1 n2 -- ? )
[ squares ] [ squares squares ] bi* { { [ dup 1 = ] [ 2drop t ] } { [ 2dup = ] [ 2drop f ] } [ (happy?) ] } cond ;
- happy? ( n -- ? )
dup (happy?) ;
- happy-numbers ( n -- seq )
[ 0 [ over 0 > ] [ dup happy? [ dup , [ 1 - ] dip ] when 1 + ] while 2drop ] { } make ;</lang>
Output: <lang factor>8 happy-numbers ! { 1 7 10 13 19 23 28 31 }</lang>
Fantom
<lang fantom> class Main {
static Bool isHappy (Int n) { Int[] record := [,] while (n != 1 && !record.contains(n)) { record.add (n) // find sum of squares of digits newn := 0 while (n > 0) { newn += (n.mod(10) * n.mod(10)) n = n.div(10) } n = newn } return (n == 1) }
public static Void main () { i := 1 count := 0 while (count < 8) { if (isHappy (i)) { echo (i) count += 1 } i += 1 } }
} </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>
Fortran
<lang fortran>program happy
implicit none integer, parameter :: find = 8 integer :: found integer :: number
found = 0 number = 1 do if (found == find) then exit end if if (is_happy (number)) then found = found + 1 write (*, '(i0)') number end if number = number + 1 end do
contains
function sum_digits_squared (number) result (result)
implicit none integer, intent (in) :: number integer :: result integer :: digit integer :: rest integer :: work
result = 0 work = number do if (work == 0) then exit end if rest = work / 10 digit = work - 10 * rest result = result + digit * digit work = rest end do
end function sum_digits_squared
function is_happy (number) result (result)
implicit none integer, intent (in) :: number logical :: result integer :: turtoise integer :: hare
turtoise = number hare = number do turtoise = sum_digits_squared (turtoise) hare = sum_digits_squared (sum_digits_squared (hare)) if (turtoise == hare) then exit end if end do result = turtoise == 1
end function is_happy
end program happy</lang> Output: <lang>1 7 10 13 19 23 28 31</lang>
Go
<lang go>package main
import (
"fmt" "strconv"
)
func happy(n int) bool {
m := make(map[int]int) for n > 1 { m[n] = 0 s := strconv.Itoa(n) n = 0 for _, d := range s { x := d - '0' n += x * x } if _, ok := m[n]; ok { return false } } return true
}
func main() {
for found, n := 0, 1; found < 8; n++ { if happy(n) { fmt.Print(n, " ") found++ } } fmt.Println("")
}</lang> Output:
1 7 10 13 19 23 28 31
Haskell
<lang haskell>import Data.Char (digitToInt) import Data.Set (member, insert, empty)
isHappy :: Integer -> Bool isHappy = p empty
where p _ 1 = True p s n | n `member` s = False | otherwise = p (insert n s) (f n) f = sum . map ((^2) . toInteger . digitToInt) . show
main = mapM_ print $ take 8 $ filter isHappy [1..]</lang>
Icon and Unicon
<lang Icon>procedure main(arglist) local n n := arglist[1] | 8 # limiting number of happy numbers to generate, default=8 writes("The first ",n," happy numbers are:") every writes(" ", happy(seq()) \ n ) write() end
procedure happy(i) #: returns i if i is happy local n
if 4 ~= (0 <= i) then { # unhappy if negative, 0, or 4 if i = 1 then return i every (n := 0) +:= !i ^ 2 if happy(n) then return i }
end</lang>
Usage and Output:
| happynum.exe The first 8 happy numbers are: 1 7 10 13 19 23 28 31
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>
K
<lang k>
hpy: {x@&1={~|/x=1 4}{_+/_sqr 0$'$x}//:x}
hpy 1+!100
1 7 10 13 19 23 28 31 32 44 49 68 70 79 82 86 91 94 97 100
8#hpy 1+!100
1 7 10 13 19 23 28 31 </lang>
Logo
Liberty BASIC
<lang lb>
ct = 0 n = 0 DO n = n + 1 IF HappyN(n, sqrInt$) = 1 THEN ct = ct + 1 PRINT ct, n END IF LOOP UNTIL ct = 8
END
FUNCTION HappyN(n, sqrInts$)
n$ = Str$(n) sqrInts = 0 FOR i = 1 TO Len(n$) sqrInts = sqrInts + Val(Mid$(n$, i, 1)) ^ 2 NEXT i IF sqrInts = 1 THEN HappyN = 1 EXIT FUNCTION END IF IF Instr(sqrInts$, ":";Str$(sqrInts);":") > 0 THEN HappyN = 0 EXIT FUNCTION END IF sqrInts$ = sqrInts$ + Str$(sqrInts) + ":" HappyN = HappyN(sqrInts, sqrInts$)
END FUNCTION</lang>
Lua
<lang lua>function digits(n)
if n > 0 then return n % 10, digits(math.floor(n/10)) end
end function sumsq(a, ...)
return a and a ^ 2 + sumsq(...) or 0
end local happy = setmetatable({true, false, false, false}, {
__index = function(self, n) self[n] = self[sumsq(digits(n))] return self[n] end } )
i, j = 0, 1 repeat
i, j = happy[j] and (print(j) or i+1) or i, j + 1
until i == 8</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>
MUMPS
<lang MUMPS> ISHAPPY(N)
;Determines if a number N is a happy number ;Note that the returned strings do not have a leading digit unless it is a happy number IF (N'=N\1)!(N<0) QUIT "Not a positive integer" NEW SUM,I ;SUM is the sum of the square of each digit ;I is a loop variable ;SEQ is the sequence of previously checked SUMs from the original N ;If it isn't set already, initialize it to an empty string IF $DATA(SEQ)=0 NEW SEQ SET SEQ="" SET SUM=0 FOR I=1:1:$LENGTH(N) DO .SET SUM=SUM+($EXTRACT(N,I)*$EXTRACT(N,I)) QUIT:(SUM=1) SUM QUIT:$FIND(SEQ,SUM)>1 "Part of a sequence not containing 1" SET SEQ=SEQ_","_SUM QUIT $$ISHAPPY(SUM)
HAPPY(C) ;Finds the first C happy numbers
NEW I ;I is a counter for what integer we're looking at WRITE !,"The first "_C_" happy numbers are:" FOR I=1:1 QUIT:C<1 SET Q=+$$ISHAPPY(I) WRITE:Q !,I SET:Q C=C-1 KILL I QUIT
</lang>
Output:
USER>D HAPPY^ROSETTA(8) The first 8 happy numbers are: 1 7 10 13 19 23 28 31 USER>W:+$$ISHAPPY^ROSETTA(320) "Happy Number" Happy Number USER>W:+$$ISHAPPY^ROSETTA(321) "Happy Number" USER>
OCaml
Using Floyd's cycle-finding algorithm. <lang ocaml>let step = let rec aux s n = if n =/ Int 0 then s else let q = quo_num n (Int 10) and r = mod_num n (Int 10) in aux (s +/ (r */ r)) q in aux (Int 0);;
let happy n = let rec aux x y = if x =/ y then x else aux (step x) (step (step y)) in (aux n (step n)) =/ Int 1;;
let first n = let rec aux v x n = if n = 0 then v else if happy x then aux (x::v) (x +/ Int 1) (n - 1) else aux v (x +/ Int 1) n in aux [ ] (Int 1) n;;
List.rev_map int_of_num (first 8);; (* - : int list = [1; 7; 10; 13; 19; 23; 28; 31] *)</lang>
Objeck
<lang objeck> use IO; use Structure;
bundle Default {
class HappyNumbers { function : native : IsHappy(n : Int) ~ Bool { cache := IntVector->New(); sum := 0; while(n <> 1) { if(cache->Has(n)) { return false; }; cache->AddBack(n); while(n <> 0) { digit := n % 10; sum += (digit * digit); n /= 10; }; n := sum; sum := 0; };
return true; }
function : Main(args : String[]) ~ Nil { num := 1; happynums := IntVector->New();
while(happynums->Size() < 8) { if(IsHappy(num)) { happynums->AddBack(num); }; num += 1; }; Console->GetInstance()->Print("First 8 happy numbers: "); each(i : happynums) { Console->GetInstance()->Print(happynums->Get(i))->Print(","); }; Console->GetInstance()->PrintLine(""); } }
} </lang>
Oz
<lang oz>declare
fun {IsHappy N} {IsHappy2 N nil} end fun {IsHappy2 N Seen} if N == 1 then true elseif {Member N Seen} then false else
Next = {Sum {Map {Digits N} Square}}
in
{IsHappy2 Next N|Seen}
end end
fun {Sum Xs} {FoldL Xs Number.'+' 0} end fun {Digits N} {Map {Int.toString N} fun {$ D} D - &0 end} end fun {Square N} N*N end
fun lazy {Nat I} I|{Nat I+1} end %% List.filter is eager. But we need a lazy Filter: fun lazy {LFilter Xs P} case Xs of X|Xr andthen {P X} then X|{LFilter Xr P} [] _|Xr then {LFilter Xr P} [] nil then nil end end
HappyNumbers = {LFilter {Nat 1} IsHappy}
in
{Show {List.take HappyNumbers 8}}</lang>
PARI/GP
- This code uses the select() function, which was added in PARI version 2.4.2. The order of the arguments changed between versions; to use in 2.4.2 change
select(function, vector)
toselect(vector, function)
.
If the number has more than three digits, the sum of the squares of its digits has fewer digits than the number itself. If the number has three digits, the sum of the squares of its digits is at most 3 * 9^2 = 243. A simple solution is to look up numbers up to 243 and calculate the sum of squares only for larger numbers. <lang parigp>H=[1,7,10,13,19,23,28,31,32,44,49,68,70,79,82,86,91,94,97,100,103,109,129,130,133,139,167,176,188,190,192,193,203,208,219,226,230,236,239]; isHappy(n)={
if(n<262, setsearch(H,n)>0 , n=eval(Vec(Str(n))); isHappy(sum(i=1,#n,n[i]^2)) )
}; select(isHappy, vector(31,i,i))</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; $seen{$n}++ and return 0;}}
for (my ($n, $happy) = (1, 0) ; $happy < 8 ; ++$n)
{is_happy $n or next; print "$n\n"; ++$happy;}</lang>
Perl 6
<lang perl6>sub happy (Int $n is copy returns Bool) {
my %seen; loop { ($n = [+] map * ** 2, $n.comb) == 1 and return True; %seen{$n}++ and return False; }
}
say join ' ', grep(&happy, 1 .. *)[^8]; </lang> Here's another approach that uses a different set of tricks including lazy lists, gather/take, repeat-until, and the cross metaoperator X. <lang perl6>my @happy := gather for 2..* -> $number {
my %stopper = 1 => 1; my $n = $number; repeat until %stopper{$n}++ { $n = [+] $n.comb X** 2; } take $number if $n == 1;
}
say ~@happy[^8]; </lang> There's more than one way to do it...
PHP
<lang php> class happynumber {
/* For example, 7 is happy, as the associated sequence is: 7² = 49 4² + 9² = 97 9² + 7² = 130 1² + 3² + 0² = 10 1² + 0² = 1. */
var $list,$num; static $cache;
function __construct() { $this->list=array(); } static function run($anz,$beg=1) { for($i=0,$x=$beg;$i < $anz;$i++) { while(!$z=happynumber::num($x)) $x++; $x++; echo "\n".$z; } }
function ishappy($num) { $sum=0; $this->list[]=$num; foreach(str_split($num) as $v) { $sum+=($v*$v); } ### if($sum==1)return true; elseif(in_array($sum,$this->list))return false; else return $this->ishappy($sum); }
static function num($p) { $obj=new happynumber(); $out= ($obj->ishappy($p))? $p : false; return $out; }
}
for($a=1;$a<10;$a++) happynumber::run(10,$a*10000);
</lang>
PicoLisp
<lang PicoLisp>(de happy? (N)
(let Seen NIL (loop (T (= N 1) T) (T (member N Seen)) (setq N (apply + (mapcar '((C) (** (format C) 2)) (chop (push 'Seen N)) ) ) ) ) ) )
(let H 0
(do 8 (until (happy? (inc 'H))) (printsp H) ) )</lang>
Output:
1 7 10 13 19 23 28 31
PL/I
<lang PL/I> get list (n); put skip list ('The number is ', n); do i = 1 to 100;
m = 0; do until (n = 0); m = m + mod(n, 10)**2; n = n/10; end; if m = 1 then do; put (' and is a happy number'); stop; end;
end; </lang>
PowerShell
Traditional
<lang PowerShell>function happy([int] $n) {
$a=@() for($i=2;$a.count -lt $n;$i++) { $sum=$i $hist=@{} while( $hist[$sum] -eq $null ) { if($sum -eq 1) { $a+=$i $i } $hist[$sum]=$sum $sum2=0 foreach($j in $sum.ToString().ToCharArray()) { $k=([int]$j)-0x30 $sum2+=$k*$k } $sum=$sum2 } }
}</lang>
With Pipeline
<lang PowerShell>function happy([int] $n) {
1..$n | ForEach-Object { $sum=$_ $hist=@{} while( $hist[$sum] -eq $null ) { if($sum -eq 1) { $_ } $hist[$sum]=$sum $sum2=0 foreach($j in $sum.ToString().ToCharArray()) { $k=([int]$j)-0x30 $sum2+=$k*$k } $sum=$sum2 } }
}</lang>
Prolog
Works with SWI-Prolog <lang Prolog>happy_numbers(L, Nb) :-
% creation of the list length(L, Nb), % Process of this list get_happy_number(L, 1).
% the game is over
get_happy_number([], _).
% querying the newt happy_number get_happy_number([H | T], N) :-
N1 is N+1, (is_happy_number(N) -> H = N, get_happy_number(T, N1); get_happy_number([H | T], N1)).
% we must memorized the numbers reached is_happy_number(N) :-
is_happy_number(N, [N]).
% a number is happy when we get 1 is_happy_number(N, _L) :-
get_next_number(N, 1), !.
% or when this number is not already reached ! is_happy_number(N, L) :-
get_next_number(N, NN), \+member(NN, L), is_happy_number(NN, [NN | L]).
% Process of the next number from N get_next_number(N, NewN) :-
get_list_digits(N, LD), maplist(square, LD, L), sumlist(L, NewN).
get_list_digits(N, LD) :- number_chars(N, LCD), maplist(number_chars_, LD, LCD).
number_chars_(D, CD) :- number_chars(D, [CD]).
square(N, SN) :- SN is N * N.</lang>Output : <lang Prolog> ?- happy_numbers(L, 8). L = [1,7,10,13,19,23,28,31].</lang>
PureBasic
<lang PureBasic>#ToFind=8
- MaxTests=100
Declare is_happy(n)
If OpenConsole()
Define i=1,Happy Repeat If is_happy(i) Happy+1 PrintN("#"+Str(Happy)+RSet(Str(i),3)) EndIf i+1 Until Happy>=#ToFind ; Print(#CRLF$+#CRLF$+"Press ENTER to exit"): Input() CloseConsole()
EndIf
Procedure is_happy(n)
Protected i,j=n,dig,sum Repeat sum=0 While j dig=j%10 j/10 sum+dig*dig Wend If sum=1: ProcedureReturn #True: EndIf j=sum i+1 Until i>#MaxTests ProcedureReturn #False
EndProcedure</lang>
Python
<lang python>>>> def happy(n):
past = set() while True: total = sum(int(i)**2 for i in str(n)) if total == 1: return True if total in past: return False n = total past.add(total)
>>> [x for x in range(1,500) if happy(x)][:8] [1, 7, 10, 13, 19, 23, 28, 31]</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
REXX
<lang REXX> /*REXX program to display the 1st 8 (or specified arg) happy numbers*/
arg limit . /*get argument for LIMIT. */ if limit== then limit=8 /*if not specified, set LIMIT to 8*/ haps=0 /*count of happy numbers so far. */
do n=1 while haps<limit /*search integers starting at one.*/ q=n /*Q may or may not be "happy". */ a.=0
do forever /*see if Q is a happy number. */ if q==1 then do /*if Q is unity, then it's happy*/ haps=haps+1 /*bump the count of happy numbers.*/ say n /*display the number. */ iterate n /*and then keep looking for more. */ end
sum=0 /*initialize sum to zero. */
do j=1 for length(q) /*add the squares of the numerals.*/ sum=sum+substr(q,j,1)**2 end
if a.sum then iterate n /*if already summed, Q is unhappy.*/ a.sum=1 /*mark the sum as being found. */ q=sum /*now, lets try the Q sum. */ end
end
</lang> Sample Output
1 7 10 13 19 23 28 31
Sample output when 100 is specified as the program's argument.
1 7 10 13 19 23 28 31 32 44 49 68 70 79 82 86 91 94 97 100 103 109 129 130 133 139 167 176 188 190 192 193 203 208 219 226 230 236 239 262 263 280 291 293 301 302 310 313 319 320 326 329 331 338 356 362 365 367 368 376 379 383 386 391 392 397 404 409 440 446 464 469 478 487 490 496 536 556 563 565 566 608 617 622 623 632 635 637 638 644 649 653 655 656 665 671 673 680 683 694
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]}
Scala
<lang scala>scala> def isHappy(n: Int) = {
| new Iterator[Int] { | val seen = scala.collection.mutable.Set[Int]() | var curr = n | def next = { | val res = curr | curr = res.toString.map(_.asDigit).map(n => n * n).sum | seen += res | res | } | def hasNext = !seen.contains(curr) | }.toList.last == 1 | }
isHappy: (n: Int)Boolean
scala> Iterator from 1 filter isHappy take 8 foreach println 1 7 10 13 19 23 28 31 </lang>
Scheme
<lang scheme>(define (number->list num)
(do ((num num (quotient num 10)) (lst '() (cons (remainder num 10) lst))) ((zero? num) lst)))
(define (happy? num)
(let loop ((num num) (seen '())) (cond ((= num 1) #t) ((memv num seen) #f) (else (loop (apply + (map (lambda (x) (* x x)) (number->list num))) (cons num seen))))))
(display "happy numbers:") (let loop ((n 1) (more 8))
(cond ((= more 0) (newline)) ((happy? n) (display " ") (display n) (loop (+ n 1) (- more 1))) (else (loop (+ n 1) more))))</lang>
The output is:
happy numbers: 1 7 10 13 19 23 28 31
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}
UNIX Shell
<lang bash>#!/bin/bash function sum_of_square_digits {
local -i n="$1" sum=0 while (( n )); do local -i d=n%10 let sum+=d*d let n=n/10 done echo "$sum"
}
function is_happy? {
local -i n="$1" local seen=() while (( n != 1 )); do if [ -n "${seen[$n]}" ]; then return 1 fi seen[n]=1 let n="$(sum_of_square_digits "$n")" done return 0
}
function first_n_happy {
local -i count="$1" local -i n for (( n=0; count; n+=1 )); do if is_happy? "$n"; then echo "$n" let count-=1 fi done return 0
}
first_n_happy 8</lang>
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>
Visual Basic .NET
This version uses Linq to carry out the calculations. <lang Visual Basic .NET>Module HappyNumbers
Sub Main() Dim n As Integer = 1 Dim found As Integer = 0
Do Until found = 8 If IsHappy(n) Then found += 1 Console.WriteLine("{0}: {1}", found, n) End If n += 1 Loop
Console.ReadLine() End Sub
Private Function IsHappy(ByVal n As Integer) Dim cache As New List(Of Long)()
Do Until n = 1 cache.Add(n) n = Aggregate c In n.ToString() _ Into Total = Sum(Int32.Parse(c) ^ 2) If cache.Contains(n) Then Return False Loop
Return True End Function
End Module</lang> The output is:
1: 1 2: 7 3: 10 4: 13 5: 19 6: 23 7: 28 8: 31
- Programming Tasks
- Arithmetic operations
- ActionScript
- Ada
- ALGOL 68
- APL
- AutoHotkey
- AWK
- BBC BASIC
- Brat
- C
- C++
- C sharp
- Clojure
- Common Lisp
- D
- Dc
- E
- Erlang
- F Sharp
- Factor
- Fantom
- Forth
- Fortran
- Go
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- K
- Logo
- Liberty BASIC
- Lua
- Mathematica
- MUMPS
- OCaml
- Objeck
- Oz
- PARI/GP
- Perl
- Perl 6
- PHP
- PicoLisp
- PL/I
- PowerShell
- Prolog
- PureBasic
- Python
- R
- REXX
- Ruby
- Scala
- Scheme
- Smalltalk
- Tcl
- UNIX Shell
- Ursala
- Visual Basic .NET