Happy numbers

From Rosetta Code

(Redirected from Happy Number)
Jump to: navigation, search
Task
Happy numbers
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.

Contents

[edit] 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();

[edit] 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;

Sample output:

 1 7 10 13 19 23 28 31

[edit] ALGOL 68

Works with: ALGOL 68 version Standard - no extensions to language used Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386 Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386

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

Output:

         +1
         +7
        +10
        +13
        +19
        +23
        +28
        +31

[edit] 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)
}

[edit] 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
}
}
}

[edit] 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;
}

[edit] C++

Translation of: Python

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

Alternative version without caching:

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

Cycle detection in is_happy() above is done using Floyd's cycle-finding algorithm.

[edit] C#

 
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));
}
}
}
 
First 8 happy numbers : 1,7,10,13,19,23,28,31

[edit] 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))

[edit] Common 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))

[edit] D

D V.2

import std.range, std.conv, std.stdio, std.algorithm;
 
bool isHappy(int n) {
int[int] past; // a set
while (true) {
int total;
foreach (digit; to!string(n))
total += to!int(to!string(digit)) ^^ 2;
if (total == 1 || total in past)
return total !in past;
n = total;
past[total] = 0; // add total to the set
}
}
 
void main() {
auto h = filter!(isHappy)(iota(1, int.max));
writeln(array(take(h, 8)));
}

Output:

1 7 10 13 19 23 28 31

[edit] 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 }
}

[edit] 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, []).
 
Command:
erl -run tasks main -run init stop -noshell
Output:
8 Happy Numbers: [1,7,10,13,19,23,28,31]

[edit] F#

This requires the F# power pack to be referenced and the 2010 beta of F#

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

[edit] 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

[edit] 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

Output:

1
7
10
13
19
23
28
31

[edit] 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..]

[edit] Icon and Unicon

[edit] 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 <= integer( \i)) then # unhappy if negative, 0, or 4
if 1 = i then return i
else {
n := 0
i ? while n +:= move(1) ^ 2
if happy(n) then return i
}
end

Usage and Output:

| happynum.exe 

The first 8 happy numbers are: 1 7 10 13 19 23 28 31

[edit] Unicon

This slight variant on the Icon solution also works in Icon:

procedure main(arglist)
n := integer(arglist[1]) | 8 # limit 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
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

[edit] J

   8{. (#~1=+/@(*:@(,.&.":))^:(1&~:*.4&~:)^:_ "0) 1+i.100
1 7 10 13 19 23 28 31

This is a repeat while construction

 f ^: cond ^: _   input

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.

 (binary array) # 1..100

So for easier reading the solution could be expressed as:

   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

[edit] Java

Works with: Java version 1.5+

Translation of: JavaScript

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

[edit] 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++ ;
}

[edit] Liberty BASIC

 
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

[edit] 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

[edit] Mathematica

Custom function HappyQ:

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

Examples for a specific number:

HappyQ[1337]
HappyQ[137]

gives back:

True
False

Example finding the first 8:

m = 8;
n = 1;
i = 0;
happynumbers = {};
While[n <= m,
i++;
If[HappyQ[i],
n++;
AppendTo[happynumbers, i]
]
]
happynumbers

gives back:

{1, 7, 10, 13, 19, 23, 28, 31}


[edit] 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
 
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>

[edit] 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("");
}
}
}
 

[edit] 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}}

[edit] 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;}

[edit] Perl 6

Works with: Rakudo version 2010.07

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

Here's another approach that uses a different set of tricks including lazy lists, gather/take, repeat-until, and the cross metaoperator X.

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

There's more than one way to do it...

[edit] 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);
 
 

[edit] 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) ) )

Output:

1 7 10 13 19 23 28 31

[edit] 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;
 

[edit] PureBasic

Works with: PureBasic version 4.41

#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

[edit] 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]

[edit] 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
}

Example usage

is.happy(2)
[1] FALSE
attr(,"cycle")
[1]   4  16  37  58  89 145  42  20
#Find happy numbers between 1 and 50
which(apply(rbind(1:50), 2, is.happy))
1  7 10 13 19 23 28 31 32 44 49
#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
1  7 10 13 19 23 28 31

[edit] REXX

count = 0
do zahl = 1 by 1 until count = 8
t = zahl
all_sums = ""
do forever
sum = 0
do i = 1 to length(t)
z = substr(t,i,1)
sum = sum + z*z
end
if t = 1 | pos(sum,all_sums) > 0 then leave
t = sum
all_sums = all_sums sum
end
if sum = 1 then do
say zahl
count = count + 1
end
end

[edit] Ruby

Use of cache from Python

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
[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]}

[edit] 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
 

[edit] 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))))

The output is:

happy numbers: 1 7 10 13 19 23 28 31

[edit] Smalltalk

Works with: GNU Smalltalk

Translation of: Python

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.

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
]
]
].
|happy|
happy := HappyNumber new.
 
1 to: 30 do: [ :i |
(happy isHappy: i)
ifTrue: [ i displayNl ]
].

[edit] Tcl

using code from Sum of squares#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]"
the first 8 happy numbers are: {1 7 10 13 19 23 28 31}

[edit] 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.

#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

output:

<1,7,10,13,19,23,28,31>
Personal tools
Support