Happy numbers: Difference between revisions
PascalABC.NET |
|||
(512 intermediate revisions by more than 100 users not shown) | |||
Line 1: | Line 1: | ||
{{task|Arithmetic operations}} |
{{task|Arithmetic operations}} |
||
From Wikipedia, the free encyclopedia: |
From Wikipedia, the free encyclopedia: |
||
:: A [[wp:Happy number|happy number]] is defined by the following process: |
|||
:A [[wp:Happy number|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. |
|||
:: 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'''. |
|||
'''Task:''' Find and print the first 8 happy numbers. |
|||
<br> |
|||
:: Those numbers for which this process end in '''1''' are ''happy'' numbers, |
|||
:: while those numbers that do <u>not</u> end in '''1''' are ''unhappy'' numbers. |
|||
;Task: |
|||
Find and print the first '''8''' happy numbers. |
|||
Display an example of your output here on this page. |
|||
;Related tasks: |
|||
* [[Iterated digits squaring]] |
|||
;See also: |
|||
* The OEIS entry: [[oeis:A007770|The happy numbers: A007770]] |
|||
* The OEIS entry: [[oeis:A031177|The unhappy numbers; A031177]] |
|||
<br><br> |
|||
=={{header|11l}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="11l">F happy(=n) |
|||
Set[Int] past |
|||
L n != 1 |
|||
n = sum(String(n).map(с -> Int(с)^2)) |
|||
I n C past |
|||
R 0B |
|||
past.add(n) |
|||
R 1B |
|||
print((0.<500).filter(x -> happy(x))[0.<8])</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[1, 7, 10, 13, 19, 23, 28, 31] |
|||
</pre> |
|||
=={{header|8080 Assembly}}== |
|||
This is not just a demonstration of 8080 assembly, but also of why it pays to look closely at the problem domain. |
|||
The following program only does 8-bit unsigned integer math, which not only fits the 8080's instruction set very well, |
|||
it also means the cycle detection can be done using only an array of 256 flags, and all other state |
|||
fits in the registers. This makes the program a good deal simpler than it would've been otherwise. |
|||
In general, 8-bit math is not good enough for numerical problems, but in this particular case, |
|||
the problem only asks for the first eight happy numbers, none of which (nor any of the unhappy numbers |
|||
in between) have a cycle that ever goes above 145, so eight bits is good enough. In fact, for any input |
|||
under 256, the cycle never goes above 163; this program could be trivially changed to print up to 39 happy numbers. |
|||
<syntaxhighlight lang="8080asm">flags: equ 2 ; 256-byte page in which to keep track of cycles |
|||
puts: equ 9 ; CP/M print string |
|||
bdos: equ 5 ; CP/M entry point |
|||
org 100h |
|||
lxi d,0108h ; D=current number to test, E=amount of numbers |
|||
;;; Is D happy? |
|||
number: mvi a,1 ; We haven't seen any numbers yet, set flags to 1 |
|||
lxi h,256*flags |
|||
init: mov m,a |
|||
inr l |
|||
jnz init |
|||
mov a,d ; Get digits |
|||
step: call digits |
|||
mov l,a ; L = D1 * D1 |
|||
mov h,a |
|||
xra a |
|||
sqr1: add h |
|||
dcr l |
|||
jnz sqr1 |
|||
mov l,a |
|||
mov h,b ; L += D10 * D10 |
|||
xra a |
|||
sqr10: add h |
|||
dcr b |
|||
jnz sqr10 |
|||
add l |
|||
mov l,a |
|||
mov h,c ; L += D100 * D100 |
|||
xra a |
|||
sqr100: add h |
|||
dcr c |
|||
jnz sqr100 |
|||
add l |
|||
mov l,a |
|||
mvi h,flags ; Look up corresponding flag |
|||
dcr m ; Will give 0 the first time and not-0 afterwards |
|||
mov a,l ; If we haven't seen the number before, another step |
|||
jz step |
|||
dcr l ; If we _had_ seen it, then is it 1? |
|||
jz happy ; If so, it is happy |
|||
next: inr d ; Afterwards, try next number |
|||
jmp number |
|||
happy: mov a,d ; D is happy - get its digits (for output) |
|||
lxi h,string+3 |
|||
call digits ; Write digits into string for output |
|||
call sdgt ; Ones digit, |
|||
mov a,b ; Tens digit, |
|||
call sdgt |
|||
mov a,c ; Hundreds digit |
|||
call sdgt |
|||
push d ; Keep counters on stack |
|||
mvi c,puts ; Print string using CP/M call |
|||
xchg |
|||
call bdos |
|||
pop d ; Restore counters |
|||
dcr e ; One fewer happy number left |
|||
jnz next ; If we need more, do the next one |
|||
ret |
|||
;;; Store A as ASCII digit in [HL] and go to previous digit |
|||
sdgt: adi '0' |
|||
dcx h |
|||
mov m,a |
|||
ret |
|||
;;; Get digits of 8-bit number in A. |
|||
;;; Input: A = number |
|||
;;; Output: C=100s digit, B=10s digit, A=1s digit |
|||
digits: lxi b,-1 ; Set B and C to -1 (correct for extra loop cycle) |
|||
d100: inr c ; Calculate hundreds digit |
|||
sui 100 ; By trial subtraction of 100 |
|||
jnc d100 ; Until underflow occurs |
|||
adi 100 ; Loop runs one cycle too many, so add 100 back |
|||
d10: inr b ; Calculate 10s digit in the same way |
|||
sui 10 |
|||
jnc d10 |
|||
adi 10 |
|||
ret ; 1s digit is left in A afterwards |
|||
string: db '000',13,10,'$'</syntaxhighlight> |
|||
{{out}} |
|||
<pre>001 |
|||
007 |
|||
010 |
|||
013 |
|||
019 |
|||
023 |
|||
028 |
|||
031</pre> |
|||
=={{header|8th}}== |
|||
<syntaxhighlight lang="8th"> |
|||
: until! "not while!" eval i; |
|||
with: w |
|||
with: n |
|||
: sumsqd \ n -- n |
|||
0 swap repeat |
|||
0; 10 /mod -rot sqr + swap |
|||
again ; |
|||
: cycle \ n xt -- n |
|||
>r |
|||
dup r@ exec \ -- tortoise, hare |
|||
repeat |
|||
swap r@ exec |
|||
swap r@ exec r@ exec |
|||
2dup = until! |
|||
rdrop drop ; |
|||
: happy? ' sumsqd cycle 1 = ; |
|||
: .happy \ n -- |
|||
1 repeat |
|||
dup happy? if dup . space swap 1- swap then 1+ |
|||
over 0 > while! |
|||
2drop cr ; |
|||
;with |
|||
;with |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
ok> 8 .happy |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|ABC}}== |
|||
<syntaxhighlight lang="ABC">HOW TO RETURN square.digit.sum n: |
|||
PUT 0 IN sum |
|||
WHILE n>0: |
|||
PUT n mod 10 IN digit |
|||
PUT sum + digit ** 2 IN sum |
|||
PUT floor (n/10) IN n |
|||
RETURN sum |
|||
HOW TO REPORT happy n: |
|||
PUT {} IN seen |
|||
WHILE n not.in seen: |
|||
INSERT n IN seen |
|||
PUT square.digit.sum n IN n |
|||
REPORT n=1 |
|||
HOW TO RETURN next.happy n: |
|||
PUT n+1 IN n |
|||
WHILE NOT happy n: PUT n+1 IN n |
|||
RETURN n |
|||
PUT 0 IN n |
|||
FOR i IN {1..8}: |
|||
PUT next.happy n IN n |
|||
WRITE n/</syntaxhighlight> |
|||
{{out}} |
|||
<Pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|ACL2}}== |
|||
<syntaxhighlight lang="lisp">(include-book "arithmetic-3/top" :dir :system) |
|||
(defun sum-of-digit-squares (n) |
|||
(if (zp n) |
|||
0 |
|||
(+ (expt (mod n 10) 2) |
|||
(sum-of-digit-squares (floor n 10))))) |
|||
(defun is-happy-r (n seen) |
|||
(let ((next (sum-of-digit-squares n))) |
|||
(cond ((= next 1) t) |
|||
((member next seen) nil) |
|||
(t (is-happy-r next (cons next seen)))))) |
|||
(defun is-happy (n) |
|||
(is-happy-r n nil)) |
|||
(defun first-happy-nums-r (n i) |
|||
(cond ((zp n) nil) |
|||
((is-happy i) |
|||
(cons i (first-happy-nums-r (1- n) (1+ i)))) |
|||
(t (first-happy-nums-r n (1+ i))))) |
|||
(defun first-happy-nums (n) |
|||
(first-happy-nums-r n 1))</syntaxhighlight> |
|||
Output: |
|||
<pre>(1 7 10 13 19 23 28 31)</pre> |
|||
=={{header|Action!}}== |
|||
<syntaxhighlight lang="action!">BYTE FUNC SumOfSquares(BYTE x) |
|||
BYTE sum,d |
|||
sum=0 |
|||
WHILE x#0 |
|||
DO |
|||
d=x MOD 10 |
|||
d==*d |
|||
sum==+d |
|||
x==/10 |
|||
OD |
|||
RETURN (sum) |
|||
BYTE FUNC Contains(BYTE ARRAY a BYTE count,x) |
|||
BYTE i |
|||
FOR i=0 TO count-1 |
|||
DO |
|||
IF a(i)=x THEN RETURN (1) FI |
|||
OD |
|||
RETURN (0) |
|||
BYTE FUNC IsHappyNumber(BYTE x) |
|||
BYTE ARRAY cache(100) |
|||
BYTE count |
|||
count=0 |
|||
WHILE x#1 |
|||
DO |
|||
cache(count)=x |
|||
count==+1 |
|||
x=SumOfSquares(x) |
|||
IF Contains(cache,count,x) THEN |
|||
RETURN (0) |
|||
FI |
|||
OD |
|||
RETURN (1) |
|||
PROC Main() |
|||
BYTE x,count |
|||
x=1 count=0 |
|||
WHILE count<8 |
|||
DO |
|||
IF IsHappyNumber(x) THEN |
|||
count==+1 |
|||
PrintF("%I: %I%E",count,x) |
|||
FI |
|||
x==+1 |
|||
OD |
|||
RETURN</syntaxhighlight> |
|||
{{out}} |
|||
[https://gitlab.com/amarok8bit/action-rosetta-code/-/raw/master/images/Happy_numbers.png Screenshot from Atari 8-bit computer] |
|||
<pre> |
|||
1: 1 |
|||
2: 7 |
|||
3: 10 |
|||
4: 13 |
|||
5: 19 |
|||
6: 23 |
|||
7: 28 |
|||
8: 31 |
|||
</pre> |
|||
=={{header|ActionScript}}== |
|||
<syntaxhighlight 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();</syntaxhighlight> |
|||
Sample output: |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
=={{header|Ada}}== |
=={{header|Ada}}== |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; use Ada.Text_IO; |
||
with Ada.Containers.Ordered_Sets; |
with Ada.Containers.Ordered_Sets; |
||
Line 46: | Line 407: | ||
end if; |
end if; |
||
end loop; |
end loop; |
||
end Test_Happy_Digits;</ |
end Test_Happy_Digits;</syntaxhighlight> |
||
Sample output: |
Sample output: |
||
<pre> |
<pre> |
||
Line 56: | Line 417: | ||
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}} |
{{works with|ALGOL 68G|Any - tested with release mk15-0.8b.fc9.i386}} |
||
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}} |
{{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386}} |
||
< |
<syntaxhighlight lang="algol68">INT base10 = 10, num happy = 8; |
||
PROC next = (INT in n)INT: ( |
PROC next = (INT in n)INT: ( |
||
Line 80: | Line 441: | ||
print((i, new line)) |
print((i, new line)) |
||
FI |
FI |
||
OD</ |
OD</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 92: | Line 453: | ||
+31 |
+31 |
||
</pre> |
</pre> |
||
=={{header|ALGOL-M}}== |
|||
<syntaxhighlight lang="algolm">begin |
|||
integer function mod(a,b); |
|||
integer a,b; |
|||
mod := a-(a/b)*b; |
|||
integer function sumdgtsq(n); |
|||
integer n; |
|||
sumdgtsq := |
|||
if n = 0 then 0 |
|||
else mod(n,10)*mod(n,10) + sumdgtsq(n/10); |
|||
integer function happy(n); |
|||
integer n; |
|||
begin |
|||
integer i; |
|||
integer array seen[0:200]; |
|||
for i := 0 step 1 until 200 do seen[i] := 0; |
|||
while seen[n] = 0 do |
|||
begin |
|||
seen[n] := 1; |
|||
n := sumdgtsq(n); |
|||
end; |
|||
happy := if n = 1 then 1 else 0; |
|||
end; |
|||
integer i, n; |
|||
i := n := 0; |
|||
while n < 8 do |
|||
begin |
|||
if happy(i) = 1 then |
|||
begin |
|||
write(i); |
|||
n := n + 1; |
|||
end; |
|||
i := i + 1; |
|||
end; |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|ALGOL W}}== |
|||
<syntaxhighlight lang="algolw"> |
|||
begin % find some happy numbers: numbers whose digit-square sums become 1 % |
|||
% when repeatedly applied % |
|||
% returns true if n is happy, false otherwise % |
|||
logical procedure isHappy ( integer value n ) ; |
|||
begin |
|||
% in base ten, numbers either reach 1 or loop around a sequence % |
|||
% containing 4 (see the Wikipedia article) % |
|||
integer v, dSum, d; |
|||
v := abs n; |
|||
if v > 1 then begin |
|||
while begin |
|||
dSum := 0; |
|||
while v not = 0 do begin |
|||
d := v rem 10; |
|||
v := v div 10; |
|||
dSum := dSum + ( d * d ) |
|||
end while_v_ne_0 ; |
|||
v := dSum; |
|||
v not = 1 and v not = 4 |
|||
end do begin end |
|||
end if_v_ne_0 ; |
|||
v = 1 |
|||
end isHappy ; |
|||
begin % find the first 8 happy numbers % |
|||
integer n, hCount; |
|||
hCount := 0; |
|||
n := 1; |
|||
while hCount < 8 do begin |
|||
if isHappy( n ) then begin |
|||
writeon( i_w := 1, s_w := 0, " ", n ); |
|||
hCount := hCount + 1 |
|||
end if_isHappy__n ; |
|||
n := n + 1 |
|||
end while_hCount_lt_10 |
|||
end |
|||
end. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|APL}}== |
|||
===Tradfn=== |
|||
<syntaxhighlight 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 |
|||
∇</syntaxhighlight> |
|||
<pre> |
|||
HappyNumbers 100 8 |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
===Dfn=== |
|||
<syntaxhighlight lang="apl"> |
|||
HappyNumbers←{ ⍝ return the first ⍵ Happy Numbers |
|||
⍺←⍬ ⍝ initial list |
|||
⍵=+/⍺:⍸⍺ ⍝ 1's mark happy numbers |
|||
sq←×⍨ ⍝ square function (times selfie) |
|||
isHappy←{ ⍝ is ⍵ a happy number? |
|||
⍺←⍬ ⍝ previous sums |
|||
⍵=1:1 ⍝ if we get to 1, it's happy |
|||
n←+/sq∘⍎¨⍕⍵ ⍝ sum of the square of the digits |
|||
n∊⍺:0 ⍝ if we hit this sum before, it's not happy |
|||
(⍺,n)∇ n} ⍝ recurse until it's happy or not |
|||
(⍺,isHappy 1+≢⍺)∇ ⍵ ⍝ recurse until we have ⍵ happy numbers |
|||
} |
|||
HappyNumbers 8 |
|||
1 7 10 13 19 23 28 31 |
|||
</syntaxhighlight> |
|||
=={{header|AppleScript}}== |
|||
===Iteration=== |
|||
<syntaxhighlight lang="applescript">on run |
|||
set howManyHappyNumbers to 8 |
|||
set happyNumberList to {} |
|||
set globalCounter to 1 |
|||
repeat howManyHappyNumbers times |
|||
repeat while not isHappy(globalCounter) |
|||
set globalCounter to globalCounter + 1 |
|||
end repeat |
|||
set end of happyNumberList to globalCounter |
|||
set globalCounter to globalCounter + 1 |
|||
end repeat |
|||
log happyNumberList |
|||
end run |
|||
on isHappy(numberToCheck) |
|||
set localCycle to {} |
|||
repeat while (numberToCheck ≠ 1) |
|||
if localCycle contains numberToCheck then |
|||
exit repeat |
|||
end if |
|||
set end of localCycle to numberToCheck |
|||
set tempNumber to 0 |
|||
repeat while (numberToCheck > 0) |
|||
set digitOfNumber to numberToCheck mod 10 |
|||
set tempNumber to tempNumber + (digitOfNumber ^ 2) |
|||
set numberToCheck to (numberToCheck - digitOfNumber) / 10 |
|||
end repeat |
|||
set numberToCheck to tempNumber |
|||
end repeat |
|||
return (numberToCheck = 1) |
|||
end isHappy</syntaxhighlight> |
|||
<pre> |
|||
Result: (*1, 7, 10, 13, 19, 23, 28, 31*) |
|||
</pre> |
|||
===Functional composition=== |
|||
{{Trans|JavaScript}} |
|||
{{Trans|Haskell}} |
|||
<syntaxhighlight lang="applescript">---------------------- HAPPY NUMBERS ----------------------- |
|||
-- isHappy :: Int -> Bool |
|||
on isHappy(n) |
|||
-- endsInOne :: [Int] -> Int -> Bool |
|||
script endsInOne |
|||
-- sumOfSquaredDigits :: Int -> Int |
|||
script sumOfSquaredDigits |
|||
-- digitSquared :: Int -> Int -> Int |
|||
script digitSquared |
|||
on |λ|(a, x) |
|||
(a + (x as integer) ^ 2) as integer |
|||
end |λ| |
|||
end script |
|||
on |λ|(n) |
|||
foldl(digitSquared, 0, splitOn("", n as string)) |
|||
end |λ| |
|||
end script |
|||
-- [Int] -> Int -> Bool |
|||
on |λ|(s, n) |
|||
if n = 1 then |
|||
true |
|||
else |
|||
if s contains n then |
|||
false |
|||
else |
|||
|λ|(s & n, |λ|(n) of sumOfSquaredDigits) |
|||
end if |
|||
end if |
|||
end |λ| |
|||
end script |
|||
endsInOne's |λ|({}, n) |
|||
end isHappy |
|||
--------------------------- TEST --------------------------- |
|||
on run |
|||
-- seriesLength :: {n:Int, xs:[Int]} -> Bool |
|||
script seriesLength |
|||
property target : 8 |
|||
on |λ|(rec) |
|||
length of xs of rec = target of seriesLength |
|||
end |λ| |
|||
end script |
|||
-- succTest :: {n:Int, xs:[Int]} -> {n:Int, xs:[Int]} |
|||
script succTest |
|||
on |λ|(rec) |
|||
tell rec to set {xs, n} to {its xs, its n} |
|||
script testResult |
|||
on |λ|(x) |
|||
if isHappy(x) then |
|||
xs & x |
|||
else |
|||
xs |
|||
end if |
|||
end |λ| |
|||
end script |
|||
{n:n + 1, xs:testResult's |λ|(n)} |
|||
end |λ| |
|||
end script |
|||
xs of |until|(seriesLength, succTest, {n:1, xs:{}}) |
|||
--> {1, 7, 10, 13, 19, 23, 28, 31} |
|||
end run |
|||
-------------------- GENERIC FUNCTIONS --------------------- |
|||
-- foldl :: (a -> b -> a) -> a -> [b] -> a |
|||
on foldl(f, startValue, xs) |
|||
tell mReturn(f) |
|||
set v to startValue |
|||
set lng to length of xs |
|||
repeat with i from 1 to lng |
|||
set v to |λ|(v, item i of xs, i, xs) |
|||
end repeat |
|||
return v |
|||
end tell |
|||
end foldl |
|||
-- Lift 2nd class handler function into 1st class script wrapper |
|||
-- mReturn :: Handler -> Script |
|||
on mReturn(f) |
|||
if class of f is script then |
|||
f |
|||
else |
|||
script |
|||
property |λ| : f |
|||
end script |
|||
end if |
|||
end mReturn |
|||
-- splitOn :: String -> String -> [String] |
|||
on splitOn(pat, src) |
|||
set {dlm, my text item delimiters} to ¬ |
|||
{my text item delimiters, pat} |
|||
set xs to text items of src |
|||
set my text item delimiters to dlm |
|||
return xs |
|||
end splitOn |
|||
-- until :: (a -> Bool) -> (a -> a) -> a -> a |
|||
on |until|(p, f, x) |
|||
set mp to mReturn(p) |
|||
set v to x |
|||
tell mReturn(f) |
|||
repeat until mp's |λ|(v) |
|||
set v to |λ|(v) |
|||
end repeat |
|||
end tell |
|||
return v |
|||
end |until|</syntaxhighlight> |
|||
{{Out}} |
|||
<syntaxhighlight lang="applescript">{1, 7, 10, 13, 19, 23, 28, 31}</syntaxhighlight> |
|||
=={{header|Arturo}}== |
|||
{{trans|Nim}} |
|||
<syntaxhighlight lang="rebol">ord0: to :integer `0` |
|||
happy?: function [x][ |
|||
n: x |
|||
past: new [] |
|||
while [n <> 1][ |
|||
s: to :string n |
|||
n: 0 |
|||
loop s 'c [ |
|||
i: (to :integer c) - ord0 |
|||
n: n + i * i |
|||
] |
|||
if contains? past n -> return false |
|||
'past ++ n |
|||
] |
|||
return true |
|||
] |
|||
loop 0..31 'x [ |
|||
if happy? x -> print x |
|||
]</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang="autohotkey">Loop { |
||
If isHappy(A_Index) { |
If isHappy(A_Index) { |
||
out .= (out="" ? "" : ",") . A_Index |
out .= (out="" ? "" : ",") . A_Index |
||
Line 114: | Line 823: | ||
Return false |
Return false |
||
Else Return isHappy(sum, list) |
Else Return isHappy(sum, list) |
||
}</ |
}</syntaxhighlight> |
||
<pre> |
|||
The first 8 happy numbers are: 1,7,10,13,19,23,28,31 |
|||
</pre> |
|||
===Alternative version=== |
|||
<syntaxhighlight lang="autohotkey">while h < 8 |
|||
if (Happy(A_Index)) { |
|||
Out .= A_Index A_Space |
|||
h++ |
|||
} |
|||
MsgBox, % Out |
|||
Happy(n) { |
|||
=={{header|AWK}}== |
|||
Loop, { |
|||
Loop, Parse, n |
|||
t += A_LoopField ** 2 |
|||
if (t = 89) |
|||
return, 0 |
|||
if (t = 1) |
|||
return, 1 |
|||
n := t, t := 0 |
|||
} |
|||
}</syntaxhighlight> |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
=={{header|AutoIt}}== |
|||
<lang awk>function is_happy(n) |
|||
<syntaxhighlight lang="autoit"> |
|||
$c = 0 |
|||
$k = 0 |
|||
While $c < 8 |
|||
$k += 1 |
|||
$n = $k |
|||
While $n <> 1 |
|||
$s = StringSplit($n, "") |
|||
$t = 0 |
|||
For $i = 1 To $s[0] |
|||
$t += $s[$i] ^ 2 |
|||
Next |
|||
$n = $t |
|||
Switch $n |
|||
Case 4,16,37,58,89,145,42,20 |
|||
ExitLoop |
|||
EndSwitch |
|||
WEnd |
|||
If $n = 1 Then |
|||
ConsoleWrite($k & " is Happy" & @CRLF) |
|||
$c += 1 |
|||
EndIf |
|||
WEnd |
|||
</syntaxhighlight> |
|||
<pre> |
|||
Use a set of numbers (4,16,37,58,89,145,42,20) to indicate a loop and exit. |
|||
Output: |
|||
1 is Happy |
|||
7 is Happy |
|||
10 is Happy |
|||
13 is Happy |
|||
19 is Happy |
|||
23 is Happy |
|||
28 is Happy |
|||
31 is Happy |
|||
</pre> |
|||
===Alternative version=== |
|||
<syntaxhighlight lang="autoit"> |
|||
$c = 0 |
|||
$k = 0 |
|||
While $c < 8 |
|||
$a = ObjCreate("System.Collections.ArrayList") |
|||
$k += 1 |
|||
$n = $k |
|||
While $n <> 1 |
|||
If $a.Contains($n) Then |
|||
ExitLoop |
|||
EndIf |
|||
$a.add($n) |
|||
$s = StringSplit($n, "") |
|||
$t = 0 |
|||
For $i = 1 To $s[0] |
|||
$t += $s[$i] ^ 2 |
|||
Next |
|||
$n = $t |
|||
WEnd |
|||
If $n = 1 Then |
|||
ConsoleWrite($k & " is Happy" & @CRLF) |
|||
$c += 1 |
|||
EndIf |
|||
$a.Clear |
|||
WEnd |
|||
</syntaxhighlight> |
|||
<pre> |
|||
Saves all numbers in a list, duplicate entry indicates a loop. |
|||
Output: |
|||
1 is Happy |
|||
7 is Happy |
|||
10 is Happy |
|||
13 is Happy |
|||
19 is Happy |
|||
23 is Happy |
|||
28 is Happy |
|||
31 is Happy |
|||
</pre> |
|||
=={{header|AWK}}== |
|||
<syntaxhighlight lang="awk">function is_happy(n) |
|||
{ |
{ |
||
if ( n in happy ) return 1; |
if ( n in happy ) return 1; |
||
Line 158: | Line 968: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Result: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
===Alternative version=== |
|||
=={{header|C}}== |
|||
Alternately, for legibility one might write: |
|||
<lang c>#include <stdio.h> |
|||
#include <stdbool.h> |
|||
#include <stdlib.h> |
|||
#include <string.h> |
|||
#include <assert.h> |
|||
<syntaxhighlight lang="awk">BEGIN { |
|||
typedef struct list { |
|||
for (i = 1; i < 50; ++i){ |
|||
int val; |
|||
if (isHappy(i)) { |
|||
struct list *next; |
|||
print i; |
|||
} list_t; |
|||
} |
|||
} |
|||
exit |
|||
} |
|||
function isHappy(n, seen) { |
|||
bool in_cycle(list_t *c, int n) |
|||
delete seen; |
|||
while (1) { |
|||
n = sumSqrDig(n) |
|||
if (seen[n]) { |
|||
return n == 1 |
|||
} |
|||
seen[n] = 1 |
|||
} |
|||
} |
|||
function sumSqrDig(n, d, tot) { |
|||
while (n) { |
|||
d = n % 10 |
|||
tot += d * d |
|||
n = int(n/10) |
|||
} |
|||
return tot |
|||
}</syntaxhighlight> |
|||
=={{header|BASIC}}== |
|||
==={{header|Applesoft BASIC}}=== |
|||
<syntaxhighlight lang="gwbasic"> 0 C = 8: DIM S(16):B = 10: PRINT "THE FIRST "C" HAPPY NUMBERS": FOR R = C TO 0 STEP 0:N = H: GOSUB 1: PRINT MID$ (" " + STR$ (H),1 + (R = C),255 * I);:R = R - I:H = H + 1: NEXT R: END |
|||
1 S = 0: GOSUB 3:I = N = 1: IF NOT Q THEN RETURN |
|||
2 FOR Q = 1 TO 0 STEP 0:S(S) = N:S = S + 1: GOSUB 6:N = T: GOSUB 3: NEXT Q:I = N = 1: RETURN |
|||
3 Q = N > 1: IF NOT Q OR NOT S THEN RETURN |
|||
4 Q = 0: FOR I = 0 TO S - 1: IF N = S(I) THEN RETURN |
|||
5 NEXT I:Q = 1: RETURN |
|||
6 T = 0: FOR I = N TO 0 STEP 0:M = INT (I / B):T = INT (T + (I - M * B) ^ 2):I = M: NEXT I: RETURN</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
THE FIRST 8 HAPPY NUMBERS |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
==={{header|BASIC256}}=== |
|||
<syntaxhighlight lang="freebasic">n = 1 : cnt = 0 |
|||
print "The first 8 isHappy numbers are:" |
|||
print |
|||
while cnt < 8 |
|||
if isHappy(n) = 1 then |
|||
cnt += 1 |
|||
print cnt; " => "; n |
|||
end if |
|||
n += 1 |
|||
end while |
|||
function isHappy(num) |
|||
isHappy = 0 |
|||
cont = 0 |
|||
while cont < 50 and isHappy <> 1 |
|||
num$ = string(num) |
|||
cont += 1 |
|||
isHappy = 0 |
|||
for i = 1 to length(num$) |
|||
isHappy += int(mid(num$,i,1)) ^ 2 |
|||
next i |
|||
num = isHappy |
|||
end while |
|||
end function</syntaxhighlight> |
|||
==={{header|BBC BASIC}}=== |
|||
{{works with|BBC BASIC for Windows}} |
|||
<syntaxhighlight 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)</syntaxhighlight> |
|||
Output: |
|||
<pre> 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</pre> |
|||
==={{header|Commodore BASIC}}=== |
|||
The array sizes here are tuned to the minimum values required to find the first 8 happy numbers in numerical order. The <tt>H</tt> and <tt>U</tt> arrays are used for memoization, so the subscripts <tt>H(</tt><i>n</i><tt>)</tt> and <tt>U(</tt><i>n</i><tt>)</tt> must exist for the highest <i>n</i> encountered. The array <tt>N</tt> must have room to hold the longest chain examined in the course of determining whether a single number is happy, which thanks to the memoization is only ten elements long. |
|||
<syntaxhighlight lang="gwbasic"> |
|||
100 C=8:DIM H(145),U(145),N(9) |
|||
110 PRINT CHR$(147):PRINT "THE FIRST"C"HAPPY NUMBERS:":PRINT |
|||
120 H(1)=1:N=1 |
|||
130 FOR C=C TO 0 STEP 0 |
|||
140 : GOSUB 200 |
|||
150 : IF H THEN PRINT N,:C=C-1 |
|||
160 : N=N+1 |
|||
170 NEXT C |
|||
180 PRINT |
|||
190 END |
|||
200 K=0:N(K)=N |
|||
210 IF H(N(K)) THEN H=1:FOR J=0 TO K:U(N(J))=0:H(N(J))=1:NEXT J:RETURN |
|||
220 IF U(N(K)) THEN H=0:RETURN |
|||
230 U(N(K))=1 |
|||
240 N$=MID$(STR$(N(K)),2) |
|||
250 L=LEN(N$) |
|||
260 K=K+1:N(K)=0 |
|||
270 FOR I=1 TO L |
|||
280 : D = VAL(MID$(N$,I,1)) |
|||
290 : N(K) = N(K) + D * D |
|||
300 NEXT I |
|||
310 GOTO 210</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
THE FIRST 8 HAPPY NUMBERS: |
|||
1 7 10 13 |
|||
19 23 28 31 |
|||
READY. |
|||
</pre> |
|||
==={{header|FreeBASIC}}=== |
|||
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64 |
|||
Function isHappy(n As Integer) As Boolean |
|||
If n < 0 Then Return False |
|||
' Declare a dynamic array to store previous sums. |
|||
' If a previous sum is duplicated before a sum of 1 is reached |
|||
' then the number can't be "happy" as the cycle will just repeat |
|||
Dim prevSums() As Integer |
|||
Dim As Integer digit, ub, sum = 0 |
|||
Do |
|||
While n > 0 |
|||
digit = n Mod 10 |
|||
sum += digit * digit |
|||
n \= 10 |
|||
Wend |
|||
If sum = 1 Then Return True |
|||
ub = UBound(prevSums) |
|||
If ub > -1 Then |
|||
For i As Integer = 0 To ub |
|||
If sum = prevSums(i) Then Return False |
|||
Next |
|||
End If |
|||
ub += 1 |
|||
Redim Preserve prevSums(0 To ub) |
|||
prevSums(ub) = sum |
|||
n = sum |
|||
sum = 0 |
|||
Loop |
|||
End Function |
|||
Dim As Integer n = 1, count = 0 |
|||
Print "The first 8 happy numbers are : " |
|||
Print |
|||
While count < 8 |
|||
If isHappy(n) Then |
|||
count += 1 |
|||
Print count;" =>"; n |
|||
End If |
|||
n += 1 |
|||
Wend |
|||
Print |
|||
Print "Press any key to quit" |
|||
Sleep</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 => 1 |
|||
2 => 7 |
|||
3 => 10 |
|||
4 => 13 |
|||
5 => 19 |
|||
6 => 23 |
|||
7 => 28 |
|||
8 => 31 |
|||
</pre> |
|||
==={{header|Liberty BASIC}}=== |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
Output:- |
|||
<pre>1 1 |
|||
2 7 |
|||
3 10 |
|||
4 13 |
|||
5 19 |
|||
6 23 |
|||
7 28 |
|||
8 31 |
|||
</pre> |
|||
==={{header|Locomotive Basic}}=== |
|||
<syntaxhighlight lang="locobasic">10 mode 1:defint a-z |
|||
20 for i=1 to 100 |
|||
30 i2=i |
|||
40 for l=1 to 20 |
|||
50 a$=str$(i2) |
|||
60 i2=0 |
|||
70 for j=1 to len(a$) |
|||
80 d=val(mid$(a$,j,1)) |
|||
90 i2=i2+d*d |
|||
100 next j |
|||
110 if i2=1 then print i;"is a happy number":n=n+1:goto 150 |
|||
120 if i2=4 then 150 ' cycle found |
|||
130 next l |
|||
140 ' check if we have reached 8 numbers yet |
|||
150 if n=8 then end |
|||
160 next i</syntaxhighlight> |
|||
[[File:Happy Numbers, Locomotive BASIC.png]] |
|||
==={{header|PureBasic}}=== |
|||
<syntaxhighlight lang="purebasic">#ToFind=8 |
|||
#MaxTests=100 |
|||
#True = 1: #False = 0 |
|||
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</syntaxhighlight> |
|||
Sample output: |
|||
<pre>#1 1 |
|||
#2 7 |
|||
#3 10 |
|||
#4 13 |
|||
#5 19 |
|||
#6 23 |
|||
#7 28 |
|||
#8 31</pre> |
|||
==={{header|Run BASIC}}=== |
|||
<syntaxhighlight lang="runbasic">for i = 1 to 100 |
|||
if happy(i) = 1 then |
|||
cnt = cnt + 1 |
|||
PRINT cnt;". ";i;" is a happy number " |
|||
if cnt = 8 then end |
|||
end if |
|||
next i |
|||
FUNCTION happy(num) |
|||
while count < 50 and happy <> 1 |
|||
num$ = str$(num) |
|||
count = count + 1 |
|||
happy = 0 |
|||
for i = 1 to len(num$) |
|||
happy = happy + val(mid$(num$,i,1)) ^ 2 |
|||
next i |
|||
num = happy |
|||
wend |
|||
end function</syntaxhighlight> |
|||
<pre>1. 1 is a happy number |
|||
2. 7 is a happy number |
|||
3. 10 is a happy number |
|||
4. 13 is a happy number |
|||
5. 19 is a happy number |
|||
6. 23 is a happy number |
|||
7. 28 is a happy number |
|||
8. 31 is a happy number |
|||
</pre> |
|||
==={{header|uBasic/4tH}}=== |
|||
<syntaxhighlight lang="text"> |
|||
' ************************ |
|||
' MAIN |
|||
' ************************ |
|||
PROC _PRINT_HAPPY(20) |
|||
END |
|||
' ************************ |
|||
' END MAIN |
|||
' ************************ |
|||
' ************************ |
|||
' SUBS & FUNCTIONS |
|||
' ************************ |
|||
' -------------------- |
|||
_is_happy PARAM(1) |
|||
' -------------------- |
|||
LOCAL (5) |
|||
f@ = 100 |
|||
c@ = a@ |
|||
b@ = 0 |
|||
DO WHILE b@ < f@ |
|||
e@ = 0 |
|||
DO WHILE c@ |
|||
d@ = c@ % 10 |
|||
c@ = c@ / 10 |
|||
e@ = e@ + (d@ * d@) |
|||
LOOP |
|||
UNTIL e@ = 1 |
|||
c@ = e@ |
|||
b@ = b@ + 1 |
|||
LOOP |
|||
RETURN(b@ < f@) |
|||
' -------------------- |
|||
_PRINT_HAPPY PARAM(1) |
|||
' -------------------- |
|||
LOCAL (2) |
|||
b@ = 1 |
|||
c@ = 0 |
|||
DO |
|||
IF FUNC (_is_happy(b@)) THEN |
|||
c@ = c@ + 1 |
|||
PRINT b@ |
|||
ENDIF |
|||
b@ = b@ + 1 |
|||
UNTIL c@ + 1 > a@ |
|||
LOOP |
|||
RETURN |
|||
' ************************ |
|||
' END SUBS & FUNCTIONS |
|||
' ************************ |
|||
</syntaxhighlight> |
|||
==={{header|VBA}}=== |
|||
<syntaxhighlight lang="vb"> |
|||
Option Explicit |
|||
Sub Test_Happy() |
|||
Dim i&, Cpt& |
|||
For i = 1 To 100 |
|||
If Is_Happy_Number(i) Then |
|||
Debug.Print "Is Happy : " & i |
|||
Cpt = Cpt + 1 |
|||
If Cpt = 8 Then Exit For |
|||
End If |
|||
Next |
|||
End Sub |
|||
Public Function Is_Happy_Number(ByVal N As Long) As Boolean |
|||
Dim i&, Number$, Cpt& |
|||
Is_Happy_Number = False 'default value |
|||
Do |
|||
Cpt = Cpt + 1 'Count Loops |
|||
Number = CStr(N) 'conversion Long To String to be able to use Len() function |
|||
N = 0 |
|||
For i = 1 To Len(Number) |
|||
N = N + CInt(Mid(Number, i, 1)) ^ 2 |
|||
Next i |
|||
'If Not N = 1 after 50 Loop ==> Number Is Not Happy |
|||
If Cpt = 50 Then Exit Function |
|||
Loop Until N = 1 |
|||
Is_Happy_Number = True |
|||
End Function |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>Is Happy : 1 |
|||
Is Happy : 7 |
|||
Is Happy : 10 |
|||
Is Happy : 13 |
|||
Is Happy : 19 |
|||
Is Happy : 23 |
|||
Is Happy : 28 |
|||
Is Happy : 31</pre> |
|||
==={{header|VBScript}}=== |
|||
<syntaxhighlight lang="vb"> |
|||
count = 0 |
|||
firsteigth="" |
|||
For i = 1 To 100 |
|||
If IsHappy(CInt(i)) Then |
|||
firsteight = firsteight & i & "," |
|||
count = count + 1 |
|||
End If |
|||
If count = 8 Then |
|||
Exit For |
|||
End If |
|||
Next |
|||
WScript.Echo firsteight |
|||
Function IsHappy(n) |
|||
IsHappy = False |
|||
m = 0 |
|||
Do Until m = 60 |
|||
sum = 0 |
|||
For j = 1 To Len(n) |
|||
sum = sum + (Mid(n,j,1))^2 |
|||
Next |
|||
If sum = 1 Then |
|||
IsHappy = True |
|||
Exit Do |
|||
Else |
|||
n = sum |
|||
m = m + 1 |
|||
End If |
|||
Loop |
|||
End Function |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>1,7,10,13,19,23,28,31,</pre> |
|||
==={{header|Visual Basic .NET}}=== |
|||
This version uses Linq to carry out the calculations. |
|||
<syntaxhighlight lang="vbnet">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</syntaxhighlight> |
|||
The output is: |
|||
<pre>1: 1 |
|||
2: 7 |
|||
3: 10 |
|||
4: 13 |
|||
5: 19 |
|||
6: 23 |
|||
7: 28 |
|||
8: 31</pre> |
|||
====Cacheless version==== |
|||
{{trans|C#}} |
|||
Curiously, this runs in about two thirds of the time of the cacheless C# version on Tio.run. |
|||
<syntaxhighlight lang="vbnet">Module Module1 |
|||
Dim sq As Integer() = {1, 4, 9, 16, 25, 36, 49, 64, 81} |
|||
Function isOne(x As Integer) As Boolean |
|||
While True |
|||
If x = 89 Then Return False |
|||
Dim t As Integer, s As Integer = 0 |
|||
Do |
|||
t = (x Mod 10) - 1 : If t >= 0 Then s += sq(t) |
|||
x \= 10 |
|||
Loop While x > 0 |
|||
If s = 1 Then Return True |
|||
x = s |
|||
End While |
|||
Return False |
|||
End Function |
|||
Sub Main(ByVal args As String()) |
|||
Const Max As Integer = 10_000_000 |
|||
Dim st As DateTime = DateTime.Now |
|||
Console.Write("---Happy Numbers---" & vbLf & "The first 8:") |
|||
Dim i As Integer = 1, c As Integer = 0 |
|||
While c < 8 |
|||
If isOne(i) Then Console.Write("{0} {1}", If(c = 0, "", ","), i, c) : c += 1 |
|||
i += 1 |
|||
End While |
|||
Dim m As Integer = 10 |
|||
While m <= Max |
|||
Console.Write(vbLf & "The {0:n0}th: ", m) |
|||
While c < m |
|||
If isOne(i) Then c += 1 |
|||
i += 1 |
|||
End While |
|||
Console.Write("{0:n0}", i - 1) |
|||
m = m * 10 |
|||
End While |
|||
Console.WriteLine(vbLf & "Computation time {0} seconds.", (DateTime.Now - st).TotalSeconds) |
|||
End Sub |
|||
End Module</syntaxhighlight> |
|||
{{out}} |
|||
<pre>---Happy Numbers--- |
|||
The first 8: 1, 7, 10, 13, 19, 23, 28, 31 |
|||
The 10th: 44 |
|||
The 100th: 694 |
|||
The 1,000th: 6,899 |
|||
The 10,000th: 67,169 |
|||
The 100,000th: 692,961 |
|||
The 1,000,000th: 7,105,849 |
|||
The 10,000,000th: 71,313,350 |
|||
Computation time 19.235551 seconds.</pre> |
|||
==={{header|ZX Spectrum Basic}}=== |
|||
{{trans|Run_BASIC}} |
|||
<syntaxhighlight lang="zxbasic">10 FOR i=1 TO 100 |
|||
20 GO SUB 1000 |
|||
30 IF isHappy=1 THEN PRINT i;" is a happy number" |
|||
40 NEXT i |
|||
50 STOP |
|||
1000 REM Is Happy? |
|||
1010 LET isHappy=0: LET count=0: LET num=i |
|||
1020 IF count=50 OR isHappy=1 THEN RETURN |
|||
1030 LET n$=STR$ (num) |
|||
1040 LET count=count+1 |
|||
1050 LET isHappy=0 |
|||
1060 FOR j=1 TO LEN n$ |
|||
1070 LET isHappy=isHappy+VAL n$(j)^2 |
|||
1080 NEXT j |
|||
1090 LET num=isHappy |
|||
1100 GO TO 1020</syntaxhighlight> |
|||
=={{header|Batch File}}== |
|||
happy.bat |
|||
<syntaxhighlight lang="dos">@echo off |
|||
setlocal enableDelayedExpansion |
|||
::Define a list with 10 terms as a convenience for defining a loop |
|||
set "L10=0 1 2 3 4 5 6 7 8 9" |
|||
shift /1 & goto %1 |
|||
exit /b |
|||
:list min count |
|||
:: This routine prints all happy numbers > min (arg1) |
|||
:: until it finds count (arg2) happy numbers. |
|||
set /a "n=%~1, cnt=%~2" |
|||
call :listInternal |
|||
exit /b |
|||
:test min [max] |
|||
:: This routine sequentially tests numbers between min (arg1) and max (arg2) |
|||
:: to see if they are happy. If max is not specified then it defaults to min. |
|||
set /a "min=%~1" |
|||
if "%~2" neq "" (set /a "max=%~2") else set max=%min% |
|||
::The FOR /L loop does not detect integer overflow, so must protect against |
|||
::an infinite loop when max=0x7FFFFFFFF |
|||
set end=%max% |
|||
if %end% equ 2147483647 set /a end-=1 |
|||
for /l %%N in (%min% 1 %end%) do ( |
|||
call :testInternal %%N && (echo %%N is happy :^)) || echo %%N is sad :( |
|||
) |
|||
if %end% neq %max% call :testInternal %max% && (echo %max% is happy :^)) || echo %max% is sad :( |
|||
exit /b |
|||
:listInternal |
|||
:: This loop sequentially tests each number >= n. The loop conditionally |
|||
:: breaks within the body once cnt happy numbers have been found, or if |
|||
:: the max integer value is reached. Performance is improved by using a |
|||
:: FOR loop to perform most of the looping, with a GOTO only needed once |
|||
:: per 100 iterations. |
|||
for %%. in ( |
|||
%L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% |
|||
) do ( |
|||
call :testInternal !n! && ( |
|||
echo !n! |
|||
set /a cnt-=1 |
|||
if !cnt! leq 0 exit /b 0 |
|||
) |
|||
if !n! equ 2147483647 ( |
|||
>&2 echo ERROR: Maximum integer value reached |
|||
exit /b 1 |
|||
) |
|||
set /a n+=1 |
|||
) |
|||
goto :listInternal |
|||
:testInternal n |
|||
:: This routine loops until the sum of squared digits converges on 1 (happy) |
|||
:: or it detects a cycle (sad). It exits with errorlevel 0 for happy and 1 for sad. |
|||
:: Performance is improved by using a FOR loop for the looping instead of a GOTO. |
|||
:: Numbers less than 1000 never neeed more than 20 iterations, and any number |
|||
:: with 4 or more digits shrinks by at least one digit each iteration. |
|||
:: Since Windows batch can't handle more than 10 digits, allowance for 27 |
|||
:: iterations is enough, and 30 is more than adequate. |
|||
setlocal |
|||
set n=%1 |
|||
for %%. in (%L10% %L10% %L10%) do ( |
|||
if !n!==1 exit /b 0 |
|||
%= Only numbers < 1000 can cycle =% |
|||
if !n! lss 1000 ( |
|||
if defined t.!n! exit /b 1 |
|||
set t.!n!=1 |
|||
) |
|||
%= Sum the squared digits =% |
|||
%= Batch can't handle numbers greater than 10 digits so we can use =% |
|||
%= a constrained FOR loop and avoid a slow goto =% |
|||
set sum=0 |
|||
for /l %%N in (1 1 10) do ( |
|||
if !n! gtr 0 set /a "sum+=(n%%10)*(n%%10), n/=10" |
|||
) |
|||
set /a n=sum |
|||
)</syntaxhighlight> |
|||
Sample usage and output |
|||
<pre> |
|||
>happy list 1 8 |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
>happy list 1000000000 10 |
|||
1000000000 |
|||
1000000003 |
|||
1000000009 |
|||
1000000029 |
|||
1000000030 |
|||
1000000033 |
|||
1000000039 |
|||
1000000067 |
|||
1000000076 |
|||
1000000088 |
|||
>happy test 30 |
|||
30 is sad :( |
|||
>happy test 31 |
|||
31 is happy :) |
|||
>happy test 1 10 |
|||
1 is happy :) |
|||
2 is sad :( |
|||
3 is sad :( |
|||
4 is sad :( |
|||
5 is sad :( |
|||
6 is sad :( |
|||
7 is happy :) |
|||
8 is sad :( |
|||
9 is sad :( |
|||
10 is happy :) |
|||
>happy test "50 + 10 * 5" |
|||
100 is happy :) |
|||
>happy test 0x7fffffff |
|||
2147483647 is sad :( |
|||
>happy test 0x7ffffffd |
|||
2147483645 is happy :) |
|||
>happy list 0x7ffffff0 10 |
|||
2147483632 |
|||
2147483645 |
|||
ERROR: Maximum integer value reached |
|||
</pre> |
|||
=={{header|BCPL}}== |
|||
<syntaxhighlight lang="bcpl">get "libhdr" |
|||
let sumdigitsq(n) = |
|||
n=0 -> 0, (n rem 10)*(n rem 10)+sumdigitsq(n/10) |
|||
let happy(n) = valof |
|||
$( let seen = vec 255 |
|||
for i = 0 to 255 do i!seen := false |
|||
$( n!seen := true |
|||
n := sumdigitsq(n) |
|||
$) repeatuntil n!seen |
|||
resultis 1!seen |
|||
$) |
|||
let start() be |
|||
$( let n, i = 0, 0 |
|||
while n < 8 do |
|||
$( if happy(i) do |
|||
$( n := n + 1 |
|||
writef("%N ",i) |
|||
$) |
|||
i := i + 1 |
|||
$) |
|||
wrch('*N') |
|||
$)</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
=={{header|Bori}}== |
|||
<syntaxhighlight lang="bori">bool isHappy (int n) |
|||
{ |
{ |
||
ints cache; |
|||
for( ; c != NULL; c = c->next ) |
|||
if ( n == c->val ) return true; |
|||
while (n != 1) |
|||
return false; |
|||
{ |
|||
int sum = 0; |
|||
if (cache.contains(n)) |
|||
return false; |
|||
cache.add(n); |
|||
while (n != 0) |
|||
{ |
|||
int digit = n % 10; |
|||
sum += (digit * digit); |
|||
n = (int)(n / 10); |
|||
} |
|||
n = sum; |
|||
} |
|||
return true; |
|||
} |
} |
||
void |
void test () |
||
{ |
{ |
||
int num = 1; |
|||
list_t *p = malloc(sizeof(list_t)); assert(p!=NULL); |
|||
ints happynums; |
|||
p->val = n; p->next = NULL; |
|||
if ( *c == NULL ) { |
|||
while (happynums.count() < 8) |
|||
*c = p; |
|||
{ |
|||
if (isHappy(num)) |
|||
p->next = *c; |
|||
happynums.add(num); |
|||
num++; |
|||
} |
|||
} |
|||
puts("First 8 happy numbers : " + str.newline + happynums); |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre>First 8 happy numbers : |
|||
[1, 7, 10, 13, 19, 23, 28, 31]</pre> |
|||
=={{header|BQN}}== |
|||
<syntaxhighlight lang="bqn">SumSqDgt ← +´2⋆˜ •Fmt-'0'˙ |
|||
Happy ← ⟨⟩{𝕨((⊑∊˜ )◶⟨∾𝕊(SumSqDgt⊢),1=⊢⟩)𝕩}⊢ |
|||
8↑Happy¨⊸/↕50</syntaxhighlight> |
|||
{{out}} |
|||
<pre>⟨ 1 7 10 13 19 23 28 31 ⟩</pre> |
|||
=={{header|Brat}}== |
|||
<syntaxhighlight lang="brat">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 | |
|||
void kill_cycle(list_t *c) |
|||
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}"</syntaxhighlight> |
|||
Output: |
|||
<pre>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]</pre> |
|||
=={{header|C}}== |
|||
Recursively look up if digit square sum is happy. |
|||
<syntaxhighlight lang="c">#include <stdio.h> |
|||
#define CACHE 256 |
|||
enum { h_unknown = 0, h_yes, h_no }; |
|||
unsigned char buf[CACHE] = {0, h_yes, 0}; |
|||
int happy(int n) |
|||
{ |
{ |
||
int sum = 0, x, nn; |
|||
list_t *t; |
|||
if (n < CACHE) { |
|||
if (buf[n]) return 2 - buf[n]; |
|||
t = c->next; |
|||
buf[n] = h_no; |
|||
free(c); |
|||
} |
|||
for (nn = n; nn; nn /= 10) x = nn % 10, sum += x * x; |
|||
x = happy(sum); |
|||
if (n < CACHE) buf[n] = 2 - x; |
|||
return x; |
|||
} |
} |
||
int main() |
|||
bool is_happy(int n) |
|||
{ |
{ |
||
int i, cnt = 8; |
|||
for (i = 1; cnt || !printf("\n"); i++) |
|||
int new_n; |
|||
if (happy(i)) --cnt, printf("%d ", i); |
|||
printf("The %dth happy number: ", cnt = 1000000); |
|||
while( (n != 1) && !in_cycle(cycle, n) ) { |
|||
for (i = 1; cnt; i++) |
|||
add_cycle(&cycle, n); |
|||
if (happy(i)) --cnt || printf("%d\n", i); |
|||
new_n = 0; |
|||
while( n > 0 ) { |
|||
return 0; |
|||
int d = n % 10; |
|||
}</syntaxhighlight> |
|||
new_n += d*d; |
|||
output<pre>1 7 10 13 19 23 28 31 |
|||
The 1000000th happy number: 7105849</pre> |
|||
} |
|||
Without caching, using cycle detection: |
|||
n = new_n; |
|||
<syntaxhighlight lang="c">#include <stdio.h> |
|||
} |
|||
kill_cycle(cycle); |
|||
int dsum(int n) |
|||
return (n == 1); |
|||
{ |
|||
int sum, x; |
|||
for (sum = 0; n; n /= 10) x = n % 10, sum += x * x; |
|||
return sum; |
|||
} |
|||
int happy(int n) |
|||
{ |
|||
int nn; |
|||
while (n > 999) n = dsum(n); /* 4 digit numbers can't cycle */ |
|||
nn = dsum(n); |
|||
while (nn != n && nn != 1) |
|||
n = dsum(n), nn = dsum(dsum(nn)); |
|||
return n == 1; |
|||
} |
} |
||
int main() |
int main() |
||
{ |
{ |
||
int i, cnt = 8; |
|||
for (i = 1; cnt || !printf("\n"); i++) |
|||
if (happy(i)) --cnt, printf("%d ", i); |
|||
} |
|||
printf("The %dth happy number: ", cnt = 1000000); |
|||
return EXIT_SUCCESS; |
|||
for (i = 1; cnt; i++) |
|||
}</lang> |
|||
if (happy(i)) --cnt || printf("%d\n", i); |
|||
return 0; |
|||
}</syntaxhighlight> Output is same as above, but much slower. |
|||
=={{header|C sharp|C#}}== |
|||
<syntaxhighlight 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)); |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
<pre> |
|||
First 8 happy numbers : 1,7,10,13,19,23,28,31 |
|||
</pre> |
|||
===Alternate (cacheless)=== |
|||
Instead of caching and checking for being stuck in a loop, one can terminate on the "unhappy" endpoint of 89. One might be temped to try caching the so-far-found happy and unhappy numbers and checking the cache to speed things up. However, I have found that the cache implementation overhead reduces performance compared to this cacheless version.<br/> |
|||
Reaching 10 million, the <34 second computation time was from Tio.run. It takes under 5 seconds on a somewhat modern CPU. If you edit it to max out at 100 million, it takes about 50 seconds (on the somewhat modern CPU).<syntaxhighlight lang="csharp">using System; |
|||
using System.Collections.Generic; |
|||
class Program |
|||
{ |
|||
static int[] sq = { 1, 4, 9, 16, 25, 36, 49, 64, 81 }; |
|||
static bool isOne(int x) |
|||
{ |
|||
while (true) |
|||
{ |
|||
if (x == 89) return false; |
|||
int s = 0, t; |
|||
do if ((t = (x % 10) - 1) >= 0) s += sq[t]; while ((x /= 10) > 0); |
|||
if (s == 1) return true; |
|||
x = s; |
|||
} |
|||
} |
|||
static void Main(string[] args) |
|||
{ |
|||
const int Max = 10_000_000; DateTime st = DateTime.Now; |
|||
Console.Write("---Happy Numbers---\nThe first 8:"); |
|||
int c = 0, i; for (i = 1; c < 8; i++) |
|||
if (isOne(i)) Console.Write("{0} {1}", c == 0 ? "" : ",", i, ++c); |
|||
for (int m = 10; m <= Max; m *= 10) |
|||
{ |
|||
Console.Write("\nThe {0:n0}th: ", m); |
|||
for (; c < m; i++) if (isOne(i)) c++; |
|||
Console.Write("{0:n0}", i - 1); |
|||
} |
|||
Console.WriteLine("\nComputation time {0} seconds.", (DateTime.Now - st).TotalSeconds); |
|||
} |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>---Happy Numbers--- |
|||
The first 8: 1, 7, 10, 13, 19, 23, 28, 31 |
|||
The 10th: 44 |
|||
The 100th: 694 |
|||
The 1,000th: 6,899 |
|||
The 10,000th: 67,169 |
|||
The 100,000th: 692,961 |
|||
The 1,000,000th: 7,105,849 |
|||
The 10,000,000th: 71,313,350 |
|||
Computation time 33.264518 seconds.</pre> |
|||
=={{header|C++}}== |
=={{header|C++}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="cpp">#include <map> |
||
#include <set> |
#include <set> |
||
Line 266: | Line 2,040: | ||
std::cout << i << std::endl; |
std::cout << i << std::endl; |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
32 |
|||
44 |
|||
49</pre> |
|||
Alternative version without caching: |
Alternative version without caching: |
||
<syntaxhighlight lang="cpp">unsigned int happy_iteration(unsigned int n) |
|||
<lang cpp>unsigned int happy_iteration(unsigned int n) |
|||
{ |
{ |
||
unsigned int result = 0; |
unsigned int result = 0; |
||
Line 310: | Line 2,094: | ||
} |
} |
||
std::cout << std::endl; |
std::cout << std::endl; |
||
}</ |
}</syntaxhighlight> |
||
Output: |
|||
<pre>1 7 10 13 19 23 28 31 </pre> |
|||
Cycle detection in <code>is_happy()</code> above is done using [[wp:Floyd's cycle-finding algorithm|Floyd's cycle-finding algorithm]]. |
Cycle detection in <code>is_happy()</code> above is done using [[wp:Floyd's cycle-finding algorithm|Floyd's cycle-finding algorithm]]. |
||
=={{header|Clojure}}== |
|||
<syntaxhighlight lang="clojure">(defn happy? [n] |
|||
(loop [n n, seen #{}] |
|||
(cond |
|||
(= n 1) true |
|||
(seen n) false |
|||
:else |
|||
(recur (->> (str n) |
|||
(map #(Character/digit % 10)) |
|||
(map #(* % %)) |
|||
(reduce +)) |
|||
(conj seen n))))) |
|||
(def happy-numbers (filter happy? (iterate inc 1))) |
|||
(println (take 8 happy-numbers))</syntaxhighlight> |
|||
Output:<pre>(1 7 10 13 19 23 28 31)</pre> |
|||
===Alternate Version (with caching)=== |
|||
<syntaxhighlight lang="clojure">(require '[clojure.set :refer [union]]) |
|||
(def ^{:private true} cache {:happy (atom #{}) :sad (atom #{})}) |
|||
(defn break-apart [n] |
|||
(->> (str n) |
|||
(map str) |
|||
(map #(Long/parseLong %)))) |
|||
(defn next-number [n] |
|||
(->> (break-apart n) |
|||
(map #(* % %)) |
|||
(apply +))) |
|||
(defn happy-or-sad? [prev n] |
|||
(cond (or (= n 1) ((deref (:happy cache)) n)) :happy |
|||
(or ((deref (:sad cache)) n) (some #(= % n) prev)) :sad |
|||
:else :unknown)) |
|||
(defn happy-algo [n] |
|||
(let [get-next (fn [[prev n]] [(conj prev n) (next-number n)]) |
|||
my-happy-or-sad? (fn [[prev n]] [(happy-or-sad? prev n) (conj prev n)]) |
|||
unknown? (fn [[res nums]] (= res :unknown)) |
|||
[res nums] (->> [#{} n] |
|||
(iterate get-next) |
|||
(map my-happy-or-sad?) |
|||
(drop-while unknown?) |
|||
first) |
|||
_ (swap! (res cache) union nums)] |
|||
res)) |
|||
(def happy-numbers (->> (iterate inc 1) |
|||
(filter #(= :happy (happy-algo %))))) |
|||
(println (take 8 happy-numbers))</syntaxhighlight> |
|||
Same output. |
|||
=={{header|CLU}}== |
|||
<syntaxhighlight lang="clu">sum_dig_sq = proc (n: int) returns (int) |
|||
sum_sq: int := 0 |
|||
while n > 0 do |
|||
sum_sq := sum_sq + (n // 10) ** 2 |
|||
n := n / 10 |
|||
end |
|||
return (sum_sq) |
|||
end sum_dig_sq |
|||
is_happy = proc (n: int) returns (bool) |
|||
nn: int := sum_dig_sq(n) |
|||
while nn ~= n cand nn ~= 1 do |
|||
n := sum_dig_sq(n) |
|||
nn := sum_dig_sq(sum_dig_sq(nn)) |
|||
end |
|||
return (nn = 1) |
|||
end is_happy |
|||
happy_numbers = iter (start, num: int) yields (int) |
|||
n: int := start |
|||
while num > 0 do |
|||
if is_happy(n) then |
|||
yield (n) |
|||
num := num-1 |
|||
end |
|||
n := n+1 |
|||
end |
|||
end happy_numbers |
|||
start_up = proc () |
|||
po: stream := stream$primary_output() |
|||
for i: int in happy_numbers(1, 8) do |
|||
stream$putl(po, int$unparse(i)) |
|||
end |
|||
end start_up </syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|COBOL}}== |
|||
<syntaxhighlight lang="cobol"> IDENTIFICATION DIVISION. |
|||
PROGRAM-ID. HAPPY. |
|||
DATA DIVISION. |
|||
WORKING-STORAGE SECTION. |
|||
01 VARIABLES. |
|||
03 CANDIDATE PIC 9(4). |
|||
03 SQSUM-IN PIC 9(4). |
|||
03 FILLER REDEFINES SQSUM-IN. |
|||
05 DIGITS PIC 9 OCCURS 4 TIMES. |
|||
03 SQUARE PIC 9(4). |
|||
03 SUM-OF-SQUARES PIC 9(4). |
|||
03 N PIC 9. |
|||
03 TORTOISE PIC 9(4). |
|||
03 HARE PIC 9(4). |
|||
88 HAPPY VALUE 1. |
|||
03 SEEN PIC 9 VALUE ZERO. |
|||
03 OUT-FMT PIC ZZZ9. |
|||
PROCEDURE DIVISION. |
|||
BEGIN. |
|||
PERFORM DISPLAY-IF-HAPPY VARYING CANDIDATE FROM 1 BY 1 |
|||
UNTIL SEEN IS EQUAL TO 8. |
|||
STOP RUN. |
|||
DISPLAY-IF-HAPPY. |
|||
PERFORM CHECK-HAPPY. |
|||
IF HAPPY, |
|||
MOVE CANDIDATE TO OUT-FMT, |
|||
DISPLAY OUT-FMT, |
|||
ADD 1 TO SEEN. |
|||
CHECK-HAPPY. |
|||
MOVE CANDIDATE TO TORTOISE, SQSUM-IN. |
|||
PERFORM CALC-SUM-OF-SQUARES. |
|||
MOVE SUM-OF-SQUARES TO HARE. |
|||
PERFORM CHECK-HAPPY-STEP UNTIL TORTOISE IS EQUAL TO HARE. |
|||
CHECK-HAPPY-STEP. |
|||
MOVE TORTOISE TO SQSUM-IN. |
|||
PERFORM CALC-SUM-OF-SQUARES. |
|||
MOVE SUM-OF-SQUARES TO TORTOISE. |
|||
MOVE HARE TO SQSUM-IN. |
|||
PERFORM CALC-SUM-OF-SQUARES. |
|||
MOVE SUM-OF-SQUARES TO SQSUM-IN. |
|||
PERFORM CALC-SUM-OF-SQUARES. |
|||
MOVE SUM-OF-SQUARES TO HARE. |
|||
CALC-SUM-OF-SQUARES. |
|||
MOVE ZERO TO SUM-OF-SQUARES. |
|||
PERFORM ADD-DIGIT-SQUARE VARYING N FROM 1 BY 1 |
|||
UNTIL N IS GREATER THAN 4. |
|||
ADD-DIGIT-SQUARE. |
|||
MULTIPLY DIGITS(N) BY DIGITS(N) GIVING SQUARE. |
|||
ADD SQUARE TO SUM-OF-SQUARES.</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|CoffeeScript}}== |
|||
<syntaxhighlight lang="coffeescript">happy = (n) -> |
|||
seen = {} |
|||
while true |
|||
n = sum_digit_squares(n) |
|||
return true if n == 1 |
|||
return false if seen[n] |
|||
seen[n] = true |
|||
sum_digit_squares = (n) -> |
|||
sum = 0 |
|||
for c in n.toString() |
|||
d = parseInt(c) |
|||
sum += d*d |
|||
sum |
|||
i = 1 |
|||
cnt = 0 |
|||
while cnt < 8 |
|||
if happy(i) |
|||
console.log i |
|||
cnt += 1 |
|||
i += 1</syntaxhighlight> |
|||
output |
|||
<pre> |
|||
> coffee happy.coffee |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
<lang |
<syntaxhighlight lang="lisp">(defun sqr (n) |
||
( |
(* n n)) |
||
(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)))))) |
|||
(defun sum-of-sqr-dgts (n) |
|||
(loop |
|||
(loop for i = n then (floor i 10) |
|||
with happy = 0 |
|||
while (plusp i) |
|||
for n from 0 |
|||
sum (sqr (mod i 10)))) |
|||
when (happyp n) |
|||
(defun happy-p (n &optional cache) |
|||
do (incf happy) and |
|||
(or (= n 1) |
|||
(unless (find n cache) |
|||
(happy-p (sum-of-sqr-dgts n) |
|||
(cons n cache))))) |
|||
(defun happys (&aux (happys 0)) |
|||
(loop for i from 1 |
|||
while (< happys 8) |
|||
when (happy-p i) |
|||
collect i and do (incf happys))) |
|||
(print (happys)) |
|||
</syntaxhighlight> |
|||
Output:<pre>(1 7 10 13 19 23 28 31)</pre> |
|||
=={{header|E}}== |
|||
=={{header|Cowgol}}== |
|||
<lang e>def isHappyNumber(var x :int) { |
|||
<syntaxhighlight lang="cowgol">include "cowgol.coh"; |
|||
sub sumDigitSquare(n: uint8): (s: uint8) is |
|||
s := 0; |
|||
while n != 0 loop |
|||
var d := n % 10; |
|||
s := s + d * d; |
|||
n := n / 10; |
|||
end loop; |
|||
end sub; |
|||
sub isHappy(n: uint8): (h: uint8) is |
|||
var seen: uint8[256]; |
|||
MemZero(&seen[0], @bytesof seen); |
|||
while seen[n] == 0 loop |
|||
seen[n] := 1; |
|||
n := sumDigitSquare(n); |
|||
end loop; |
|||
if n == 1 then |
|||
h := 1; |
|||
else |
|||
h := 0; |
|||
end if; |
|||
end sub; |
|||
var n: uint8 := 1; |
|||
var seen: uint8 := 0; |
|||
while seen < 8 loop |
|||
if isHappy(n) != 0 then |
|||
print_i8(n); |
|||
print_nl(); |
|||
seen := seen + 1; |
|||
end if; |
|||
n := n + 1; |
|||
end loop;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Crystal}}== |
|||
{{trans|Ruby}} |
|||
<syntaxhighlight lang="ruby">def happy?(n) |
|||
past = [] of Int32 | Int64 |
|||
until n == 1 |
|||
sum = 0; while n > 0; sum += (n % 10) ** 2; n //= 10 end |
|||
return false if past.includes? (n = sum) |
|||
past << n |
|||
end |
|||
true |
|||
end |
|||
i = count = 0 |
|||
until count == 8; (puts i; count += 1) if happy?(i += 1) end |
|||
puts |
|||
(99999999999900..99999999999999).each { |i| puts i if happy?(i) }</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
99999999999901 |
|||
99999999999910 |
|||
99999999999914 |
|||
99999999999915 |
|||
99999999999916 |
|||
99999999999937 |
|||
99999999999941 |
|||
99999999999951 |
|||
99999999999956 |
|||
99999999999961 |
|||
99999999999965 |
|||
99999999999973</pre> |
|||
=={{header|D}}== |
|||
<syntaxhighlight lang="d">bool isHappy(int n) pure nothrow { |
|||
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() { |
|||
import std.stdio, std.algorithm, std.range; |
|||
int.max.iota.filter!isHappy.take(8).writeln; |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre>[1, 7, 10, 13, 19, 23, 28, 31]</pre> |
|||
===Alternative Version=== |
|||
<syntaxhighlight lang="d">import std.stdio, std.algorithm, std.range, std.conv, std.string; |
|||
bool isHappy(int n) pure nothrow { |
|||
int[int] seen; |
|||
while (true) { |
|||
immutable t = n.text.representation.map!q{(a - '0') ^^ 2}.sum; |
|||
if (t == 1) |
|||
return true; |
|||
if (t in seen) |
|||
return false; |
|||
n = t; |
|||
seen[t] = 0; |
|||
} |
|||
} |
|||
void main() { |
|||
int.max.iota.filter!isHappy.take(8).writeln; |
|||
}</syntaxhighlight> |
|||
Same output. |
|||
=={{header|Dart}}== |
|||
<syntaxhighlight lang="dart">main() { |
|||
HashMap<int,bool> happy=new HashMap<int,bool>(); |
|||
happy[1]=true; |
|||
int count=0; |
|||
int i=0; |
|||
while(count<8) { |
|||
if(happy[i]==null) { |
|||
int j=i; |
|||
Set<int> sequence=new Set<int>(); |
|||
while(happy[j]==null && !sequence.contains(j)) { |
|||
sequence.add(j); |
|||
int sum=0; |
|||
int val=j; |
|||
while(val>0) { |
|||
int digit=val%10; |
|||
sum+=digit*digit; |
|||
val=(val/10).toInt(); |
|||
} |
|||
j=sum; |
|||
} |
|||
bool sequenceHappy=happy[j]; |
|||
Iterator<int> it=sequence.iterator(); |
|||
while(it.hasNext()) { |
|||
happy[it.next()]=sequenceHappy; |
|||
} |
|||
} |
|||
if(happy[i]) { |
|||
print(i); |
|||
count++; |
|||
} |
|||
i++; |
|||
} |
|||
}</syntaxhighlight> |
|||
=={{header|dc}}== |
|||
<syntaxhighlight lang="dc">[lcI~rscd*+lc0<H]sH |
|||
[0rsclHxd4<h]sh |
|||
[lIp]s_ |
|||
0sI[lI1+dsIlhx2>_z8>s]dssx</syntaxhighlight> |
|||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|DCL}}== |
|||
<syntaxhighlight lang="dcl">$ happy_1 = 1 |
|||
$ found = 0 |
|||
$ i = 1 |
|||
$ loop1: |
|||
$ n = i |
|||
$ seen_list = "," |
|||
$ loop2: |
|||
$ if f$type( happy_'n ) .nes. "" then $ goto happy |
|||
$ if f$type( unhappy_'n ) .nes. "" then $ goto unhappy |
|||
$ if f$locate( "," + n + ",", seen_list ) .eq. f$length( seen_list ) |
|||
$ then |
|||
$ seen_list = seen_list + f$string( n ) + "," |
|||
$ else |
|||
$ goto unhappy |
|||
$ endif |
|||
$ ns = f$string( n ) |
|||
$ nl = f$length( ns ) |
|||
$ j = 0 |
|||
$ sumsq = 0 |
|||
$ loop3: |
|||
$ digit = f$integer( f$extract( j, 1, ns )) |
|||
$ sumsq = sumsq + digit * digit |
|||
$ j = j + 1 |
|||
$ if j .lt. nl then $ goto loop3 |
|||
$ n = sumsq |
|||
$ goto loop2 |
|||
$ unhappy: |
|||
$ j = 1 |
|||
$ loop4: |
|||
$ x = f$element( j, ",", seen_list ) |
|||
$ if x .eqs. "" then $ goto continue |
|||
$ unhappy_'x = 1 |
|||
$ j = j + 1 |
|||
$ goto loop4 |
|||
$ happy: |
|||
$ found = found + 1 |
|||
$ found_'found = i |
|||
$ if found .eq. 8 then $ goto done |
|||
$ j = 1 |
|||
$ loop5: |
|||
$ x = f$element( j, ",", seen_list ) |
|||
$ if x .eqs. "" then $ goto continue |
|||
$ happy_'x = 1 |
|||
$ j = j + 1 |
|||
$ goto loop5 |
|||
$ continue: |
|||
$ i = i + 1 |
|||
$ goto loop1 |
|||
$ done: |
|||
$ show symbol found*</syntaxhighlight> |
|||
{{out}} |
|||
<pre> FOUND = 8 Hex = 00000008 Octal = 00000000010 |
|||
FOUND_1 = 1 Hex = 00000001 Octal = 00000000001 |
|||
FOUND_2 = 7 Hex = 00000007 Octal = 00000000007 |
|||
FOUND_3 = 10 Hex = 0000000A Octal = 00000000012 |
|||
FOUND_4 = 13 Hex = 0000000D Octal = 00000000015 |
|||
FOUND_5 = 19 Hex = 00000013 Octal = 00000000023 |
|||
FOUND_6 = 23 Hex = 00000017 Octal = 00000000027 |
|||
FOUND_7 = 28 Hex = 0000001C Octal = 00000000034 |
|||
FOUND_8 = 31 Hex = 0000001F Octal = 00000000037</pre> |
|||
=={{header|Delphi}}== |
|||
{{libheader| System.SysUtils}} |
|||
{{libheader| Boost.Int}} |
|||
Adaptation of [[#Pascal]]. The lib '''Boost.Int''' can be found here [https://github.com/MaiconSoft/DelphiBoostLib] |
|||
<syntaxhighlight lang="delphi"> |
|||
program Happy_numbers; |
|||
{$APPTYPE CONSOLE} |
|||
uses |
|||
System.SysUtils, |
|||
Boost.Int; |
|||
type |
|||
TIntegerDynArray = TArray<Integer>; |
|||
TIntHelper = record helper for Integer |
|||
function IsHappy: Boolean; |
|||
procedure Next; |
|||
end; |
|||
{ TIntHelper } |
|||
function TIntHelper.IsHappy: Boolean; |
|||
var |
|||
cache: TIntegerDynArray; |
|||
sum, n: integer; |
|||
begin |
|||
n := self; |
|||
repeat |
|||
sum := 0; |
|||
while n > 0 do |
|||
begin |
|||
sum := sum + (n mod 10) * (n mod 10); |
|||
n := n div 10; |
|||
end; |
|||
if sum = 1 then |
|||
exit(True); |
|||
if cache.Has(sum) then |
|||
exit(False); |
|||
n := sum; |
|||
cache.Add(sum); |
|||
until false; |
|||
end; |
|||
procedure TIntHelper.Next; |
|||
begin |
|||
inc(self); |
|||
end; |
|||
var |
|||
count, n: integer; |
|||
begin |
|||
n := 1; |
|||
count := 0; |
|||
while count < 8 do |
|||
begin |
|||
if n.IsHappy then |
|||
begin |
|||
count.Next; |
|||
write(n, ' '); |
|||
end; |
|||
n.Next; |
|||
end; |
|||
writeln; |
|||
readln; |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
=={{header|Draco}}== |
|||
<syntaxhighlight lang="draco">proc nonrec dsumsq(byte n) byte: |
|||
byte r, d; |
|||
r := 0; |
|||
while n~=0 do |
|||
d := n % 10; |
|||
n := n / 10; |
|||
r := r + d * d |
|||
od; |
|||
r |
|||
corp |
|||
proc nonrec happy(byte n) bool: |
|||
[256] bool seen; |
|||
byte i; |
|||
for i from 0 upto 255 do seen[i] := false od; |
|||
while not seen[n] do |
|||
seen[n] := true; |
|||
n := dsumsq(n) |
|||
od; |
|||
seen[1] |
|||
corp |
|||
proc nonrec main() void: |
|||
byte n, seen; |
|||
n := 1; |
|||
seen := 0; |
|||
while seen < 8 do |
|||
if happy(n) then |
|||
writeln(n:3); |
|||
seen := seen + 1 |
|||
fi; |
|||
n := n + 1 |
|||
od |
|||
corp</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|DWScript}}== |
|||
<syntaxhighlight lang="delphi">function IsHappy(n : Integer) : Boolean; |
|||
var |
|||
cache : array of Integer; |
|||
sum : Integer; |
|||
begin |
|||
while True do begin |
|||
sum := 0; |
|||
while n>0 do begin |
|||
sum += Sqr(n mod 10); |
|||
n := n div 10; |
|||
end; |
|||
if sum = 1 then |
|||
Exit(True); |
|||
if sum in cache then |
|||
Exit(False); |
|||
n := sum; |
|||
cache.Add(sum); |
|||
end; |
|||
end; |
|||
var n := 8; |
|||
var i : Integer; |
|||
while n>0 do begin |
|||
Inc(i); |
|||
if IsHappy(i) then begin |
|||
PrintLn(i); |
|||
Dec(n); |
|||
end; |
|||
end;</syntaxhighlight> |
|||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Dyalect}}== |
|||
<syntaxhighlight lang="dyalect">func happy(n) { |
|||
var m = [] |
|||
while n > 1 { |
|||
m.Add(n) |
|||
var x = n |
|||
n = 0 |
|||
while x > 0 { |
|||
var d = x % 10 |
|||
n += d * d |
|||
x /= 10 |
|||
} |
|||
if m.IndexOf(n) != -1 { |
|||
return false |
|||
} |
|||
} |
|||
return true |
|||
} |
|||
var (n, found) = (1, 0) |
|||
while found < 8 { |
|||
if happy(n) { |
|||
print("\(n) ", terminator: "") |
|||
found += 1 |
|||
} |
|||
n += 1 |
|||
} |
|||
print()</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
=={{header|Déjà Vu}}== |
|||
<syntaxhighlight lang="dejavu">next-num: |
|||
0 |
|||
while over: |
|||
over |
|||
* dup % swap 10 |
|||
+ |
|||
swap floor / swap 10 swap |
|||
drop swap |
|||
is-happy happies n: |
|||
if has happies n: |
|||
return happies! n |
|||
local :seq set{ n } |
|||
n |
|||
while /= 1 dup: |
|||
next-num |
|||
if has seq dup: |
|||
drop |
|||
set-to happies n false |
|||
return false |
|||
if has happies dup: |
|||
set-to happies n dup happies! |
|||
return |
|||
set-to seq over true |
|||
drop |
|||
set-to happies n true |
|||
true |
|||
local :h {} |
|||
1 0 |
|||
while > 8 over: |
|||
if is-happy h dup: |
|||
!print( "A happy number: " over ) |
|||
swap ++ swap |
|||
++ |
|||
drop |
|||
drop</syntaxhighlight> |
|||
{{output}} |
|||
<pre>A happy number: 1 |
|||
A happy number: 7 |
|||
A happy number: 10 |
|||
A happy number: 13 |
|||
A happy number: 19 |
|||
A happy number: 23 |
|||
A happy number: 28 |
|||
A happy number: 31</pre> |
|||
=={{header|E}}== |
|||
{{output?|E}} |
|||
<syntaxhighlight lang="e">def isHappyNumber(var x :int) { |
|||
var seen := [].asSet() |
var seen := [].asSet() |
||
while (!seen.contains(x)) { |
while (!seen.contains(x)) { |
||
Line 353: | Line 2,842: | ||
println(x) |
println(x) |
||
if ((count += 1) >= 8) { break } |
if ((count += 1) >= 8) { break } |
||
}</ |
}</syntaxhighlight> |
||
=={{header|EasyLang}}== |
|||
<syntaxhighlight lang=text> |
|||
func dsum n . |
|||
while n > 0 |
|||
d = n mod 10 |
|||
s += d * d |
|||
n = n div 10 |
|||
. |
|||
return s |
|||
. |
|||
func happy n . |
|||
while n > 999 |
|||
n = dsum n |
|||
. |
|||
len seen[] 999 |
|||
repeat |
|||
n = dsum n |
|||
until seen[n] = 1 |
|||
seen[n] = 1 |
|||
. |
|||
return if n = 1 |
|||
. |
|||
while cnt < 8 |
|||
n += 1 |
|||
if happy n = 1 |
|||
cnt += 1 |
|||
write n & " " |
|||
. |
|||
. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|Eiffel}}== |
|||
<syntaxhighlight lang="eiffel"> |
|||
class |
|||
APPLICATION |
|||
create |
|||
make |
|||
feature {NONE} -- Initialization |
|||
make |
|||
-- Run application. |
|||
local |
|||
l_val: INTEGER |
|||
do |
|||
from |
|||
l_val := 1 |
|||
until |
|||
l_val > 100 |
|||
loop |
|||
if is_happy_number (l_val) then |
|||
print (l_val.out) |
|||
print ("%N") |
|||
end |
|||
l_val := l_val + 1 |
|||
end |
|||
end |
|||
feature -- Happy number |
|||
is_happy_number (a_number: INTEGER): BOOLEAN |
|||
-- Is `a_number' a happy number? |
|||
require |
|||
positive_number: a_number > 0 |
|||
local |
|||
l_number: INTEGER |
|||
l_set: ARRAYED_SET [INTEGER] |
|||
do |
|||
from |
|||
l_number := a_number |
|||
create l_set.make (10) |
|||
until |
|||
l_number = 1 or l_set.has (l_number) |
|||
loop |
|||
l_set.put (l_number) |
|||
l_number := square_sum_of_digits (l_number) |
|||
end |
|||
Result := (l_number = 1) |
|||
end |
|||
feature{NONE} -- Implementation |
|||
square_sum_of_digits (a_number: INTEGER): INTEGER |
|||
-- Sum of the sqares of digits of `a_number'. |
|||
require |
|||
positive_number: a_number > 0 |
|||
local |
|||
l_number, l_digit: INTEGER |
|||
do |
|||
from |
|||
l_number := a_number |
|||
until |
|||
l_number = 0 |
|||
loop |
|||
l_digit := l_number \\ 10 |
|||
Result := Result + l_digit * l_digit |
|||
l_number := l_number // 10 |
|||
end |
|||
end |
|||
end |
|||
</syntaxhighlight> |
|||
=={{header|Elena}}== |
|||
{{trans|C#}} |
|||
ELENA 6.x : |
|||
<syntaxhighlight lang="elena">import extensions; |
|||
import system'collections; |
|||
import system'routines; |
|||
isHappy(int n) |
|||
{ |
|||
auto cache := new List<int>(5); |
|||
int sum := 0; |
|||
int num := n; |
|||
while (num != 1) |
|||
{ |
|||
if (cache.indexOfElement(num) != -1) |
|||
{ |
|||
^ false |
|||
}; |
|||
cache.append(num); |
|||
while (num != 0) |
|||
{ |
|||
int digit := num.mod(10); |
|||
sum += (digit*digit); |
|||
num /= 10 |
|||
}; |
|||
num := sum; |
|||
sum := 0 |
|||
}; |
|||
^ true |
|||
} |
|||
public program() |
|||
{ |
|||
auto happynums := new List<int>(8); |
|||
int num := 1; |
|||
while (happynums.Length < 8) |
|||
{ |
|||
if (isHappy(num)) |
|||
{ |
|||
happynums.append(num) |
|||
}; |
|||
num += 1 |
|||
}; |
|||
console.printLine("First 8 happy numbers: ", happynums.asEnumerable()) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
First 8 happy numbers: 1,7,10,13,19,23,28,31 |
|||
</pre> |
|||
=={{header|Elixir}}== |
|||
<syntaxhighlight lang="elixir">defmodule Happy do |
|||
def task(num) do |
|||
Process.put({:happy, 1}, true) |
|||
Stream.iterate(1, &(&1+1)) |
|||
|> Stream.filter(fn n -> happy?(n) end) |
|||
|> Enum.take(num) |
|||
end |
|||
defp happy?(n) do |
|||
sum = square_sum(n, 0) |
|||
val = Process.get({:happy, sum}) |
|||
if val == nil do |
|||
Process.put({:happy, sum}, false) |
|||
val = happy?(sum) |
|||
Process.put({:happy, sum}, val) |
|||
end |
|||
val |
|||
end |
|||
defp square_sum(0, sum), do: sum |
|||
defp square_sum(n, sum) do |
|||
r = rem(n, 10) |
|||
square_sum(div(n, 10), sum + r*r) |
|||
end |
|||
end |
|||
IO.inspect Happy.task(8)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[1, 7, 10, 13, 19, 23, 28, 31] |
|||
</pre> |
|||
=={{header|Erlang}}== |
|||
<syntaxhighlight 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, []). |
|||
</syntaxhighlight> |
|||
Command: <syntaxhighlight lang="bash">erl -run tasks main -run init stop -noshell</syntaxhighlight> |
|||
Output: <syntaxhighlight lang="bash">8 Happy Numbers: [1,7,10,13,19,23,28,31]</syntaxhighlight> |
|||
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): |
|||
<syntaxhighlight 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.</syntaxhighlight> |
|||
Output: |
|||
<pre>[1,7,10,13,19,23,28,31]</pre> |
|||
=={{header|Euphoria}}== |
|||
<syntaxhighlight lang="euphoria">function is_happy(integer n) |
|||
sequence seen |
|||
integer k |
|||
seen = {} |
|||
while n > 1 do |
|||
seen &= n |
|||
k = 0 |
|||
while n > 0 do |
|||
k += power(remainder(n,10),2) |
|||
n = floor(n/10) |
|||
end while |
|||
n = k |
|||
if find(n,seen) then |
|||
return 0 |
|||
end if |
|||
end while |
|||
return 1 |
|||
end function |
|||
integer n,count |
|||
n = 1 |
|||
count = 0 |
|||
while count < 8 do |
|||
if is_happy(n) then |
|||
? n |
|||
count += 1 |
|||
end if |
|||
n += 1 |
|||
end while</syntaxhighlight> |
|||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
=={{header|F_Sharp|F#}}== |
|||
This requires the F# power pack to be referenced and the 2010 beta of F# |
|||
<syntaxhighlight 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 |
|||
|> Seq.iter (Printf.printf "%d\n") // Print results |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
=={{header|Factor}}== |
|||
<syntaxhighlight 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 ;</syntaxhighlight> |
|||
{{out}} |
|||
<syntaxhighlight lang="factor">8 happy-numbers ! { 1 7 10 13 19 23 28 31 }</syntaxhighlight> |
|||
=={{header|FALSE}}== |
|||
<syntaxhighlight lang="false">[$10/$10*@\-$*\]m: {modulo squared and division} |
|||
[$m;![$9>][m;!@@+\]#$*+]s: {sum of squares} |
|||
[$0[1ø1>][1ø3+ø3ø=|\1-\]#\%]f: {look for duplicates} |
|||
{check happy number} |
|||
[ |
|||
$1[f;!~2ø1=~&][1+\s;!@]# {loop over sequence until 1 or duplicate} |
|||
1ø1= {return value} |
|||
\[$0=~][@%1-]#% {drop sequence and counter} |
|||
]h: |
|||
0 1 |
|||
"Happy numbers:" |
|||
[1ø8=~][h;![" "$.\1+\]?1+]# |
|||
%%</syntaxhighlight> |
|||
{{out}} |
|||
<pre>Happy numbers: 1 7 10 13 19 23 28 31</pre> |
|||
=={{header|Fantom}}== |
|||
<syntaxhighlight 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 |
|||
} |
|||
} |
|||
} |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
=={{header|FOCAL}}== |
|||
<syntaxhighlight lang="focal">01.10 S J=0;S N=1;T %2 |
|||
01.20 D 3;I (K-2)1.5 |
|||
01.30 S N=N+1 |
|||
01.40 I (J-8)1.2;Q |
|||
01.50 T N,! |
|||
01.60 S J=J+1 |
|||
01.70 G 1.3 |
|||
02.10 S A=K;S R=0 |
|||
02.20 S B=FITR(A/10) |
|||
02.30 S R=R+(A-10*B)^2 |
|||
02.40 S A=B |
|||
02.50 I (-A)2.2 |
|||
03.10 F X=0,162;S S(X)=-1 |
|||
03.20 S K=N |
|||
03.30 S S(K)=0 |
|||
03.40 D 2;S K=R |
|||
03.50 I (S(K))3.3</syntaxhighlight> |
|||
{{out}} |
|||
<pre>= 1 |
|||
= 7 |
|||
= 10 |
|||
= 13 |
|||
= 19 |
|||
= 23 |
|||
= 28 |
|||
= 31</pre> |
|||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
<syntaxhighlight lang="forth">: next ( n -- n ) |
|||
<lang forth> |
|||
: next ( n -- n ) |
|||
0 swap begin 10 /mod >r dup * + r> ?dup 0= until ; |
0 swap begin 10 /mod >r dup * + r> ?dup 0= until ; |
||
Line 376: | Line 3,330: | ||
loop drop ; |
loop drop ; |
||
8 happy-numbers \ 1 7 10 13 19 23 28 31 |
8 happy-numbers \ 1 7 10 13 19 23 28 31</syntaxhighlight> |
||
</lang> |
|||
===Lookup Table=== |
|||
Every sequence either ends in 1, or contains a 4 as part of a cycle. Extending the table through 9 is a (modest) optimization/memoization. This executes '500000 happy-numbers' about 5 times faster than the above solution. |
|||
<syntaxhighlight lang="forth">CREATE HAPPINESS 0 C, 1 C, 0 C, 0 C, 0 C, 0 C, 0 C, 1 C, 0 C, 0 C, |
|||
: next ( n -- n') |
|||
0 swap BEGIN dup WHILE 10 /mod >r dup * + r> REPEAT drop ; |
|||
: happy? ( n -- t|f) |
|||
BEGIN dup 10 >= WHILE next REPEAT chars HAPPINESS + C@ 0<> ; |
|||
: happy-numbers ( n --) >r 0 |
|||
BEGIN r@ WHILE |
|||
BEGIN 1+ dup happy? UNTIL dup . r> 1- >r |
|||
REPEAT r> drop drop ; |
|||
8 happy-numbers</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
Produces the 1 millionth happy number with: |
|||
<syntaxhighlight lang="forth">: happy-number ( n -- n') \ produce the nth happy number |
|||
>r 0 BEGIN r@ WHILE |
|||
BEGIN 1+ dup happy? UNTIL r> 1- >r |
|||
REPEAT r> drop ; |
|||
1000000 happy-number . \ 7105849</syntaxhighlight> |
|||
in about 9 seconds. |
|||
=={{header|Fortran}}== |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Frege}}== |
|||
{{trans|Haskell}} |
|||
{{Works with|Frege|3.21.586-g026e8d7}} |
|||
<syntaxhighlight lang="frege">module Happy where |
|||
import Prelude.Math |
|||
-- ugh, since Frege doesn't have Set, use Map instead |
|||
import Data.Map (member, insertMin, empty emptyMap) |
|||
digitToInteger :: Char -> Integer |
|||
digitToInteger c = fromInt $ (ord c) - (ord '0') |
|||
isHappy :: Integer -> Bool |
|||
isHappy = p emptyMap |
|||
where p _ 1n = true |
|||
p s n | n `member` s = false |
|||
| otherwise = p (insertMin n () s) (f n) |
|||
f = sum . map (sqr . digitToInteger) . unpacked . show |
|||
main _ = putStrLn $ unwords $ map show $ take 8 $ filter isHappy $ iterate (+ 1n) 1n</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 7 10 13 19 23 28 31 |
|||
runtime 0.614 wallclock seconds. |
|||
</pre> |
|||
=={{header|FutureBasic}}== |
|||
<syntaxhighlight lang="futurebasic"> |
|||
include "NSLog.incl" |
|||
local fn IsHappy( num as NSUInteger ) as NSUInteger |
|||
NSUInteger i, happy = 0, count = 0 |
|||
while ( count < 50 ) and ( happy != 1 ) |
|||
CFStringRef numStr = str( num ) |
|||
count++ : happy = 0 |
|||
for i = 1 to len( numStr ) |
|||
happy = happy + fn StringIntegerValue( mid( numStr, i, 1 ) ) ^ 2 |
|||
next |
|||
num = happy |
|||
wend |
|||
end fn = num |
|||
void local fn HappyNumbers |
|||
NSUInteger i, count = 0 |
|||
for i = 1 to 100 |
|||
if ( fn IsHappy(i) == 1 ) |
|||
count++ |
|||
NSLog( @"%2lu. %2lu is a happy number", count, i ) |
|||
if count == 8 then exit fn |
|||
end if |
|||
next |
|||
end fn |
|||
fn HappyNumbers |
|||
HandleEvents |
|||
</syntaxhighlight> |
|||
{{output}} |
|||
<pre> |
|||
1. 1 is a happy number |
|||
2. 7 is a happy number |
|||
3. 10 is a happy number |
|||
4. 13 is a happy number |
|||
5. 19 is a happy number |
|||
6. 23 is a happy number |
|||
7. 28 is a happy number |
|||
8. 31 is a happy number |
|||
</pre> |
|||
=={{header|Fōrmulæ}}== |
|||
{{FormulaeEntry|page=https://formulae.org/?script=examples/Happy_numbers}} |
|||
'''Solution.''' |
|||
The following function returns whether a given number is happy or not: |
|||
[[File:Fōrmulæ - Happy numbers 01.png]] |
|||
Retrieving the first 8 happy numbers |
|||
[[File:Fōrmulæ - Happy numbers 02.png]] |
|||
[[File:Fōrmulæ - Happy numbers 03.png]] |
|||
=={{header|Go}}== |
|||
<syntaxhighlight lang="go">package main |
|||
import "fmt" |
|||
func happy(n int) bool { |
|||
m := make(map[int]bool) |
|||
for n > 1 { |
|||
m[n] = true |
|||
var x int |
|||
for x, n = n, 0; x > 0; x /= 10 { |
|||
d := x % 10 |
|||
n += d * d |
|||
} |
|||
if m[n] { |
|||
return false |
|||
} |
|||
} |
|||
return true |
|||
} |
|||
func main() { |
|||
for found, n := 0, 1; found < 8; n++ { |
|||
if happy(n) { |
|||
fmt.Print(n, " ") |
|||
found++ |
|||
} |
|||
} |
|||
fmt.Println() |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|Groovy}}== |
|||
<syntaxhighlight lang="groovy">Number.metaClass.isHappy = { |
|||
def number = delegate as Long |
|||
def cycle = new HashSet<Long>() |
|||
while (number != 1 && !cycle.contains(number)) { |
|||
cycle << number |
|||
number = (number as String).collect { d = (it as Long); d * d }.sum() |
|||
} |
|||
number == 1 |
|||
} |
|||
def matches = [] |
|||
for (int i = 0; matches.size() < 8; i++) { |
|||
if (i.happy) { matches << i } |
|||
} |
|||
println matches</syntaxhighlight> |
|||
{{out}} |
|||
<pre>[1, 7, 10, 13, 19, 23, 28, 31]</pre> |
|||
=={{header|Harbour}}== |
|||
<syntaxhighlight lang="xbase">PROCEDURE Main() |
|||
LOCAL i := 8, nH := 0 |
|||
? hb_StrFormat( "The first %d happy numbers are:", i ) |
|||
? |
|||
WHILE i > 0 |
|||
IF IsHappy( ++nH ) |
|||
?? hb_NtoS( nH ) + " " |
|||
--i |
|||
ENDIF |
|||
END |
|||
RETURN |
|||
STATIC FUNCTION IsHappy( nNumber ) |
|||
STATIC aUnhappy := {} |
|||
LOCAL nDigit, nSum := 0, cNumber := hb_NtoS( nNumber ) |
|||
FOR EACH nDigit IN cNumber |
|||
nSum += Val( nDigit ) ^ 2 |
|||
NEXT |
|||
IF nSum == 1 |
|||
aUnhappy := {} |
|||
RETURN .T. |
|||
ELSEIF AScan( aUnhappy, nSum ) > 0 |
|||
RETURN .F. |
|||
ENDIF |
|||
AAdd( aUnhappy, nSum ) |
|||
RETURN IsHappy( nSum )</syntaxhighlight> |
|||
Output: |
|||
The first 8 happy numbers are: |
|||
1 7 10 13 19 23 28 31 |
|||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
< |
<syntaxhighlight lang="haskell">import Data.Char (digitToInt) |
||
import Data.Set (member, insert, empty) |
|||
isHappy :: Integer -> Bool |
|||
happys :: [Int] |
|||
isHappy = p empty |
|||
happys = filter (p []) [1..] |
|||
where |
where |
||
p _ 1 = True |
|||
p s n |
|||
| otherwise = p (n : l) (f n) |
|||
| n `member` s = False |
|||
f = sum . map ((^2) . digitToInt) . show |
|||
| otherwise = p (insert n s) (f n) |
|||
f = sum . fmap ((^ 2) . toInteger . digitToInt) . show |
|||
main :: IO () |
|||
main = mapM_ print $ take 8 happys</lang> |
|||
main = mapM_ print $ take 8 $ filter isHappy [1 ..]</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
We can create a cache for small numbers to greatly speed up the process: |
|||
=={{header|J}}== |
|||
<syntaxhighlight lang="haskell">import Data.Array (Array, (!), listArray) |
|||
<lang j> |
|||
8{. (#~1=+/@(*:@(,.&.":))^:(1&~:*.4&~:)^:_ "0) 1+i.100 |
|||
1 7 10 13 19 23 28 31</lang> |
|||
happy :: Int -> Bool |
|||
happy x |
|||
| xx <= 150 = seen ! xx |
|||
| otherwise = happy xx |
|||
where |
|||
xx = dsum x |
|||
seen :: Array Int Bool |
|||
seen = |
|||
listArray (1, 150) $ True : False : False : False : (happy <$> [5 .. 150]) |
|||
dsum n |
|||
| n < 10 = n * n |
|||
| otherwise = |
|||
let (q, r) = n `divMod` 10 |
|||
in r * r + dsum q |
|||
main :: IO () |
|||
main = print $ sum $ take 10000 $ filter happy [1 ..]</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>327604323</pre> |
|||
=={{header|Icon}} and {{header|Unicon}}== |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
Usage and Output: |
|||
<pre> |
|||
| happynum.exe |
|||
The first 8 happy numbers are: 1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|J}}== |
|||
<syntaxhighlight lang="j"> 8{. (#~1=+/@(*:@(,.&.":))^:(1&~:*.4&~:)^:_ "0) 1+i.100 |
|||
1 7 10 13 19 23 28 31</syntaxhighlight> |
|||
This is a repeat while construction |
This is a repeat while construction |
||
< |
<syntaxhighlight lang="j"> f ^: cond ^: _ input</syntaxhighlight> |
||
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. |
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. |
||
< |
<syntaxhighlight lang="j"> (binary array) # 1..100</syntaxhighlight> |
||
So for easier reading the solution could be expressed as: |
So for easier reading the solution could be expressed as: |
||
< |
<syntaxhighlight lang="j"> cond=: 1&~: *. 4&~: NB. not equal to 1 and not equal to 4 |
||
sumSqrDigits=: +/@(*:@(,.&.":)) |
sumSqrDigits=: +/@(*:@(,.&.":)) |
||
Line 408: | Line 3,703: | ||
14 |
14 |
||
8{. (#~ 1 = sumSqrDigits ^: cond ^:_ "0) 1 + i.100 |
8{. (#~ 1 = sumSqrDigits ^: cond ^:_ "0) 1 + i.100 |
||
1 7 10 13 19 23 28 31</ |
1 7 10 13 19 23 28 31</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{works with|Java|1.5+}} |
{{works with|Java|1.5+}} |
||
{{trans|JavaScript}} |
{{trans|JavaScript}} |
||
< |
<syntaxhighlight lang="java5">import java.util.HashSet; |
||
public class Happy{ |
public class Happy{ |
||
public static boolean happy(long number){ |
public static boolean happy(long number){ |
||
long m = 0; |
long m = 0; |
||
int digit = 0; |
int digit = 0; |
||
HashSet<Long> cycle = new HashSet<Long>(); |
|||
while(number != 1 && |
while(number != 1 && cycle.add(number)){ |
||
cycle.add(number); |
|||
m = 0; |
m = 0; |
||
while(number > 0){ |
while(number > 0){ |
||
Line 441: | Line 3,734: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
===Java 1.8=== |
|||
{{works with|Java|1.8}} |
|||
{{trans|Java}} |
|||
<syntaxhighlight lang="java"> |
|||
import java.util.Arrays; |
|||
import java.util.HashSet; |
|||
import java.util.List; |
|||
public class HappyNumbers { |
|||
public static void main(String[] args) { |
|||
for (int current = 1, total = 0; total < 8; current++) |
|||
if (isHappy(current)) { |
|||
System.out.println(current); |
|||
total++; |
|||
} |
|||
} |
|||
public static boolean isHappy(int number) { |
|||
HashSet<Integer> cycle = new HashSet<>(); |
|||
while (number != 1 && cycle.add(number)) { |
|||
List<String> numStrList = Arrays.asList(String.valueOf(number).split("")); |
|||
number = numStrList.stream().map(i -> Math.pow(Integer.parseInt(i), 2)).mapToInt(i -> i.intValue()).sum(); |
|||
} |
|||
return number == 1; |
|||
} |
|||
}</syntaxhighlight> |
|||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
<lang javascript>function happy(number) { |
|||
var m, digit ; |
|||
var cycle = new Array() ; |
|||
===ES5=== |
|||
while(number != 1 && cycle[number] != true) { |
|||
====Iteration==== |
|||
<syntaxhighlight lang="javascript">function happy(number) { |
|||
var m, digit ; |
|||
var cycle = [] ; |
|||
while(number != 1 && cycle[number] !== true) { |
|||
cycle[number] = true ; |
cycle[number] = true ; |
||
m = 0 ; |
m = 0 ; |
||
Line 459: | Line 3,806: | ||
} |
} |
||
return (number == 1) ; |
return (number == 1) ; |
||
} |
} |
||
var cnt = 8 ; |
var cnt = 8 ; |
||
var number = 1 ; |
var number = 1 ; |
||
while(cnt-- > 0) { |
while(cnt-- > 0) { |
||
while(!happy(number)) |
while(!happy(number)) |
||
Line 469: | Line 3,816: | ||
document.write(number + " ") ; |
document.write(number + " ") ; |
||
number++ ; |
number++ ; |
||
}</ |
}</syntaxhighlight> |
||
Output: |
|||
<pre>1 7 10 13 19 23 28 31 </pre> |
|||
===ES6=== |
|||
====Functional composition==== |
|||
{{Trans|Haskell}} |
|||
<syntaxhighlight lang="javascript">(() => { |
|||
// isHappy :: Int -> Bool |
|||
const isHappy = n => { |
|||
const f = n => |
|||
foldl( |
|||
(a, x) => a + raise(read(x), 2), // ^2 |
|||
0, |
|||
splitOn('', show(n)) |
|||
), |
|||
p = (s, n) => n === 1 ? ( |
|||
true |
|||
) : member(n, s) ? ( |
|||
false |
|||
) : p( |
|||
insert(n, s), f(n) |
|||
); |
|||
return p(new Set(), n); |
|||
}; |
|||
// GENERIC FUNCTIONS ------------------------------------------------------ |
|||
// enumFromTo :: Int -> Int -> [Int] |
|||
const enumFromTo = (m, n) => |
|||
Array.from({ |
|||
length: Math.floor(n - m) + 1 |
|||
}, (_, i) => m + i); |
|||
// filter :: (a -> Bool) -> [a] -> [a] |
|||
const filter = (f, xs) => xs.filter(f); |
|||
// foldl :: (b -> a -> b) -> b -> [a] -> b |
|||
const foldl = (f, a, xs) => xs.reduce(f, a); |
|||
// insert :: Ord a => a -> Set a -> Set a |
|||
const insert = (e, s) => s.add(e); |
|||
// member :: Ord a => a -> Set a -> Bool |
|||
const member = (e, s) => s.has(e); |
|||
// read :: Read a => String -> a |
|||
const read = JSON.parse; |
|||
// show :: a -> String |
|||
const show = x => JSON.stringify(x); |
|||
// splitOn :: String -> String -> [String] |
|||
const splitOn = (cs, xs) => xs.split(cs); |
|||
// raise :: Num -> Int -> Num |
|||
const raise = (n, e) => Math.pow(n, e); |
|||
// take :: Int -> [a] -> [a] |
|||
const take = (n, xs) => xs.slice(0, n); |
|||
// TEST ------------------------------------------------------------------- |
|||
return show( |
|||
take(8, filter(isHappy, enumFromTo(1, 50))) |
|||
); |
|||
})()</syntaxhighlight> |
|||
{{Out}} |
|||
<syntaxhighlight lang="javascript">[1, 7, 10, 13, 19, 23, 28, 31]</syntaxhighlight> |
|||
Or, to stop immediately at the 8th member of the series, we can preserve functional composition while using an iteratively implemented '''until()''' function: |
|||
<syntaxhighlight lang="javascript">(() => { |
|||
// isHappy :: Int -> Bool |
|||
const isHappy = n => { |
|||
const f = n => |
|||
foldl( |
|||
(a, x) => a + raise(read(x), 2), // ^2 |
|||
0, |
|||
splitOn('', show(n)) |
|||
), |
|||
p = (s, n) => n === 1 ? ( |
|||
true |
|||
) : member(n, s) ? ( |
|||
false |
|||
) : p( |
|||
insert(n, s), f(n) |
|||
); |
|||
return p(new Set(), n); |
|||
}; |
|||
// GENERIC FUNCTIONS ------------------------------------------------------ |
|||
// filter :: (a -> Bool) -> [a] -> [a] |
|||
const filter = (f, xs) => xs.filter(f); |
|||
// foldl :: (b -> a -> b) -> b -> [a] -> b |
|||
const foldl = (f, a, xs) => xs.reduce(f, a); |
|||
// insert :: Ord a => a -> Set a -> Set a |
|||
const insert = (e, s) => s.add(e); |
|||
// member :: Ord a => a -> Set a -> Bool |
|||
const member = (e, s) => s.has(e); |
|||
// read :: Read a => String -> a |
|||
const read = JSON.parse; |
|||
// show :: a -> String |
|||
const show = x => JSON.stringify(x); |
|||
// splitOn :: String -> String -> [String] |
|||
const splitOn = (cs, xs) => xs.split(cs); |
|||
// raise :: Num -> Int -> Num |
|||
const raise = (n, e) => Math.pow(n, e); |
|||
// until :: (a -> Bool) -> (a -> a) -> a -> a |
|||
const until = (p, f, x) => { |
|||
let v = x; |
|||
while (!p(v)) v = f(v); |
|||
return v; |
|||
}; |
|||
// TEST ------------------------------------------------------------------- |
|||
return show( |
|||
until( |
|||
m => m.xs.length === 8, |
|||
m => { |
|||
const n = m.n; |
|||
return { |
|||
n: n + 1, |
|||
xs: isHappy(n) ? m.xs.concat(n) : m.xs |
|||
}; |
|||
}, { |
|||
n: 1, |
|||
xs: [] |
|||
} |
|||
) |
|||
.xs |
|||
); |
|||
})();</syntaxhighlight> |
|||
{{Out}} |
|||
<syntaxhighlight lang="javascript">[1, 7, 10, 13, 19, 23, 28, 31]</syntaxhighlight> |
|||
=={{header|jq}}== |
|||
{{works with|jq|1.4}} |
|||
<syntaxhighlight lang="jq">def is_happy_number: |
|||
def next: tostring | explode | map( (. - 48) | .*.) | add; |
|||
def last(g): reduce g as $i (null; $i); |
|||
# state: either 1 or [i, o] |
|||
# where o is an an object with the previously encountered numbers as keys |
|||
def loop: |
|||
recurse( if . == 1 then empty # all done |
|||
elif .[0] == 1 then 1 # emit 1 |
|||
else (.[0]| next) as $n |
|||
| if $n == 1 then 1 |
|||
elif .[1]|has($n|tostring) then empty |
|||
else [$n, (.[1] + {($n|tostring):true}) ] |
|||
end |
|||
end ); |
|||
1 == last( [.,{}] | loop );</syntaxhighlight> |
|||
'''Emit a stream of the first n happy numbers''': |
|||
<syntaxhighlight lang="jq"># Set n to -1 to continue indefinitely: |
|||
def happy(n): |
|||
def subtask: # state: [i, found] |
|||
if .[1] == n then empty |
|||
else .[0] as $n |
|||
| if ($n | is_happy_number) then $n, ([ $n+1, .[1]+1 ] | subtask) |
|||
else (.[0] += 1) | subtask |
|||
end |
|||
end; |
|||
[0,0] | subtask; |
|||
happy($n|tonumber)</syntaxhighlight> |
|||
{{out}} |
|||
<syntaxhighlight lang="sh">$ jq --arg n 8 -n -f happy.jq |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</syntaxhighlight> |
|||
=={{header|Julia}}== |
|||
<syntaxhighlight lang="julia"> |
|||
function happy(x) |
|||
happy_ints = Int[] |
|||
int_try = 1 |
|||
while length(happy_ints) < x |
|||
n = int_try |
|||
past = Int[] |
|||
while n != 1 |
|||
n = sum(y^2 for y in digits(n)) |
|||
n in past && break |
|||
push!(past, n) |
|||
end |
|||
n == 1 && push!(happy_ints,int_try) |
|||
int_try += 1 |
|||
end |
|||
return happy_ints |
|||
end</syntaxhighlight> |
|||
Output |
|||
<pre> julia> happy(8) |
|||
8-element Int32 Array: |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
A recursive version: |
|||
<syntaxhighlight lang="julia">sumhappy(n) = sum(x->x^2, digits(n)) |
|||
function ishappy(x, mem = Int[]) |
|||
x == 1 ? true : |
|||
x in mem ? false : |
|||
ishappy(sumhappy(x), [mem ; x]) |
|||
end |
|||
nexthappy(x) = ishappy(x+1) ? x+1 : nexthappy(x+1) |
|||
happy(n) = accumulate((a, b) -> nexthappy(a), 1:n) |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>julia> show(happy(8)) |
|||
[1,7,10,13,19,23,28,31,32]</pre> |
|||
Alternate, Translation of C<br> |
|||
Faster with use of cache |
|||
{{trans|C}} |
|||
<syntaxhighlight lang="julia">const CACHE = 256 |
|||
buf = zeros(Int, CACHE) |
|||
buf[begin] = 1 |
|||
function happy(n) |
|||
if n < CACHE |
|||
buf[n] > 0 && return 2-buf[n] |
|||
buf[n] = 2 |
|||
end |
|||
sqsum = 0 |
|||
nn = n |
|||
while nn != 0 |
|||
nn, x = divrem(nn, 10) |
|||
sqsum += x * x |
|||
end |
|||
x = happy(sqsum) |
|||
n < CACHE && (buf[n] = 2 - x) |
|||
return x |
|||
end |
|||
function main() |
|||
i, counter = 1, 1000000 |
|||
while counter > 0 |
|||
if happy(i) != 0 |
|||
counter -= 1 |
|||
end |
|||
i += 1 |
|||
end |
|||
return i - 1 |
|||
end |
|||
</syntaxhighlight> |
|||
=={{header|K}}== |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
Another implementation which is easy to follow is given below: |
|||
<syntaxhighlight lang="k"> |
|||
/ happynum.k |
|||
/ sum of squares of digits of an integer |
|||
dgtsmsqr: {d::(); (0<){d::d,x!10; x%:10}/x; +/d*d} |
|||
/ Test if an integer is a Happy number |
|||
isHappy: {s::(); while[1<x;a:(dgtsmsqr x); :[(a _in s); :0; s::s,a]; x:a];:1} / Returns 1 if Happy |
|||
/ Generate first x Happy numbers and display the list |
|||
hnum: {[x]; h::();i:1;while[(#h)<x; :[(isHappy i); h::(h,i)]; i+:1]; `0: ,"List of ", ($x), " Happy Numbers"; h} |
|||
</syntaxhighlight> |
|||
The output of a session with this implementation is given below: |
|||
{{out}} |
|||
<pre> |
|||
K Console - Enter \ for help |
|||
\l happynum |
|||
hnum 8 |
|||
List of 8 Happy Numbers |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|Kotlin}}== |
|||
{{trans|C#}} |
|||
<syntaxhighlight lang="scala">// version 1.0.5-2 |
|||
fun isHappy(n: Int): Boolean { |
|||
val cache = mutableListOf<Int>() |
|||
var sum = 0 |
|||
var nn = n |
|||
var digit: Int |
|||
while (nn != 1) { |
|||
if (nn in cache) return false |
|||
cache.add(nn) |
|||
while (nn != 0) { |
|||
digit = nn % 10 |
|||
sum += digit * digit |
|||
nn /= 10 |
|||
} |
|||
nn = sum |
|||
sum = 0 |
|||
} |
|||
return true |
|||
} |
|||
fun main(args: Array<String>) { |
|||
var num = 1 |
|||
val happyNums = mutableListOf<Int>() |
|||
while (happyNums.size < 8) { |
|||
if (isHappy(num)) happyNums.add(num) |
|||
num++ |
|||
} |
|||
println("First 8 happy numbers : " + happyNums.joinToString(", ")) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
First 8 happy numbers : 1, 7, 10, 13, 19, 23, 28, 31 |
|||
</pre> |
|||
=={{header|Lambdatalk}}== |
|||
<syntaxhighlight lang="scheme"> |
|||
{def happy |
|||
{def happy.sum |
|||
{lambda {:n} |
|||
{if {= {W.length :n} 1} |
|||
then {pow {W.first :n} 2} |
|||
else {+ {pow {W.first :n} 2} |
|||
{happy.sum {W.rest :n}}}}}} |
|||
{def happy.is |
|||
{lambda {:x :a} |
|||
{if {= :x 1} |
|||
then true |
|||
else {if {> {A.in? :x :a} -1} |
|||
then false |
|||
else {happy.is {happy.sum :x} |
|||
{A.addlast! :x :a}}}}}} |
|||
{def happy.rec |
|||
{lambda {:n :a :i} |
|||
{if {= {A.length :a} :n} |
|||
then :a |
|||
else {happy.rec :n |
|||
{if {happy.is :i {A.new}} |
|||
then {A.addlast! :i :a} |
|||
else :a} |
|||
{+ :i 1}}}}} |
|||
{lambda {:n} |
|||
{happy.rec :n {A.new} 0}}} |
|||
-> happy |
|||
{happy 8} |
|||
-> [1,7,10,13,19,23,28,31] |
|||
</syntaxhighlight> |
|||
=={{header|Lasso}}== |
|||
<syntaxhighlight lang="lasso">#!/usr/bin/lasso9 |
|||
define isHappy(n::integer) => { |
|||
local(past = set) |
|||
while(#n != 1) => { |
|||
#n = with i in string(#n)->values sum math_pow(integer(#i), 2) |
|||
#past->contains(#n) ? return false | #past->insert(#n) |
|||
} |
|||
return true |
|||
} |
|||
with x in generateSeries(1, 500) |
|||
where isHappy(#x) |
|||
take 8 |
|||
select #x</syntaxhighlight> |
|||
Output: |
|||
<syntaxhighlight lang="lasso">1, 7, 10, 13, 19, 23, 28, 31</syntaxhighlight> |
|||
=={{header|Logo}}== |
|||
<syntaxhighlight lang="logo">to sum_of_square_digits :number |
|||
output (apply "sum (map [[d] d*d] ` :number)) |
|||
end |
|||
to is_happy? :number [:seen []] |
|||
output cond [ |
|||
[ [:number = 1] "true ] |
|||
[ [member? :number :seen] "false ] |
|||
[ else (is_happy? (sum_of_square_digits :number) (lput :number :seen))] |
|||
] |
|||
end |
|||
to n_happy :count [:start 1] [:result []] |
|||
output cond [ |
|||
[ [:count <= 0] :result ] |
|||
[ [is_happy? :start] |
|||
(n_happy (:count-1) (:start+1) (lput :start :result)) ] |
|||
[ else |
|||
(n_happy :count (:start+1) :result) ] |
|||
] |
|||
end |
|||
print n_happy 8 |
|||
bye</syntaxhighlight> |
|||
Output: |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
=={{header|LOLCODE}}== |
|||
{{works with|lci 0.10.3}} |
|||
<syntaxhighlight lang="lolcode">OBTW |
|||
Happy Numbers Rosetta Code task in LOLCODE |
|||
Requires 1.3 for BUKKIT availability |
|||
TLDR |
|||
HAI 1.3 |
|||
CAN HAS STDIO? |
|||
BTW Simple list implementation. |
|||
BTW Used for the list of numbers already seen in IZHAPPY |
|||
BTW Create a list |
|||
HOW IZ I MAEKLIST |
|||
I HAS A LIST ITZ A BUKKIT |
|||
LIST HAS A LENGTH ITZ 0 |
|||
FOUND YR LIST |
|||
IF U SAY SO |
|||
BTW Append an item to list |
|||
HOW IZ I PUTIN YR LIST AN YR ITEM |
|||
LIST HAS A SRS LIST'Z LENGTH ITZ ITEM |
|||
LIST'Z LENGTH R SUM OF LIST'Z LENGTH AN 1 |
|||
IF U SAY SO |
|||
BTW Check for presence of an item in the list |
|||
HOW IZ I DUZLISTHAS YR HAYSTACK AN YR NEEDLE |
|||
IM IN YR BARN UPPIN YR INDEX WILE DIFFRINT INDEX AN HAYSTACK'Z LENGTH |
|||
I HAS A ITEM ITZ HAYSTACK'Z SRS INDEX |
|||
BOTH SAEM ITEM AN NEEDLE |
|||
O RLY? |
|||
YA RLY |
|||
FOUND YR WIN |
|||
OIC |
|||
IM OUTTA YR BARN |
|||
FOUND YR FAIL |
|||
IF U SAY SO |
|||
BTW Calculate the next number using the happy formula |
|||
HOW IZ I HAPPYSTEP YR NUM |
|||
I HAS A NEXT ITZ 0 |
|||
IM IN YR LOOP |
|||
BOTH SAEM NUM AN 0 |
|||
O RLY? |
|||
YA RLY |
|||
GTFO |
|||
OIC |
|||
I HAS A DIGIT ITZ MOD OF NUM AN 10 |
|||
NUM R QUOSHUNT OF NUM AN 10 |
|||
I HAS A SQUARE ITZ PRODUKT OF DIGIT AN DIGIT |
|||
NEXT R SUM OF NEXT AN SQUARE |
|||
IM OUTTA YR LOOP |
|||
FOUND YR NEXT |
|||
IF U SAY SO |
|||
BTW Check to see if a number is happy |
|||
HOW IZ I IZHAPPY YR NUM |
|||
I HAS A SEENIT ITZ I IZ MAEKLIST MKAY |
|||
IM IN YR LOOP |
|||
BOTH SAEM NUM AN 1 |
|||
O RLY? |
|||
YA RLY |
|||
FOUND YR WIN |
|||
OIC |
|||
I IZ DUZLISTHAS YR SEENIT AN YR NUM MKAY |
|||
O RLY? |
|||
YA RLY |
|||
FOUND YR FAIL |
|||
OIC |
|||
I IZ PUTIN YR SEENIT AN YR NUM MKAY |
|||
NUM R I IZ HAPPYSTEP YR NUM MKAY |
|||
IM OUTTA YR LOOP |
|||
IF U SAY SO |
|||
BTW Print out the first 8 happy numbers |
|||
I HAS A KOUNT ITZ 0 |
|||
IM IN YR LOOP UPPIN YR NUM WILE DIFFRINT KOUNT AN 8 |
|||
I IZ IZHAPPY YR NUM MKAY |
|||
O RLY? |
|||
YA RLY |
|||
KOUNT R SUM OF KOUNT AN 1 |
|||
VISIBLE NUM |
|||
OIC |
|||
IM OUTTA YR LOOP |
|||
KTHXBYE</syntaxhighlight> |
|||
Output:<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Lua}}== |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|M2000 Interpreter}}== |
|||
{{trans|ActionScript}} |
|||
Lambda Function PrintHappy has a closure another lambda function IsHappy which has a closure of another lambda function the sumOfSquares. |
|||
<syntaxhighlight lang="m2000 interpreter"> |
|||
Function FactoryHappy { |
|||
sumOfSquares= lambda (n) ->{ |
|||
k$=str$(abs(n),"") |
|||
Sum=0 |
|||
For i=1 to len(k$) |
|||
sum+=val(mid$(k$,i,1))**2 |
|||
Next i |
|||
=sum |
|||
} |
|||
IsHappy=Lambda sumOfSquares (n) ->{ |
|||
Inventory sequence |
|||
While n<>1 { |
|||
Append sequence, n |
|||
n=sumOfSquares(n) |
|||
if exist(sequence, n) then =false : Break |
|||
} |
|||
=True |
|||
} |
|||
=Lambda IsHappy ->{ |
|||
numleft=8 |
|||
numToTest=1 |
|||
While numleft { |
|||
if ishappy(numToTest) Then { |
|||
Print numToTest |
|||
numleft-- |
|||
} |
|||
numToTest++ |
|||
} |
|||
} |
|||
} |
|||
PrintHappy=factoryHappy() |
|||
Call PrintHappy() |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|MACRO-11}}== |
|||
<syntaxhighlight lang="macro11"> .TITLE HAPPY |
|||
.MCALL .TTYOUT,.EXIT |
|||
HAPPY:: MOV #^D8,R5 ; 8 HAPPY NUMBERS |
|||
CLR R4 |
|||
1$: INC R4 |
|||
MOV R4,R0 |
|||
JSR PC,CHECK |
|||
BNE 1$ |
|||
MOV R4,R0 |
|||
JSR PC,PR0 |
|||
SOB R5,1$ |
|||
.EXIT |
|||
; CHECK IF R0 IS HAPPY: ZERO FLAG SET IF TRUE |
|||
CHECK: MOV #200,R1 |
|||
MOV #3$,R2 |
|||
1$: CLR (R2)+ |
|||
SOB R1,1$ |
|||
2$: INCB 3$(R0) |
|||
JSR PC,SUMSQ |
|||
TST 3$(R0) |
|||
BEQ 2$ |
|||
DEC R0 |
|||
RTS PC |
|||
3$: .BLKW 200 |
|||
; LET R0 = SUM OF SQUARES OF DIGITS OF R0 |
|||
SUMSQ: CLR R2 |
|||
1$: MOV #-1,R1 |
|||
2$: INC R1 |
|||
SUB #12,R0 |
|||
BCC 2$ |
|||
ADD #12,R0 |
|||
MOVB 3$(R0),R0 |
|||
ADD R0,R2 |
|||
MOV R1,R0 |
|||
BNE 1$ |
|||
MOV R2,R0 |
|||
RTS PC |
|||
3$: .BYTE ^D 0,^D 1,^D 4,^D 9,^D16 |
|||
.BYTE ^D25,^D36,^D49,^D64,^D81 |
|||
; PRINT NUMBER IN R0 AS DECIMAL. |
|||
PR0: MOV #4$,R1 |
|||
1$: MOV #-1,R2 |
|||
2$: INC R2 |
|||
SUB #12,R0 |
|||
BCC 2$ |
|||
ADD #72,R0 |
|||
MOVB R0,-(R1) |
|||
MOV R2,R0 |
|||
BNE 1$ |
|||
3$: MOVB (R1)+,R0 |
|||
.TTYOUT |
|||
BNE 3$ |
|||
RTS PC |
|||
.ASCII /...../ |
|||
4$: .BYTE 15,12,0 |
|||
.END HAPPY</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|MAD}}== |
|||
<syntaxhighlight lang="mad"> NORMAL MODE IS INTEGER |
|||
BOOLEAN CYCLE |
|||
DIMENSION CYCLE(200) |
|||
VECTOR VALUES OUTFMT = $I2*$ |
|||
SEEN = 0 |
|||
I = 0 |
|||
NEXNUM THROUGH ZERO, FOR K=0, 1, K.G.200 |
|||
ZERO CYCLE(K) = 0B |
|||
I = I + 1 |
|||
SUMSQR = I |
|||
CHKLP N = SUMSQR |
|||
SUMSQR = 0 |
|||
SUMLP DIG = N-N/10*10 |
|||
SUMSQR = SUMSQR + DIG*DIG |
|||
N = N/10 |
|||
WHENEVER N.NE.0, TRANSFER TO SUMLP |
|||
WHENEVER SUMSQR.E.1, TRANSFER TO HAPPY |
|||
WHENEVER CYCLE(SUMSQR), TRANSFER TO NEXNUM |
|||
CYCLE(SUMSQR) = 1B |
|||
TRANSFER TO CHKLP |
|||
HAPPY PRINT FORMAT OUTFMT,I |
|||
SEEN = SEEN+1 |
|||
WHENEVER SEEN.L.8, TRANSFER TO NEXNUM |
|||
END OF PROGRAM |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Maple}}== |
|||
To begin, here is a procedure to compute the sum of the squares of the digits of a positive integer. It uses the built-in procedure irem, which computes the integer remainder and, if passed a name as the optional third argument, assigns it the corresponding quotient. (In other words, it performs integer division with remainder. There is also a dual, companion procedure iquo, which returns the integer quotient and assigns the remainder to the (optional) third argument.) |
|||
<syntaxhighlight lang="maple">SumSqDigits := proc( n :: posint ) |
|||
local s := 0; |
|||
local m := n; |
|||
while m <> 0 do |
|||
s := s + irem( m, 10, 'm' )^2 |
|||
end do; |
|||
s |
|||
end proc:</syntaxhighlight> |
|||
(Note that the unevaluation quotes on the third argument to irem are essential here, as that argument must be a name and, if m were passed without quotes, it would evaluate to a number.) |
|||
For example, |
|||
<syntaxhighlight lang="maple"> |
|||
> SumSqDigits( 1234567890987654321 ); |
|||
570 |
|||
</syntaxhighlight> |
|||
We can check this by computing it another way (more directly). |
|||
<syntaxhighlight lang="maple"> |
|||
> n := 1234567890987654321: |
|||
> `+`( op( map( parse, StringTools:-Explode( convert( n, 'string' ) ) )^~2) ); |
|||
570 |
|||
</syntaxhighlight> |
|||
The most straight-forward way to check whether a number is happy or sad seems also to be the fastest (that I could think of). |
|||
<syntaxhighlight lang="maple">Happy? := proc( n ) |
|||
if n = 1 then |
|||
true |
|||
elif n = 4 then |
|||
false |
|||
else |
|||
local s := SumSqDigits( n ); |
|||
while not ( s in { 1, 4 } ) do |
|||
s := SumSqDigits( s ) |
|||
end do; |
|||
evalb( s = 1 ) |
|||
end if |
|||
end proc:</syntaxhighlight> |
|||
We can use this to determine the number of happy (H) and sad (S) numbers up to one million as follows. |
|||
<syntaxhighlight lang="maple"> |
|||
> H, S := selectremove( Happy?, [seq]( 1 .. N ) ): |
|||
> nops( H ), nops( S ); |
|||
143071, 856929 |
|||
</syntaxhighlight> |
|||
Finally, to solve the stated problem, here is a completely straight-forward routine to locate the first N happy numbers, returning them in a set. |
|||
<syntaxhighlight lang="maple">FindHappiness := proc( N ) |
|||
local count := 0; |
|||
local T := table(); |
|||
for local i while count < N do |
|||
if Happy?( i ) then |
|||
count := 1 + count; |
|||
T[ count ] := i |
|||
end if |
|||
end do; |
|||
{seq}( T[ i ], i = 1 .. count ) |
|||
end proc:</syntaxhighlight> |
|||
With input equal to 8, we get |
|||
<syntaxhighlight lang="maple"> |
|||
> FindHappiness( 8 ); |
|||
{1, 7, 10, 13, 19, 23, 28, 31} |
|||
</syntaxhighlight> |
|||
For completeness, here is an implementation of the cycle detection algorithm for recognizing happy numbers. It is much slower, however. |
|||
<syntaxhighlight lang="maple">Happy? := proc( n :: posint ) |
|||
local a, b; |
|||
a, b := n, SumSqDigits( n ); |
|||
while a <> b do |
|||
a := SumSqDigits( a ); |
|||
b := (SumSqDigits@@2)( b ) |
|||
end do; |
|||
evalb( a = 1 ) |
|||
end proc:</syntaxhighlight> |
|||
=={{header|Mathematica}}== |
=={{header|Mathematica}} / {{header|Wolfram Language}}== |
||
Custom function HappyQ: |
Custom function HappyQ: |
||
<syntaxhighlight lang="mathematica">AddSumSquare[input_]:=Append[input,Total[IntegerDigits[Last[input]]^2]] |
|||
<lang Mathematica> |
|||
NestUntilRepeat[a_,f_]:=NestWhile[f,{a},!MemberQ[Most[Last[{##}]],Last[Last[{##}]]]&,All] |
|||
AddSumSquare[input_]:=Append[input,Total[IntegerDigits[Last[input]]^2]] |
|||
HappyQ[a_]:=Last[NestUntilRepeat[a,AddSumSquare]]==1</syntaxhighlight> |
|||
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: |
Examples for a specific number: |
||
<syntaxhighlight lang="mathematica">HappyQ[1337] |
|||
<lang Mathematica> |
|||
HappyQ[137]</syntaxhighlight> |
|||
HappyQ[137] |
|||
</lang> |
|||
gives back: |
gives back: |
||
<syntaxhighlight lang="mathematica">True |
|||
<lang Mathematica> |
|||
False</syntaxhighlight> |
|||
True |
|||
False |
|||
</lang> |
|||
Example finding the first 8: |
Example finding the first 8: |
||
<syntaxhighlight lang="mathematica">m = 8; |
|||
<lang Mathematica> |
|||
m = 8; |
|||
n = 1; |
n = 1; |
||
i = 0; |
i = 0; |
||
Line 501: | Line 4,617: | ||
] |
] |
||
] |
] |
||
happynumbers |
happynumbers</syntaxhighlight> |
||
</lang> |
|||
gives back: |
gives back: |
||
<syntaxhighlight lang="mathematica">{1, 7, 10, 13, 19, 23, 28, 31}</syntaxhighlight> |
|||
<lang Mathematica> |
|||
{1, 7, 10, 13, 19, 23, 28, 31} |
|||
=={{header|MATLAB}}== |
|||
</lang> |
|||
Recursive version: |
|||
<syntaxhighlight lang="matlab">function findHappyNumbers |
|||
nHappy = 0; |
|||
k = 1; |
|||
while nHappy < 8 |
|||
if isHappyNumber(k, []) |
|||
fprintf('%d ', k) |
|||
nHappy = nHappy+1; |
|||
end |
|||
k = k+1; |
|||
end |
|||
fprintf('\n') |
|||
end |
|||
function hap = isHappyNumber(k, prev) |
|||
if k == 1 |
|||
hap = true; |
|||
elseif ismember(k, prev) |
|||
hap = false; |
|||
else |
|||
hap = isHappyNumber(sum((sprintf('%d', k)-'0').^2), [prev k]); |
|||
end |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 7 10 13 19 23 28 31 </pre> |
|||
=={{header|Maxima}}== |
|||
<syntaxhighlight lang="maxima"> |
|||
/* Function that decomposes te number into a list */ |
|||
decompose(N) := block( |
|||
digits: [], |
|||
while N > 0 do |
|||
(remainder: mod(N, 10), |
|||
digits: cons(remainder, digits), |
|||
N: floor(N/10)), |
|||
digits |
|||
)$ |
|||
/* Function that given a number returns the sum of their digits */ |
|||
sum_squares_digits(n):=block( |
|||
decompose(n), |
|||
map(lambda([x],x^2),%%), |
|||
apply("+",%%))$ |
|||
/* Predicate function based on the task iterated digits squaring */ |
|||
happyp(n):=if n=1 then true else if n=89 then false else block(iter:n,while not member(iter,[1,89]) do iter:sum_squares_digits(iter),iter,if iter=1 then true)$ |
|||
/* Test case */ |
|||
/* First eight happy numbers */ |
|||
block( |
|||
happy:[],i:1, |
|||
while length(happy)<8 do (if happyp(i) then happy:endcons(i,happy),i:i+1), |
|||
happy); |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[1,7,10,13,19,23,28,31] |
|||
</pre> |
|||
=={{header|MAXScript}}== |
|||
<syntaxhighlight lang="maxscript"> |
|||
fn isHappyNumber n = |
|||
( |
|||
local pastNumbers = #() |
|||
while n != 1 do |
|||
( |
|||
n = n as string |
|||
local newNumber = 0 |
|||
for i = 1 to n.count do |
|||
( |
|||
local digit = n[i] as integer |
|||
newNumber += pow digit 2 |
|||
) |
|||
n = newNumber |
|||
if (finditem pastNumbers n) != 0 do return false |
|||
append pastNumbers newNumber |
|||
) |
|||
n == 1 |
|||
) |
|||
printed = 0 |
|||
for i in (for h in 1 to 500 where isHappyNumber h collect h) do |
|||
( |
|||
if printed == 8 do exit |
|||
print i as string |
|||
printed += 1 |
|||
) |
|||
</syntaxhighlight> |
|||
Output: |
|||
<syntaxhighlight lang="maxscript"> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</syntaxhighlight> |
|||
=={{header|Mercury}}== |
|||
<syntaxhighlight lang="mercury">:- module happy. |
|||
:- interface. |
|||
:- import_module io. |
|||
:- pred main(io::di, io::uo) is det. |
|||
:- implementation. |
|||
:- import_module int, list, set_tree234. |
|||
main(!IO) :- |
|||
print_line(get_n_happy_numbers(8, 1), !IO). |
|||
:- func get_n_happy_numbers(int, int) = list(int). |
|||
get_n_happy_numbers(NumToFind, N) = |
|||
( if NumToFind > 0 then |
|||
( if is_happy(N, init) |
|||
then [N | get_n_happy_numbers(NumToFind - 1, N + 1)] |
|||
else get_n_happy_numbers(NumToFind, N + 1) |
|||
) |
|||
else |
|||
[] |
|||
). |
|||
:- pred is_happy(int::in, set_tree234(int)::in) is semidet. |
|||
is_happy(1, _). |
|||
is_happy(N, !.Seen) :- |
|||
not member(N, !.Seen), |
|||
insert(N, !Seen), |
|||
is_happy(sum_sqr_digits(N), !.Seen). |
|||
:- func sum_sqr_digits(int) = int. |
|||
sum_sqr_digits(N) = |
|||
( if N < 10 then sqr(N) else sqr(N mod 10) + sum_sqr_digits(N div 10) ). |
|||
:- func sqr(int) = int. |
|||
sqr(X) = X * X.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>[1, 7, 10, 13, 19, 23, 28, 31]</pre> |
|||
=={{header|MiniScript}}== |
|||
This solution uses the observation that any infinite cycle of this algorithm hits the number 89, and so that can be used to know when we've found an unhappy number. |
|||
<syntaxhighlight lang="miniscript">isHappy = function(x) |
|||
while true |
|||
if x == 89 then return false |
|||
sum = 0 |
|||
while x > 0 |
|||
sum = sum + (x % 10)^2 |
|||
x = floor(x / 10) |
|||
end while |
|||
if sum == 1 then return true |
|||
x = sum |
|||
end while |
|||
end function |
|||
found = [] |
|||
i = 1 |
|||
while found.len < 8 |
|||
if isHappy(i) then found.push i |
|||
i = i + 1 |
|||
end while |
|||
print "First 8 happy numbers: " + found</syntaxhighlight> |
|||
{{out}} |
|||
<pre>First 8 happy numbers: [1, 7, 10, 13, 19, 23, 28, 31]</pre> |
|||
=={{header|Miranda}}== |
|||
<syntaxhighlight lang="miranda">main :: [sys_message] |
|||
main = [Stdout (lay (map show (take 8 happynumbers)))] |
|||
happynumbers :: [num] |
|||
happynumbers = filter ishappy [1..] |
|||
ishappy :: num->bool |
|||
ishappy n = 1 $in loop (iterate sumdigitsquares n) |
|||
sumdigitsquares :: num->num |
|||
sumdigitsquares 0 = 0 |
|||
sumdigitsquares n = (n mod 10)^2 + sumdigitsquares (n div 10) |
|||
loop :: [*]->[*] |
|||
loop = loop' [] |
|||
where loop' mem (a:as) = mem, if a $in mem |
|||
= loop' (a:mem) as, otherwise |
|||
in :: *->[*]->bool |
|||
in val [] = False |
|||
in val (a:as) = True, if a=val |
|||
= val $in as, otherwise</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|ML}}== |
|||
==={{header|mLite}}=== |
|||
<syntaxhighlight lang="ocaml">(* |
|||
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. Display an example of your |
|||
output here. |
|||
*) |
|||
local |
|||
fun get_digits |
|||
(d, s) where (d = 0) = s |
|||
| (d, s) = get_digits( d div 10, (d mod 10) :: s) |
|||
| n = get_digits( n div 10, [n mod 10] ) |
|||
; |
|||
fun mem |
|||
(x, []) = false |
|||
| (x, a :: as) where (x = a) = true |
|||
| (x, _ :: as) = mem (x, as) |
|||
in |
|||
fun happy |
|||
1 = "happy" |
|||
| n = |
|||
let |
|||
val this = (fold (+,0) ` map (fn n = n ^ 2) ` get_digits n); |
|||
val sads = [2, 4, 16, 37, 58, 89, 145, 42, 20] |
|||
in |
|||
if (mem (n,sads)) then |
|||
"unhappy" |
|||
else |
|||
happy this |
|||
end |
|||
end |
|||
; |
|||
foreach (fn n = (print n; print " is "; println ` happy n)) ` iota 10; |
|||
</syntaxhighlight> |
|||
Output: |
|||
<pre>1 is happy |
|||
2 is unhappy |
|||
3 is unhappy |
|||
4 is unhappy |
|||
5 is unhappy |
|||
6 is unhappy |
|||
7 is happy |
|||
8 is unhappy |
|||
9 is unhappy |
|||
10 is happy</pre> |
|||
=={{header|Modula-2}}== |
|||
<syntaxhighlight lang="modula2">MODULE HappyNumbers; |
|||
FROM InOut IMPORT WriteCard, WriteLn; |
|||
CONST Amount = 8; |
|||
VAR seen, num: CARDINAL; |
|||
PROCEDURE SumDigitSquares(n: CARDINAL): CARDINAL; |
|||
VAR sum, digit: CARDINAL; |
|||
BEGIN |
|||
sum := 0; |
|||
WHILE n>0 DO |
|||
digit := n MOD 10; |
|||
n := n DIV 10; |
|||
sum := sum + digit * digit; |
|||
END; |
|||
RETURN sum; |
|||
END SumDigitSquares; |
|||
PROCEDURE Happy(n: CARDINAL): BOOLEAN; |
|||
VAR i: CARDINAL; |
|||
seen: ARRAY [0..255] OF BOOLEAN; |
|||
BEGIN |
|||
FOR i := 0 TO 255 DO |
|||
seen[i] := FALSE; |
|||
END; |
|||
REPEAT |
|||
seen[n] := TRUE; |
|||
n := SumDigitSquares(n); |
|||
UNTIL seen[n]; |
|||
RETURN seen[1]; |
|||
END Happy; |
|||
BEGIN |
|||
seen := 0; |
|||
num := 0; |
|||
WHILE seen < Amount DO |
|||
IF Happy(num) THEN |
|||
INC(seen); |
|||
WriteCard(num,2); |
|||
WriteLn(); |
|||
END; |
|||
INC(num); |
|||
END; |
|||
END HappyNumbers.</syntaxhighlight> |
|||
{{out}} |
|||
<pre> 1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|MUMPS}}== |
|||
<syntaxhighlight 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</syntaxhighlight> |
|||
Output:<pre> |
|||
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> |
|||
</pre> |
|||
=={{header|NetRexx}}== |
|||
{{trans|REXX}} |
|||
<syntaxhighlight lang="netrexx">/*NetRexx program to display the 1st 8 (or specified arg) happy numbers*/ |
|||
limit = arg[0] /*get argument for LIMIT. */ |
|||
say limit |
|||
if limit = null, limit ='' then limit=8 /*if not specified, set LIMIT to 8*/ |
|||
haps = 0 /*count of happy numbers so far. */ |
|||
loop n=1 while haps < limit /*search integers starting at one.*/ |
|||
q=n /*Q may or may not be "happy". */ |
|||
a=0 |
|||
loop 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. */ |
|||
loop j=1 for q.length /*add the squares of the numerals.*/ |
|||
sum = sum + q.substr(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</syntaxhighlight> |
|||
;Output |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
Sample output when 100 is specified as the program's argument. |
|||
<pre style="height:30ex;overflow:scroll"> |
|||
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 |
|||
</pre> |
|||
=={{header|Nim}}== |
|||
{{trans|Python}} |
|||
<syntaxhighlight lang="nim">import intsets |
|||
proc happy(n: int): bool = |
|||
var |
|||
n = n |
|||
past = initIntSet() |
|||
while n != 1: |
|||
let s = $n |
|||
n = 0 |
|||
for c in s: |
|||
let i = ord(c) - ord('0') |
|||
n += i * i |
|||
if n in past: |
|||
return false |
|||
past.incl(n) |
|||
return true |
|||
for x in 0..31: |
|||
if happy(x): |
|||
echo x</syntaxhighlight> |
|||
Output: |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Objeck}}== |
|||
<syntaxhighlight 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->Print("First 8 happy numbers: "); |
|||
each(i : happynums) { |
|||
Console->Print(happynums->Get(i))->Print(","); |
|||
}; |
|||
Console->PrintLine(""); |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
output: |
|||
<pre>First 8 happy numbers: 1,7,10,13,19,23,28,31,</pre> |
|||
=={{header|OCaml}}== |
|||
Using [[wp:Cycle detection|Floyd's cycle-finding algorithm]]. |
|||
<syntaxhighlight lang="ocaml">open Num |
|||
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.iter print_endline ( |
|||
List.rev_map string_of_num (first 8)) ;;</syntaxhighlight> |
|||
Output: |
|||
<pre>$ ocaml nums.cma happy_numbers.ml |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Oforth}}== |
|||
<syntaxhighlight lang="oforth">: isHappy(n) |
|||
| cycle | |
|||
ListBuffer new ->cycle |
|||
while(n 1 <>) [ |
|||
cycle include(n) ifTrue: [ false return ] |
|||
cycle add(n) |
|||
0 n asString apply(#[ asDigit sq + ]) ->n |
|||
] |
|||
true ; |
|||
: happyNum(N) |
|||
| numbers | |
|||
ListBuffer new ->numbers |
|||
1 while(numbers size N <>) [ dup isHappy ifTrue: [ dup numbers add ] 1+ ] |
|||
numbers println ;</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
>happyNum(8) |
|||
[1, 7, 10, 13, 19, 23, 28, 31] |
|||
</pre> |
|||
=={{header|Ol}}== |
|||
<syntaxhighlight lang="Scheme"> |
|||
(define (number->list num) |
|||
(let loop ((num num) (lst #null)) |
|||
(if (zero? num) |
|||
lst |
|||
(loop (quotient num 10) (cons (remainder num 10) lst))))) |
|||
(define (** x) (* x x)) |
|||
(define (happy? num) |
|||
(let loop ((num num) (seen #null)) |
|||
(cond |
|||
((= num 1) #true) |
|||
((memv num seen) #false) |
|||
(else |
|||
(loop (apply + (map ** (number->list num))) |
|||
(cons num seen)))))) |
|||
(display "happy numbers: ") |
|||
(let loop ((n 1) (count 0)) |
|||
(unless (= count 8) |
|||
(if (happy? n) |
|||
then |
|||
(display n) (display " ") |
|||
(loop (+ n 1) (+ count 1)) |
|||
else |
|||
(loop (+ n 1) count)))) |
|||
(print) |
|||
</syntaxhighlight> |
|||
<pre> |
|||
happy numbers: 1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|ooRexx}}== |
|||
<syntaxhighlight lang="oorexx"> |
|||
count = 0 |
|||
say "First 8 happy numbers are:" |
|||
loop i = 1 while count < 8 |
|||
if happyNumber(i) then do |
|||
count += 1 |
|||
say i |
|||
end |
|||
end |
|||
::routine happyNumber |
|||
use strict arg number |
|||
-- use to trace previous cycle results |
|||
previous = .set~new |
|||
loop forever |
|||
-- stop when we hit the target |
|||
if number = 1 then return .true |
|||
-- stop as soon as we start cycling |
|||
if previous[number] \== .nil then return .false |
|||
previous~put(number) |
|||
next = 0 |
|||
-- loop over all of the digits |
|||
loop digit over number~makearray('') |
|||
next += digit * digit |
|||
end |
|||
-- and repeat the cycle |
|||
number = next |
|||
end |
|||
</syntaxhighlight> |
|||
<pre> |
|||
First 8 happy numbers are: |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
=={{header|Oz}}== |
|||
<syntaxhighlight lang="oz">functor |
|||
import |
|||
System |
|||
define |
|||
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 |
|||
{System.show {List.take HappyNumbers 8}} |
|||
end</syntaxhighlight> |
|||
Output: |
|||
<pre>[1 7 10 13 19 23 28 31]</pre> |
|||
=={{header|PARI/GP}}== |
|||
{{PARI/GP select}} |
|||
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. |
|||
<syntaxhighlight 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))</syntaxhighlight> |
|||
Output: |
|||
<pre>%1 = [1, 7, 10, 13, 19, 23, 28, 31]</pre> |
|||
=={{header|Pascal}}== |
|||
<syntaxhighlight lang="pascal">Program HappyNumbers (output); |
|||
uses |
|||
Math; |
|||
function find(n: integer; cache: array of integer): boolean; |
|||
var |
|||
i: integer; |
|||
begin |
|||
find := false; |
|||
for i := low(cache) to high(cache) do |
|||
if cache[i] = n then |
|||
find := true; |
|||
end; |
|||
function is_happy(n: integer): boolean; |
|||
var |
|||
cache: array of integer; |
|||
sum: integer; |
|||
begin |
|||
setlength(cache, 1); |
|||
repeat |
|||
sum := 0; |
|||
while n > 0 do |
|||
begin |
|||
sum := sum + (n mod 10)**2; |
|||
n := n div 10; |
|||
end; |
|||
if sum = 1 then |
|||
begin |
|||
is_happy := true; |
|||
break; |
|||
end; |
|||
if find(sum, cache) then |
|||
begin |
|||
is_happy := false; |
|||
break; |
|||
end; |
|||
n := sum; |
|||
cache[high(cache)]:= sum; |
|||
setlength(cache, length(cache)+1); |
|||
until false; |
|||
end; |
|||
var |
|||
n, count: integer; |
|||
begin |
|||
n := 1; |
|||
count := 0; |
|||
while count < 8 do |
|||
begin |
|||
if is_happy(n) then |
|||
begin |
|||
inc(count); |
|||
write(n, ' '); |
|||
end; |
|||
inc(n); |
|||
end; |
|||
writeln; |
|||
end.</syntaxhighlight> |
|||
Output: |
|||
<pre>:> ./HappyNumbers |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
===alternative for counting fast=== |
|||
{{works with|Free Pascal}} |
|||
The Cache is limited to maximum value of the sum of squared digits and filled up in a blink of an eye.Even for cDigit2=1e9 takes 0.7s.Calculation of sum of squared digits is improved.Saving this SqrdSumCache speeds up tremendous. |
|||
So i am able to check if the 1'000'000 th happy number is 7105849 as stated in C language.This seems to be true. |
|||
Extended to 10e18 |
|||
Tested with Free Pascal 3.0.4 |
|||
<syntaxhighlight lang="pascal">Program HappyNumbers (output); |
|||
{$IFDEF FPC} |
|||
{$MODE DELPHI} |
|||
{$OPTIMIZATION ON,All} |
|||
{$ELSE} |
|||
{$APPLICATION CONSOLE} |
|||
{$ENDIF} |
|||
//{$DEFINE Use1E9} |
|||
uses |
|||
sysutils,//Timing |
|||
strutils;//Numb2USA |
|||
const |
|||
base = 10; |
|||
HighCache = 20*(sqr(base-1));//sum of sqr digit of Uint64 |
|||
{$IFDEF Use1E9} |
|||
cDigit1 = sqr(base)*sqr(base);//must be power of base |
|||
cDigit2 = Base*sqr(cDigit1);// 1e9 |
|||
cMaxPot = 18; |
|||
{$ELSE} |
|||
cDigit1 = base*sqr(base);//must be power of base |
|||
cDigit2 = sqr(cDigit1);// 1e6 |
|||
cMaxPot = 14; |
|||
{$ENDIF} |
|||
type |
|||
tSumSqrDgts = array[0..cDigit2] of word; |
|||
tCache = array[0..2*HighCache] of word; |
|||
tSqrdSumCache = array[0..2*HighCache] of Uint32; |
|||
var |
|||
SumSqrDgts :tSumSqrDgts; |
|||
Cache : tCache; |
|||
SqrdSumCache1, |
|||
SqrdSumCache2 :tSqrdSumCache; |
|||
T1,T0 : TDateTime; |
|||
MAX2,Max1 : NativeInt; |
|||
procedure InitSumSqrDgts; |
|||
//calc all sum of squared digits 0..cDigits2 |
|||
//using already calculated values |
|||
var |
|||
i,j,n,sq,Base1: NativeInt; |
|||
begin |
|||
For i := 0 to Base-1 do |
|||
SumSqrDgts[i] := i*i; |
|||
Base1 := Base; |
|||
n := Base; |
|||
repeat |
|||
For i := 1 to base-1 do |
|||
Begin |
|||
sq := SumSqrDgts[i]; |
|||
For j := 0 to base1-1 do |
|||
Begin |
|||
SumSqrDgts[n] := sq+SumSqrDgts[j]; |
|||
inc(n); |
|||
end; |
|||
end; |
|||
Base1 := Base1*base; |
|||
until Base1 >= cDigit2; |
|||
SumSqrDgts[n] := 1; |
|||
end; |
|||
function SumSqrdDgt(n: Uint64):NativeUint;inline; |
|||
var |
|||
r: Uint64; |
|||
begin |
|||
result := 0; |
|||
while n>cDigit2 do |
|||
Begin |
|||
r := n; |
|||
n := n div cDigit2; |
|||
r := r-n*cDigit2; |
|||
inc(result,SumSqrDgts[r]); |
|||
end; |
|||
inc(result,SumSqrDgts[n]); |
|||
end; |
|||
procedure CalcSqrdSumCache1; |
|||
var |
|||
Count : tSqrdSumCache; |
|||
i,sq,result : NativeInt; |
|||
begin |
|||
For i :=High(Count) downto 0 do |
|||
Count[i] := 0; |
|||
//count the manifold |
|||
For i := cDigit1-1 downto 0 do |
|||
inc(count[SumSqrDgts[i]]); |
|||
For i := High(Count) downto 0 do |
|||
if count[i] <> 0 then |
|||
Begin |
|||
Max1 := i; |
|||
BREAK; |
|||
end; |
|||
For sq := 0 to (20-3)*81 do |
|||
Begin |
|||
result := 0; |
|||
For i := Max1 downto 0 do |
|||
inc(result,Count[i]*Cache[sq+i]); |
|||
SqrdSumCache1[sq] := result; |
|||
end; |
|||
end; |
|||
procedure CalcSqrdSumCache2; |
|||
var |
|||
Count : tSqrdSumCache; |
|||
i,sq,result : NativeInt; |
|||
begin |
|||
For i :=High(Count) downto 0 do |
|||
Count[i] := 0; |
|||
For i := cDigit2-1 downto 0 do |
|||
inc(count[SumSqrDgts[i]]); |
|||
For i := High(Count) downto 0 do |
|||
if count[i] <> 0 then |
|||
Begin |
|||
Max2 := i; |
|||
BREAK; |
|||
end; |
|||
For sq := 0 to (20-6)*81 do |
|||
Begin |
|||
result := 0; |
|||
For i := Max2 downto 0 do |
|||
inc(result,Count[i]*Cache[sq+i]); |
|||
SqrdSumCache2[sq] := result; |
|||
end; |
|||
end; |
|||
procedure Inithappy; |
|||
var |
|||
n,s,p : NativeUint; |
|||
Begin |
|||
fillchar(SqrdSumCache1,SizeOf(SqrdSumCache1),#0); |
|||
fillchar(SqrdSumCache2,SizeOf(SqrdSumCache2),#0); |
|||
InitSumSqrDgts; |
|||
fillChar(Cache,SizeOf(Cache),#0); |
|||
Cache[1] := 1; |
|||
For n := 1 to High(Cache) do |
|||
Begin |
|||
If Cache[n] = 0 then |
|||
Begin |
|||
//start a linked list |
|||
Cache[n] := n; |
|||
p := n; |
|||
s := SumSqrdDgt(p); |
|||
while Cache[s] = 0 do |
|||
Begin |
|||
Cache[s] := p; |
|||
p := s; |
|||
s := SumSqrdDgt(p); |
|||
end; |
|||
//mark linked list backwards as happy number |
|||
IF Cache[s] = 1 then |
|||
Begin |
|||
repeat |
|||
s := Cache[p]; |
|||
Cache[p] := 1; |
|||
p := s; |
|||
until s = n; |
|||
Cache[n] := 1; |
|||
end; |
|||
end; |
|||
end; |
|||
//mark all unhappy numbers with 0 |
|||
For n := 1 to High(Cache) do |
|||
If Cache[n] <> 1 then |
|||
Cache[n] := 0; |
|||
CalcSqrdSumCache1; |
|||
CalcSqrdSumCache2; |
|||
end; |
|||
function is_happy(n: NativeUint): boolean;inline; |
|||
begin |
|||
is_happy := Boolean(Cache[SumSqrdDgt(n)]) |
|||
end; |
|||
function nthHappy(Limit: Uint64):Uint64; |
|||
var |
|||
d,e,sE: NativeUint; |
|||
begin |
|||
result := 0; |
|||
d := 0; |
|||
e := 0; |
|||
sE := SumSqrDgts[e]; |
|||
//big steps |
|||
while Limit >= cDigit2 do |
|||
begin |
|||
dec(Limit,SqrdSumCache2[SumSqrDgts[d]+sE]); |
|||
inc(result,cDigit2); |
|||
inc(d); |
|||
IF d >=cDigit2 then |
|||
Begin |
|||
inc(e); |
|||
sE := SumSqrdDgt(e);//SumSqrDgts[e]; |
|||
d :=0; |
|||
end; |
|||
end; |
|||
//small steps |
|||
while Limit >= cDigit1 do |
|||
Begin |
|||
dec(Limit,SqrdSumCache1[SumSqrdDgt(result)]); |
|||
inc(result,cDigit1); |
|||
end; |
|||
//ONE BY ONE |
|||
while Limit > 0 do |
|||
begin |
|||
dec(Limit,Cache[SumSqrdDgt(result)]); |
|||
inc(result); |
|||
end; |
|||
result -= 1; |
|||
end; |
|||
var |
|||
n, count :Uint64; |
|||
Limit: NativeUint; |
|||
begin |
|||
write('cDigit1 = ',Numb2USA(IntToStr(cDigit1))); |
|||
writeln(' cDigit2 = ',Numb2USA(IntToStr(cDigit2))); |
|||
T0 := now; |
|||
Inithappy; |
|||
writeln('Init takes ',FormatDateTime(' HH:NN:SS.ZZZ',now-T0)); |
|||
n := 1; |
|||
count := 0; |
|||
while count < 10 do |
|||
begin |
|||
if is_happy(n) then |
|||
begin |
|||
inc(count); |
|||
write(n, ' '); |
|||
end; |
|||
inc(n); |
|||
end; |
|||
writeln; |
|||
T0 := now; |
|||
T1 := T0; |
|||
n := 1; |
|||
Limit := 10; |
|||
repeat |
|||
writeln('1E',n:2,' n.th happy number ',Numb2USA(IntToStr(nthHappy(Limit))):26, |
|||
FormatDateTime(' HH:NN:SS.ZZZ',now-T1)); |
|||
T1 := now; |
|||
inc(n); |
|||
Limit := limit*10; |
|||
until n> cMaxPot; |
|||
writeln('Total time counting ',FormatDateTime('HH:NN:SS.ZZZ',now-T0)); |
|||
end. |
|||
</syntaxhighlight> |
|||
;output: |
|||
<pre> |
|||
cDigit1 = 1,000 cDigit2 = 1,000,000 |
|||
Init takes 00:00:00.004 |
|||
1 7 10 13 19 23 28 31 32 44 |
|||
1E 1 n.th happy number 44 00:00:00.000 |
|||
1E 2 n.th happy number 694 00:00:00.000 |
|||
1E 3 n.th happy number 6,899 00:00:00.000 |
|||
1E 4 n.th happy number 67,169 00:00:00.000 |
|||
1E 5 n.th happy number 692,961 00:00:00.000 |
|||
1E 6 n.th happy number 7,105,849 00:00:00.000 |
|||
1E 7 n.th happy number 71,313,350 00:00:00.000 |
|||
1E 8 n.th happy number 698,739,425 00:00:00.000 |
|||
1E 9 n.th happy number 6,788,052,776 00:00:00.000 |
|||
1E10 n.th happy number 66,305,148,869 00:00:00.000 |
|||
1E11 n.th happy number 660,861,957,662 00:00:00.001 |
|||
1E12 n.th happy number 6,745,877,698,967 00:00:00.008 |
|||
1E13 n.th happy number 70,538,879,028,725 00:00:00.059 |
|||
1E14 n.th happy number 744,083,563,164,178 00:00:00.612 |
|||
Total time counting 00:00:00.680 |
|||
real 0m0,685s |
|||
cDigit1 = 10,000 cDigit2 = 1,000,000,000 |
|||
Init takes 00:00:02.848 |
|||
1 7 10 13 19 23 28 31 32 44 |
|||
1E 1 n.th happy number 44 00:00:00.000 |
|||
1E 2 n.th happy number 694 00:00:00.000 |
|||
1E 3 n.th happy number 6,899 00:00:00.000 |
|||
1E 4 n.th happy number 67,169 00:00:00.000 |
|||
1E 5 n.th happy number 692,961 00:00:00.000 |
|||
1E 6 n.th happy number 7,105,849 00:00:00.000 |
|||
1E 7 n.th happy number 71,313,350 00:00:00.000 |
|||
1E 8 n.th happy number 698,739,425 00:00:00.001 |
|||
1E 9 n.th happy number 6,788,052,776 00:00:00.008 |
|||
1E10 n.th happy number 66,305,148,869 00:00:00.010 |
|||
1E11 n.th happy number 660,861,957,662 00:00:00.009 |
|||
1E12 n.th happy number 6,745,877,698,967 00:00:00.008 |
|||
1E13 n.th happy number 70,538,879,028,725 00:00:00.008 |
|||
1E14 n.th happy number 744,083,563,164,178 00:00:00.011 |
|||
1E15 n.th happy number 7,888,334,045,397,315 00:00:00.019 |
|||
1E16 n.th happy number 82,440,929,809,838,249 00:00:00.079 |
|||
1E17 n.th happy number 845,099,936,580,193,833 00:00:00.698 |
|||
1E18 n.th happy number 8,489,964,903,498,345,213 00:00:06.920 |
|||
Total time counting 00:00:07.771 |
|||
real 0m10,627s |
|||
</pre> |
|||
=={{header|PascalABC.NET}}== |
|||
<syntaxhighlight lang="delphi"> |
|||
uses School; |
|||
function IsHappy(n: integer): boolean; |
|||
begin |
|||
Result := False; |
|||
var cache := new HashSet<integer>; |
|||
while n <> 1 do |
|||
begin |
|||
if n in cache then |
|||
exit; |
|||
cache.Add(n); |
|||
n := n.Digits.Sum(d -> d*d); |
|||
end; |
|||
Result := True; |
|||
end; |
|||
begin |
|||
var n := 1; |
|||
var happyNums := new List<integer>; |
|||
while happyNums.Count < 8 do |
|||
begin |
|||
if IsHappy(n) then |
|||
happyNums.Add(n); |
|||
n += 1; |
|||
end; |
|||
happyNums.Print |
|||
end. |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Since all recurrences end with 1 or repeat (37,58,89,145,42,20,4,16), we can do this test very quickly without having to make hashes of seen numbers. |
|||
<lang perl>use List::Util qw(first sum); |
|||
<syntaxhighlight lang="perl">use List::Util qw(sum); |
|||
sub |
sub ishappy { |
||
my $s = shift; |
|||
while ($s > 6 && $s != 89) { |
|||
$s = sum(map { $_*$_ } split(//,$s)); |
|||
} |
|||
push @seen, $n;}} |
|||
$s == 1; |
|||
} |
|||
my $n = 0; |
|||
for (my ($n, $happy) = (1, 0) ; $happy < 8 ; ++$n) |
|||
print join(" ", map { 1 until ishappy(++$n); $n; } 1..8), "\n";</syntaxhighlight> |
|||
{is_happy $n or next; |
|||
{{out}} |
|||
print "$n\n"; |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
++$happy;}</lang> |
|||
Or we can solve using only the rudimentary task knowledge as below. Note the slightly different ways of doing the digit sum and finding the first 8 numbers where ishappy(n) is true -- this shows there's more than one way to do even these small sub-tasks. |
|||
{{trans|Raku}} |
|||
<syntaxhighlight lang="perl">use List::Util qw(sum); |
|||
sub is_happy { |
|||
my ($n) = @_; |
|||
my %seen; |
|||
while (1) { |
|||
$n = sum map { $_ ** 2 } split //, $n; |
|||
return 1 if $n == 1; |
|||
return 0 if $seen{$n}++; |
|||
} |
|||
} |
|||
my $n; |
|||
is_happy( ++$n ) and print "$n " or redo for 1..8;</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
=={{header|Phix}}== |
|||
Copy of [[Happy_numbers#Euphoria|Euphoria]] tweaked to give a one-line output |
|||
<!--<syntaxhighlight lang="phix">(phixonline)--> |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">is_happy</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">seen</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">seen</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">n</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
<span style="color: #008080;">while</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">+=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">),</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">/</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">k</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">,</span><span style="color: #000000;">seen</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">false</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">n</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
<span style="color: #008080;">while</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">8</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">is_happy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">&=</span> <span style="color: #000000;">n</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #000000;">n</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
<span style="color: #0000FF;">?</span><span style="color: #000000;">s</span> |
|||
<!--</syntaxhighlight>--> |
|||
{{out}} |
|||
<pre> |
|||
{1,7,10,13,19,23,28,31} |
|||
</pre> |
|||
=={{header|PHP}}== |
|||
{{trans|D}} |
|||
<syntaxhighlight lang="php">function isHappy($n) { |
|||
while (1) { |
|||
$total = 0; |
|||
while ($n > 0) { |
|||
$total += pow(($n % 10), 2); |
|||
$n /= 10; |
|||
} |
|||
if ($total == 1) |
|||
return true; |
|||
if (array_key_exists($total, $past)) |
|||
return false; |
|||
$n = $total; |
|||
$past[$total] = 0; |
|||
} |
|||
} |
|||
$i = $cnt = 0; |
|||
while ($cnt < 8) { |
|||
if (isHappy($i)) { |
|||
echo "$i "; |
|||
$cnt++; |
|||
} |
|||
$i++; |
|||
}</syntaxhighlight> |
|||
<pre>1 7 10 13 19 23 28 31 </pre> |
|||
=={{header|Picat}}== |
|||
<syntaxhighlight lang="picat">go => |
|||
println(happy_len(8)). |
|||
happy(N) => |
|||
S = [N], |
|||
Happy = 1, |
|||
while (Happy == 1, N > 1) |
|||
N := sum([to_integer(I)**2 : I in N.to_string()]), |
|||
if member(N,S) then |
|||
Happy := 0 |
|||
else |
|||
S := S ++ [N] |
|||
end |
|||
end, |
|||
Happy == 1. |
|||
happy_len(Limit) = S => |
|||
S = [], |
|||
N = 1, |
|||
while (S.length < Limit) |
|||
if happy(N) then |
|||
S := S ++ [N] |
|||
end, |
|||
N := N + 1 |
|||
end.</syntaxhighlight> |
|||
{{out}} |
|||
<pre>[1,7,10,13,19,23,28,31]</pre> |
|||
=={{header|PicoLisp}}== |
|||
<syntaxhighlight lang="picolisp">(de happy? (N) |
|||
(let Seen NIL |
|||
(loop |
|||
(T (= N 1) T) |
|||
(T (member N Seen)) |
|||
(setq N |
|||
(sum '((C) (** (format C) 2)) |
|||
(chop (push 'Seen N)) ) ) ) ) ) |
|||
(let H 0 |
|||
(do 8 |
|||
(until (happy? (inc 'H))) |
|||
(printsp H) ) )</syntaxhighlight> |
|||
Output: |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
=={{header|PILOT}}== |
|||
<syntaxhighlight lang="pilot">C :max=8 |
|||
:n=0 |
|||
:i=0 |
|||
*test |
|||
U :*happy |
|||
T (a=1):#n |
|||
C (a=1):i=i+1 |
|||
C :n=n+1 |
|||
J (i<max):*test |
|||
E : |
|||
*happy |
|||
C :a=n |
|||
:x=n |
|||
U :*sumsq |
|||
C :b=s |
|||
*loop |
|||
C :x=a |
|||
U :*sumsq |
|||
C :a=s |
|||
C :x=b |
|||
U :*sumsq |
|||
C :x=s |
|||
U :*sumsq |
|||
C :b=s |
|||
J (a<>b):*loop |
|||
E : |
|||
*sumsq |
|||
C :s=0 |
|||
*digit |
|||
C :y=x/10 |
|||
:z=x-y*10 |
|||
:s=s+z*#z |
|||
:x=y |
|||
J (x):*digit |
|||
E :</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|PL/I}}== |
|||
<syntaxhighlight lang="pl/i">test: proc options (main); /* 19 November 2011 */ |
|||
declare (i, j, n, m, nh initial (0) ) fixed binary (31); |
|||
main_loop: |
|||
do j = 1 to 100; |
|||
n = j; |
|||
do i = 1 to 100; |
|||
m = 0; |
|||
/* Form the sum of squares of the digits. */ |
|||
do until (n = 0); |
|||
m = m + mod(n, 10)**2; |
|||
n = n/10; |
|||
end; |
|||
if m = 1 then |
|||
do; |
|||
put skip list (j || ' is a happy number'); |
|||
nh = nh + 1; |
|||
if nh = 8 then return; |
|||
iterate main_loop; |
|||
end; |
|||
n = m; /* Replace n with the new number formed from digits. */ |
|||
end; |
|||
end; |
|||
end test; |
|||
</syntaxhighlight> |
|||
OUTPUT: |
|||
<pre> |
|||
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 |
|||
</pre> |
|||
=={{header|PL/M}}== |
|||
<syntaxhighlight lang="plm">100H: |
|||
/* FIND SUM OF SQUARE OF DIGITS OF NUMBER */ |
|||
DIGIT$SQUARE: PROCEDURE (N) BYTE; |
|||
DECLARE (N, T, D) BYTE; |
|||
T = 0; |
|||
DO WHILE N > 0; |
|||
D = N MOD 10; |
|||
T = T + D * D; |
|||
N = N / 10; |
|||
END; |
|||
RETURN T; |
|||
END DIGIT$SQUARE; |
|||
/* CHECK IF NUMBER IS HAPPY */ |
|||
HAPPY: PROCEDURE (N) BYTE; |
|||
DECLARE (N, I) BYTE; |
|||
DECLARE FLAG (256) BYTE; |
|||
DO I=0 TO 255; |
|||
FLAG(I) = 0; |
|||
END; |
|||
DO WHILE NOT FLAG(N); |
|||
FLAG(N) = 1; |
|||
N = DIGIT$SQUARE(N); |
|||
END; |
|||
RETURN N = 1; |
|||
END HAPPY; |
|||
/* CP/M BDOS CALL */ |
|||
BDOS: PROCEDURE (FN, ARG); |
|||
DECLARE FN BYTE, ARG ADDRESS; |
|||
GO TO 5; |
|||
END BDOS; |
|||
/* PRINT STRING */ |
|||
PRINT: PROCEDURE (STR); |
|||
DECLARE STR ADDRESS; |
|||
CALL BDOS(9, STR); |
|||
END PRINT; |
|||
/* PRINT NUMBER */ |
|||
PRINT$NUMBER: PROCEDURE (N); |
|||
DECLARE S (6) BYTE INITIAL ('...',13,10,'$'); |
|||
DECLARE P ADDRESS; |
|||
DECLARE (N, C BASED P) BYTE; |
|||
P = .S(3); |
|||
DIGIT: |
|||
P = P - 1; |
|||
C = (N MOD 10) + '0'; |
|||
N = N / 10; |
|||
IF N > 0 THEN GO TO DIGIT; |
|||
CALL PRINT(P); |
|||
END PRINT$NUMBER; |
|||
/* FIND FIRST 8 HAPPY NUMBERS */ |
|||
DECLARE SEEN BYTE INITIAL (0); |
|||
DECLARE N BYTE INITIAL (1); |
|||
DO WHILE SEEN < 8; |
|||
IF HAPPY(N) THEN DO; |
|||
CALL PRINT$NUMBER(N); |
|||
SEEN = SEEN + 1; |
|||
END; |
|||
N = N + 1; |
|||
END; |
|||
CALL BDOS(0,0); |
|||
EOF</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Potion}}== |
|||
<syntaxhighlight lang="potion">sqr = (n): n * n. |
|||
isHappy = (n) : |
|||
loop : |
|||
if (n == 1): return true. |
|||
if (n == 4): return false. |
|||
sum = 0 |
|||
n = n string |
|||
n length times (i): sum = sum + sqr(n(i) number integer). |
|||
n = sum |
|||
. |
|||
. |
|||
firstEight = () |
|||
i = 0 |
|||
while (firstEight length < 8) : |
|||
i++ |
|||
if (isHappy(i)): firstEight append(i). |
|||
. |
|||
firstEight string print</syntaxhighlight> |
|||
=={{header|PowerShell}}== |
|||
<syntaxhighlight 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 |
|||
} |
|||
$hist[$sum]=$sum |
|||
$sum2=0 |
|||
foreach($j in $sum.ToString().ToCharArray()) { |
|||
$k=([int]$j)-0x30 |
|||
$sum2+=$k*$k |
|||
} |
|||
$sum=$sum2 |
|||
} |
|||
} |
|||
$a -join ',' |
|||
}</syntaxhighlight> |
|||
Output : |
|||
<syntaxhighlight lang="powershell">happy(8) |
|||
7,10,13,19,23,28,31,32</syntaxhighlight> |
|||
=={{header|Prolog}}== |
|||
{{Works with|SWI-Prolog}} |
|||
<syntaxhighlight 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.</syntaxhighlight> |
|||
Output : |
|||
<syntaxhighlight lang="prolog"> ?- happy_numbers(L, 8). |
|||
L = [1,7,10,13,19,23,28,31].</syntaxhighlight> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
===Procedural=== |
|||
<lang python>>>> def happy(n): |
|||
<syntaxhighlight lang="python">>>> def happy(n): |
|||
past = [] |
|||
past = set() |
|||
while True: |
|||
while n != 1: |
|||
total = sum(int(i)**2 for i in str(n)) |
|||
n = sum(int(i)**2 for i in str(n)) |
|||
if n in past: |
|||
return False |
|||
past. |
past.add(n) |
||
return True |
|||
>>> [x for x in range(1,500) if happy(x)][:8] |
|||
</lang> |
|||
>>> [x for x in xrange(500) if happy(x)][:8] |
|||
[1, 7, 10, 13, 19, 23, 28, 31]</syntaxhighlight> |
|||
===Composition of pure functions=== |
|||
Drawing 8 terms from a non finite stream, rather than assuming prior knowledge of the finite sample size required: |
|||
<syntaxhighlight lang="python">'''Happy numbers''' |
|||
from itertools import islice |
|||
# main :: IO () |
|||
def main(): |
|||
'''Test''' |
|||
print( |
|||
take(8)( |
|||
happyNumbers() |
|||
) |
|||
) |
|||
# happyNumbers :: Gen [Int] |
|||
def happyNumbers(): |
|||
'''Generator :: non-finite stream of happy numbers.''' |
|||
x = 1 |
|||
while True: |
|||
x = until(isHappy)(succ)(x) |
|||
yield x |
|||
x = succ(x) |
|||
# isHappy :: Int -> Bool |
|||
def isHappy(n): |
|||
'''Happy number sequence starting at n reaches 1 ?''' |
|||
seen = set() |
|||
# p :: Int -> Bool |
|||
def p(x): |
|||
if 1 == x or x in seen: |
|||
return True |
|||
else: |
|||
seen.add(x) |
|||
return False |
|||
# f :: Int -> Int |
|||
def f(x): |
|||
return sum(int(d)**2 for d in str(x)) |
|||
return 1 == until(p)(f)(n) |
|||
# GENERIC ------------------------------------------------- |
|||
# succ :: Int -> Int |
|||
def succ(x): |
|||
'''The successor of an integer.''' |
|||
return 1 + x |
|||
# take :: Int -> [a] -> [a] |
|||
# take :: Int -> String -> String |
|||
def take(n): |
|||
'''The prefix of xs of length n, |
|||
or xs itself if n > length xs.''' |
|||
return lambda xs: ( |
|||
xs[0:n] |
|||
if isinstance(xs, list) |
|||
else list(islice(xs, n)) |
|||
) |
|||
# until :: (a -> Bool) -> (a -> a) -> a -> a |
|||
def until(p): |
|||
'''The result of repeatedly applying f until p holds. |
|||
The initial seed value is x.''' |
|||
def go(f, x): |
|||
v = x |
|||
while not p(v): |
|||
v = f(v) |
|||
return v |
|||
return lambda f: lambda x: go(f, x) |
|||
if __name__ == '__main__': |
|||
main()</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>[1, 7, 10, 13, 19, 23, 28, 31]</pre> |
|||
=={{header|Quackery}}== |
|||
<syntaxhighlight lang="quackery"> |
|||
[ 0 swap |
|||
[ 10 /mod 2 ** |
|||
rot + swap |
|||
dup 0 = until ] |
|||
drop ] is digitsquare ( n --> n ) |
|||
[ [ digitsquare |
|||
dup 1 != while |
|||
dup 42 != while |
|||
again ] |
|||
1 = ] is happy ( n --> b ) |
|||
[ [] 1 |
|||
[ dip |
|||
[ 2dup size > ] |
|||
swap while |
|||
dup happy if |
|||
[ tuck join swap ] |
|||
1+ again ] |
|||
drop nip ] is happies ( n --> [ ) |
|||
8 happies echo</syntaxhighlight> |
|||
{{Out}} |
|||
<pre>[ 1 7 10 13 19 23 28 31 ]</pre> |
|||
=={{header|R}}== |
=={{header|R}}== |
||
<syntaxhighlight lang="r">is.happy <- function(n) |
|||
<lang R> |
|||
is.happy <- function(n) |
|||
{ |
{ |
||
stopifnot(is.numeric(n) && length(n)==1) |
stopifnot(is.numeric(n) && length(n)==1) |
||
Line 564: | Line 6,382: | ||
} |
} |
||
happy |
happy |
||
}</syntaxhighlight> |
|||
} |
|||
</lang> |
|||
Example usage |
Example usage |
||
<syntaxhighlight lang="r">is.happy(2)</syntaxhighlight> |
|||
<lang R> |
|||
is.happy(2) |
|||
</lang> |
|||
[1] FALSE |
[1] FALSE |
||
attr(,"cycle") |
attr(,"cycle") |
||
[1] 4 16 37 58 89 145 42 20 |
[1] 4 16 37 58 89 145 42 20 |
||
<syntaxhighlight lang="r">#Find happy numbers between 1 and 50 |
|||
<lang R> |
|||
which(apply(rbind(1:50), 2, is.happy))</syntaxhighlight> |
|||
#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 |
1 7 10 13 19 23 28 31 32 44 49 |
||
<syntaxhighlight lang="r">#Find the first 8 happy numbers |
|||
<lang R> |
|||
#Find the first 8 happy numbers |
|||
happies <- c() |
happies <- c() |
||
i <- 1L |
i <- 1L |
||
Line 587: | Line 6,399: | ||
i <- i + 1L |
i <- i + 1L |
||
} |
} |
||
happies |
happies</syntaxhighlight> |
||
</lang> |
|||
1 7 10 13 19 23 28 31 |
1 7 10 13 19 23 28 31 |
||
=={{header|Racket}}== |
|||
<syntaxhighlight lang="racket">#lang racket |
|||
(define (sum-of-squared-digits number (result 0)) |
|||
(if (zero? number) |
|||
result |
|||
(sum-of-squared-digits (quotient number 10) |
|||
(+ result (expt (remainder number 10) 2))))) |
|||
(define (happy-number? number (seen null)) |
|||
(define next (sum-of-squared-digits number)) |
|||
(cond ((= 1 next) |
|||
#t) |
|||
((memq next seen) |
|||
#f) |
|||
(else |
|||
(happy-number? next (cons number seen))))) |
|||
(define (get-happys max) |
|||
(for/list ((x (in-range max)) |
|||
#:when (happy-number? x)) |
|||
x)) |
|||
(display (take (get-happys 100) 8)) ;displays (1 7 10 13 19 23 28 31)</syntaxhighlight> |
|||
=={{header|Raku}}== |
|||
(formerly Perl 6) |
|||
{{works with|rakudo|2015-09-13}} |
|||
<syntaxhighlight lang="raku" line>sub happy (Int $n is copy --> Bool) { |
|||
loop { |
|||
state %seen; |
|||
$n = [+] $n.comb.map: { $_ ** 2 } |
|||
return True if $n == 1; |
|||
return False if %seen{$n}++; |
|||
} |
|||
} |
|||
say join ' ', grep(&happy, 1 .. *)[^8];</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 7 10 13 19 23 28 31</pre> |
|||
Here's another approach that uses a different set of tricks including lazy lists, gather/take, repeat-until, and the cross metaoperator X. |
|||
<syntaxhighlight lang="raku" line>my @happy = lazy gather for 1..* -> $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];</syntaxhighlight> |
|||
Output is the same as above. |
|||
Here is a version using a subset and an anonymous recursion (we cheat a little bit by using the knowledge that 7 is the second happy number): |
|||
<syntaxhighlight lang="raku" line>subset Happy of Int where sub ($n) { |
|||
$n == 1 ?? True !! |
|||
$n < 7 ?? False !! |
|||
&?ROUTINE([+] $n.comb »**» 2); |
|||
} |
|||
say (grep Happy, 1 .. *)[^8];</syntaxhighlight> |
|||
Again, output is the same as above. It is not clear whether this version returns in finite time for any integer, though. |
|||
There's more than one way to do it... |
|||
=={{header|Refal}}== |
|||
<syntaxhighlight lang="refal">$ENTRY Go { |
|||
= <ShowFirst 8 Happy 1>; |
|||
}; |
|||
ShowFirst { |
|||
0 s.F s.I = ; |
|||
s.N s.F s.I, <Mu s.F s.I>: T = |
|||
<Prout s.I> |
|||
<ShowFirst <- s.N 1> s.F <+ s.I 1>>; |
|||
s.N s.F s.I = |
|||
<ShowFirst s.N s.F <+ s.I 1>>; |
|||
}; |
|||
Happy { |
|||
1 e.X = T; |
|||
s.N e.X s.N e.Y = F; |
|||
s.N e.X = <Happy <SqDigSum s.N> s.N e.X>; |
|||
}; |
|||
SqDigSum { |
|||
0 = 0; |
|||
s.N, <Symb s.N>: s.Ds e.Rs, |
|||
<Numb s.Ds>: s.D, |
|||
<Numb e.Rs>: s.R = |
|||
<+ <* s.D s.D> <SqDigSum s.R>>; |
|||
};</syntaxhighlight> |
|||
{{out}} |
|||
<pre>1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Relation}}== |
|||
<syntaxhighlight lang="relation"> |
|||
function happy(x) |
|||
set y = x |
|||
set lasty = 0 |
|||
set found = " " |
|||
while y != 1 and not (found regex "\s".y."\s") |
|||
set found = found . y . " " |
|||
set m = 0 |
|||
while y > 0 |
|||
set digit = y mod 10 |
|||
set m = m + digit * digit |
|||
set y = (y - digit) / 10 |
|||
end while |
|||
set y = format(m,"%1d") |
|||
end while |
|||
set found = found . y . " " |
|||
if y = 1 |
|||
set result = 1 |
|||
else |
|||
set result = 0 |
|||
end if |
|||
end function |
|||
set c = 0 |
|||
set i = 1 |
|||
while c < 8 and i < 100 |
|||
if happy(i) |
|||
echo i |
|||
set c = c + 1 |
|||
end if |
|||
set i = i + 1 |
|||
end while |
|||
</syntaxhighlight> |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
=={{header|REXX}}== |
|||
<syntaxhighlight lang="rexx">/*REXX program computes and displays a specified range of happy numbers. */ |
|||
Call time 'R' |
|||
linesize=80 |
|||
Parse Arg low high /* obtain range of happy numbers */ |
|||
If low='?' Then Call help |
|||
If low='' Then low=10 |
|||
If high='' Then |
|||
Parse Value 1 low With low high |
|||
Do i=0 To 9 /*build a squared decimal digit table. */ |
|||
square.i=i*i |
|||
End |
|||
happy.=0 /* happy.m=1 - m is a happy number */ |
|||
unhappy.=0 /* unhappy.n=1 - n is an unhappy number*/ |
|||
hapn=0 /* count of the happy numbers */ |
|||
ol='' |
|||
Do n=1 While hapn<high /* test integers starting with 1 */ |
|||
If unhappy.n Then /* if n is unhappy, */ |
|||
Iterate /* then try next number */ |
|||
work=n |
|||
suml='' /* list of computed sums */ |
|||
Do Forever |
|||
sum=0 |
|||
Do length(work) /* compute sum of squared digits */ |
|||
Parse Var work digit +1 work |
|||
sum=sum+square.digit |
|||
End |
|||
Select |
|||
When unhappy.sum |, /* sum is known to be unhappy */ |
|||
wordpos(sum,suml)>0 Then Do /* or was already encountered */ |
|||
-- If wordpos(sum,suml)>0 Then say 'Loop' n':' suml sum |
|||
-- If n<7 Then say n':' suml sum |
|||
unhappy.n=1 /* n is unhappy */ |
|||
Call set suml /* amd so are all sums so far */ |
|||
Iterate n |
|||
End |
|||
When sum=1 Then Do /* we reached sum=1 */ |
|||
hapn+=1 /* increment number of happy numbers */ |
|||
happy.n=1 /* n is happy */ |
|||
If hapn>=low Then /* if it is in specified range */ |
|||
Call out n /* output it */ |
|||
If hapn=high Then /* end of range reached */ |
|||
Leave n /* we are done */ |
|||
Iterate n /* otherwise proceed */ |
|||
End |
|||
Otherwise Do /* otherwise */ |
|||
suml=suml sum /* add sum to list of sums */ |
|||
work=sum /* proceed with the new sum */ |
|||
End |
|||
End |
|||
End |
|||
End |
|||
If ol>'' Then /* more output data */ |
|||
Say strip(ol) /* write to console */ |
|||
-- Say time('E') |
|||
Exit |
|||
set: /* all intermediate sums are unhappy */ |
|||
Parse Arg list |
|||
Do While list<>'' |
|||
Parse Var list s list |
|||
unhappy.s=1 |
|||
End |
|||
Return |
|||
out: /* output management */ |
|||
Parse Arg hn /* the happy number */ |
|||
If length(ol hn)>linesize Then Do /* if it does not fit */ |
|||
Say strip(ol) /* output the line */ |
|||
ol=hn /* and start a new line */ |
|||
End |
|||
Else /* otherwise */ |
|||
ol=ol hn /* append is to the output line */ |
|||
Return |
|||
help: |
|||
Say 'rexx hno n compute and show the first n happy numbers' |
|||
Say 'rexx hno low high show happy numbers from index low to high' |
|||
Exit |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
K:\_B\HN>rexx hno ? |
|||
rexx hno n compute and show the first n happy numbers |
|||
rexx hno low high show happy numbers from index low to high |
|||
K:\_B\HN>rexx hno 8 |
|||
1 7 10 13 19 23 28 31 |
|||
K:\_B\HN>rexx hno 1000 1003 |
|||
6899 6904 6917 6923 |
|||
</pre> |
|||
=={{header|Ring}}== |
|||
<syntaxhighlight lang="ring">n = 1 |
|||
found = 0 |
|||
While found < 8 |
|||
If IsHappy(n) |
|||
found += 1 |
|||
see string(found) + " : " + string(n) + nl |
|||
ok |
|||
n += 1 |
|||
End |
|||
Func IsHappy n |
|||
cache = [] |
|||
While n != 1 |
|||
Add(cache,n) |
|||
t = 0 |
|||
strn = string(n) |
|||
for e in strn |
|||
t += pow(number(e),2) |
|||
next |
|||
n = t |
|||
If find(cache,n) Return False ok |
|||
End |
|||
Return True |
|||
</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 : 1 |
|||
2 : 7 |
|||
3 : 10 |
|||
4 : 13 |
|||
5 : 19 |
|||
6 : 23 |
|||
7 : 28 |
|||
8 : 31 |
|||
</pre> |
|||
=={{header|RPL}}== |
|||
{{works with|Halcyon Calc|4.2.7}} |
|||
≪ { } SWAP '''DO''' |
|||
SWAP OVER + 0 ROT |
|||
'''DO''' |
|||
MANT RND DUP IP SQ ROT + SWAP FP |
|||
'''UNTIL''' DUP NOT '''END''' |
|||
DROP |
|||
'''UNTIL''' DUP2 POS '''END''' |
|||
SWAP DROP 1 == |
|||
≫ |
|||
'HAPY?' STO |
|||
≪ { } 0 '''DO''' |
|||
1 + '''IF''' DUP HAPY? '''THEN''' SWAP OVER + SWAP '''END''' |
|||
'''UNTIL''' OVER SIZE 8 == '''END''' |
|||
≫ EVAL |
|||
{{out}} |
|||
<pre> |
|||
1: { 1 7 10 13 19 23 28 31 } |
|||
</pre> |
|||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
{{works with|Ruby|2.1}} |
|||
Use of cache from Python |
|||
<lang ruby>def happy?(n) |
|||
<syntaxhighlight lang="ruby">require 'set' # Set: Fast array lookup / Simple existence hash |
|||
seen = [] |
|||
state = while n>1 and not seen.include?(n) |
|||
@seen_numbers = Set.new |
|||
if $happy_cache[:happy].include?(n): break :happy |
|||
@happy_numbers = Set.new |
|||
elsif $happy_cache[:sad].include?(n): break :sad |
|||
end |
|||
def happy?(n) |
|||
seen << n |
|||
return true if n == 1 # Base case |
|||
n = sum_of_squares_of_digits(n) |
|||
return @happy_numbers.include?(n) if @seen_numbers.include?(n) # Use performance cache, and stop unhappy cycles |
|||
@seen_numbers << n |
|||
digit_squared_sum = n.digits.sum{|n| n*n} |
|||
if happy?(digit_squared_sum) |
|||
@happy_numbers << n |
|||
true # Return true |
|||
else |
|||
false # Return false |
|||
end |
end |
||
end</syntaxhighlight> |
|||
state.nil? and state = n == 1 ? :happy : :sad |
|||
$happy_cache[state] += seen |
|||
state == :happy |
|||
end |
|||
Helper method to produce output: |
|||
def sum_of_squares_of_digits(n) |
|||
<syntaxhighlight lang="ruby">def print_happy |
|||
sum = 0 |
|||
happy_numbers = [] |
|||
n, d = n.divmod(10) |
|||
1.step do |i| |
|||
sum += d**2 |
|||
break if happy_numbers.length >= 8 |
|||
happy_numbers << i if happy?(i) |
|||
end |
end |
||
# or |
|||
p happy_numbers |
|||
# sum = n.to_s.each_char.inject(0) {|sum,c| sum += (c.to_i)**2} |
|||
sum |
|||
end |
end |
||
print_happy</syntaxhighlight> |
|||
$happy_cache = Hash.new([]) |
|||
happy_numbers = [] |
|||
{{out}} |
|||
i = 1 |
|||
<syntaxhighlight lang="ruby">[1, 7, 10, 13, 19, 23, 28, 31]</syntaxhighlight> |
|||
while happy_numbers.length < 8 |
|||
happy_numbers << i if happy? i |
|||
===Alternative version=== |
|||
<syntaxhighlight lang="ruby">@memo = [0,1] |
|||
def happy(n) |
|||
sum = n.digits.sum{|n| n*n} |
|||
return @memo[sum] if @memo[sum]==0 or @memo[sum]==1 |
|||
@memo[sum] = 0 # for the cycle check |
|||
@memo[sum] = happy(sum) # return 1:Happy number, 0:other |
|||
end |
|||
i = count = 0 |
|||
while count < 8 |
|||
i += 1 |
i += 1 |
||
puts i or count+=1 if happy(i)==1 |
|||
end |
end |
||
p happy_numbers |
|||
p $happy_cache</lang> |
|||
<pre>[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]}</pre> |
|||
puts |
|||
=={{header|Smalltalk}}== |
|||
for i in 99999999999900..99999999999999 |
|||
{{works with|GNU Smalltalk}} |
|||
puts i if happy(i)==1 |
|||
end</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
99999999999901 |
|||
99999999999910 |
|||
99999999999914 |
|||
99999999999915 |
|||
99999999999916 |
|||
99999999999937 |
|||
99999999999941 |
|||
99999999999951 |
|||
99999999999956 |
|||
99999999999961 |
|||
99999999999965 |
|||
99999999999973 |
|||
</pre> |
|||
===Simpler Alternative=== |
|||
{{trans|Python}} |
{{trans|Python}} |
||
<syntaxhighlight lang="ruby">def happy?(n) |
|||
past = [] |
|||
until n == 1 |
|||
n = n.digits.sum { |d| d * d } |
|||
return false if past.include? n |
|||
past << n |
|||
end |
|||
true |
|||
end |
|||
i = count = 0 |
|||
until count == 8; puts i or count += 1 if happy?(i += 1) end |
|||
puts |
|||
(99999999999900..99999999999999).each { |i| puts i if happy?(i) }</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
99999999999901 |
|||
99999999999910 |
|||
99999999999914 |
|||
99999999999915 |
|||
99999999999916 |
|||
99999999999937 |
|||
99999999999941 |
|||
99999999999951 |
|||
99999999999956 |
|||
99999999999961 |
|||
99999999999965 |
|||
99999999999973</pre> |
|||
=={{header|Rust}}== |
|||
In Rust, using a tortoise/hare cycle detection algorithm (generic for integer types) |
|||
<syntaxhighlight lang="rust">#![feature(core)] |
|||
fn sumsqd(mut n: i32) -> i32 { |
|||
let mut sq = 0; |
|||
while n > 0 { |
|||
let d = n % 10; |
|||
sq += d*d; |
|||
n /= 10 |
|||
} |
|||
sq |
|||
} |
|||
use std::num::Int; |
|||
fn cycle<T: Int>(a: T, f: fn(T) -> T) -> T { |
|||
let mut t = a; |
|||
let mut h = f(a); |
|||
while t != h { |
|||
t = f(t); |
|||
h = f(f(h)) |
|||
} |
|||
t |
|||
} |
|||
fn ishappy(n: i32) -> bool { |
|||
cycle(n, sumsqd) == 1 |
|||
} |
|||
fn main() { |
|||
let happy = std::iter::count(1, 1) |
|||
.filter(|&n| ishappy(n)) |
|||
.take(8) |
|||
.collect::<Vec<i32>>(); |
|||
println!("{:?}", happy) |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[1, 7, 10, 13, 19, 23, 28, 31] |
|||
</pre> |
|||
=={{header|Salmon}}== |
|||
<syntaxhighlight lang="salmon">variable happy_count := 0; |
|||
outer: |
|||
iterate(x; [1...+oo]) |
|||
{ |
|||
variable seen := <<(* --> false)>>; |
|||
variable now := x; |
|||
while (true) |
|||
{ |
|||
if (seen[now]) |
|||
{ |
|||
if (now == 1) |
|||
{ |
|||
++happy_count; |
|||
print(x, " is happy.\n"); |
|||
if (happy_count == 8) |
|||
break from outer;; |
|||
}; |
|||
break; |
|||
}; |
|||
seen[now] := true; |
|||
variable new := 0; |
|||
while (now != 0) |
|||
{ |
|||
new += (now % 10) * (now % 10); |
|||
now /::= 10; |
|||
}; |
|||
now := new; |
|||
}; |
|||
};</syntaxhighlight> |
|||
This Salmon program produces the following output: |
|||
<pre>1 is happy. |
|||
7 is happy. |
|||
10 is happy. |
|||
13 is happy. |
|||
19 is happy. |
|||
23 is happy. |
|||
28 is happy. |
|||
31 is happy.</pre> |
|||
=={{header|Scala}}== |
|||
<syntaxhighlight 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 |
|||
</syntaxhighlight> |
|||
=={{header|Scheme}}== |
|||
<syntaxhighlight 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))))</syntaxhighlight> |
|||
The output is: |
|||
<pre>happy numbers: 1 7 10 13 19 23 28 31</pre> |
|||
=={{header|Scratch}}== |
|||
Scratch is a free visual programming language. Click the link, then "See inside" to view the code. |
|||
https://scratch.mit.edu/projects/78912620/ |
|||
This code will allow you to check if a positive interger (<=9999) is a happy number. It will also output a list of the first 8 happy numbers. (1 7 10 13 19 23 28 31) |
|||
=={{header|Seed7}}== |
|||
<syntaxhighlight lang="seed7">$ include "seed7_05.s7i"; |
|||
const type: cacheType is hash [integer] boolean; |
|||
var cacheType: cache is cacheType.value; |
|||
const func boolean: happy (in var integer: number) is func |
|||
result |
|||
var boolean: isHappy is FALSE; |
|||
local |
|||
var bitset: cycle is bitset.value; |
|||
var integer: newnumber is 0; |
|||
var integer: cycleNum is 0; |
|||
begin |
|||
while number > 1 and number not in cycle do |
|||
if number in cache then |
|||
number := ord(cache[number]); |
|||
else |
|||
incl(cycle, number); |
|||
newnumber := 0; |
|||
while number > 0 do |
|||
newnumber +:= (number rem 10) ** 2; |
|||
number := number div 10; |
|||
end while; |
|||
number := newnumber; |
|||
end if; |
|||
end while; |
|||
isHappy := number = 1; |
|||
for cycleNum range cycle do |
|||
cache @:= [cycleNum] isHappy; |
|||
end for; |
|||
end func; |
|||
const proc: main is func |
|||
local |
|||
var integer: number is 0; |
|||
begin |
|||
for number range 1 to 50 do |
|||
if happy(number) then |
|||
writeln(number); |
|||
end if; |
|||
end for; |
|||
end func;</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
32 |
|||
44 |
|||
49 |
|||
</pre> |
|||
=={{header|SequenceL}}== |
|||
<syntaxhighlight lang="sequencel">import <Utilities/Math.sl>; |
|||
import <Utilities/Conversion.sl>; |
|||
main(argv(2)) := findHappys(stringToInt(head(argv))); |
|||
findHappys(count) := findHappysHelper(count, 1, []); |
|||
findHappysHelper(count, n, happys(1)) := |
|||
happys when size(happys) = count |
|||
else |
|||
findHappysHelper(count, n + 1, happys ++ [n]) when isHappy(n) |
|||
else |
|||
findHappysHelper(count, n + 1, happys); |
|||
isHappy(n) := isHappyHelper(n, []); |
|||
isHappyHelper(n, cache(1)) := |
|||
let |
|||
digits[i] := (n / integerPower(10, i - 1)) mod 10 |
|||
foreach i within 1 ... ceiling(log(10, n + 1)); |
|||
newN := sum(integerPower(digits, 2)); |
|||
in |
|||
false when some(n = cache) |
|||
else |
|||
true when n = 1 |
|||
else |
|||
isHappyHelper(newN, cache ++ [n]);</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
$>happy.exe 8 |
|||
[1,7,10,13,19,23,28,31] |
|||
</pre> |
|||
=={{header|SETL}}== |
|||
<syntaxhighlight lang="setl">proc is_happy(n); |
|||
s := [n]; |
|||
while n > 1 loop |
|||
if (n := +/[val(i)**2: i in str(n)]) in s then |
|||
return false; |
|||
end if; |
|||
s with:= n; |
|||
end while; |
|||
return true; |
|||
end proc;</syntaxhighlight> |
|||
<syntaxhighlight lang="setl">happy := []; |
|||
n := 1; |
|||
until #happy = 8 loop |
|||
if is_happy(n) then happy with:= n; end if; |
|||
n +:= 1; |
|||
end loop; |
|||
print(happy);</syntaxhighlight> |
|||
Output: |
|||
<pre>[1 7 10 13 19 23 28 31]</pre> |
|||
Alternative version: |
|||
<syntaxhighlight lang="setl">print([n : n in [1..100] | is_happy(n)](1..8));</syntaxhighlight> |
|||
Output: |
|||
<pre>[1 7 10 13 19 23 28 31]</pre> |
|||
=={{header|Sidef}}== |
|||
<syntaxhighlight lang="ruby">func happy(n) is cached { |
|||
static seen = Hash() |
|||
return true if n.is_one |
|||
return false if seen.exists(n) |
|||
seen{n} = 1 |
|||
happy(n.digits.sum { _*_ }) |
|||
} |
|||
say happy.first(8)</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
[1, 7, 10, 13, 19, 23, 28, 31] |
|||
</pre> |
|||
=={{header|Smalltalk}}== |
|||
{{works with|GNU Smalltalk}} |
|||
{{trans|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. |
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. |
||
< |
<syntaxhighlight lang="smalltalk">Object subclass: HappyNumber [ |
||
|cache negativeCache| |
|cache negativeCache| |
||
HappyNumber class >> new [ |me| |
HappyNumber class >> new [ |me| |
||
Line 699: | Line 7,168: | ||
] |
] |
||
] |
] |
||
].</ |
].</syntaxhighlight> |
||
<syntaxhighlight lang="smalltalk">|happy| |
|||
<lang smalltalk>|happy| |
|||
happy := HappyNumber new. |
happy := HappyNumber new. |
||
1 to: |
1 to: 31 do: [ :i | |
||
(happy isHappy: i) |
(happy isHappy: i) |
||
ifTrue: [ i displayNl ] |
ifTrue: [ i displayNl ] |
||
].</ |
].</syntaxhighlight> |
||
Output: |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
an alternative version is: |
|||
{{works with|Smalltalk/X}} |
|||
<syntaxhighlight lang="smalltalk">|next isHappy happyNumbers| |
|||
next := |
|||
[:n | |
|||
(n printString collect:[:ch | ch digitValue squared] as:Array) sum |
|||
]. |
|||
isHappy := |
|||
[:n | | t already | |
|||
already := Set new. |
|||
t := n. |
|||
[ t == 1 or:[ (already includes:t)]] whileFalse:[ |
|||
already add:t. |
|||
t := next value:t. |
|||
]. |
|||
t == 1 |
|||
]. |
|||
happyNumbers := OrderedCollection new. |
|||
try := 1. |
|||
[happyNumbers size < 8] whileTrue:[ |
|||
(isHappy value:try) ifTrue:[ happyNumbers add:try]. |
|||
try := try + 1 |
|||
]. |
|||
happyNumbers printCR</syntaxhighlight> |
|||
Output: |
|||
OrderedCollection(1 7 10 13 19 23 28 31) |
|||
=={{header|Swift}}== |
|||
<syntaxhighlight lang="swift">func isHappyNumber(var n:Int) -> Bool { |
|||
var cycle = [Int]() |
|||
while n != 1 && !cycle.contains(n) { |
|||
cycle.append(n) |
|||
var m = 0 |
|||
while n > 0 { |
|||
let d = n % 10 |
|||
m += d * d |
|||
n = (n - d) / 10 |
|||
} |
|||
n = m |
|||
} |
|||
return n == 1 |
|||
} |
|||
var found = 0 |
|||
var count = 0 |
|||
while found != 8 { |
|||
if isHappyNumber(count) { |
|||
print(count) |
|||
found++ |
|||
} |
|||
count++ |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31</pre> |
|||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
using code from [[Sum of squares#Tcl]] |
using code from [[Sum of squares#Tcl]] |
||
< |
<syntaxhighlight lang="tcl">proc is_happy n { |
||
set seen [list] |
set seen [list] |
||
while {$n > 1 && [lsearch -exact $seen $n] == -1} { |
while {$n > 1 && [lsearch -exact $seen $n] == -1} { |
||
Line 726: | Line 7,270: | ||
incr n |
incr n |
||
} |
} |
||
puts "the first 8 happy numbers are: [list $happy]"</ |
puts "the first 8 happy numbers are: [list $happy]"</syntaxhighlight> |
||
<pre>the first 8 happy numbers are: {1 7 10 13 19 23 28 31}</pre> |
<pre>the first 8 happy numbers are: {1 7 10 13 19 23 28 31}</pre> |
||
=={{header|TUSCRIPT}}== |
|||
<syntaxhighlight lang="tuscript">$$ MODE TUSCRIPT |
|||
SECTION check |
|||
IF (n!=1) THEN |
|||
n = STRINGS (n,":>/:") |
|||
LOOP/CLEAR nr=n |
|||
square=nr*nr |
|||
n=APPEND (n,square) |
|||
ENDLOOP |
|||
n=SUM(n) |
|||
r_table=QUOTES (n) |
|||
BUILD R_TABLE/word/EXACT chk=r_table |
|||
IF (seq.ma.chk) THEN |
|||
status="next" |
|||
ELSE |
|||
seq=APPEND (seq,n) |
|||
ENDIF |
|||
RELEASE r_table chk |
|||
ELSE |
|||
PRINT checkednr," is a happy number" |
|||
happynrs=APPEND (happynrs,checkednr) |
|||
status="next" |
|||
ENDIF |
|||
ENDSECTION |
|||
happynrs="" |
|||
LOOP n=1,100 |
|||
sz_happynrs=SIZE(happynrs) |
|||
IF (sz_happynrs==8) EXIT |
|||
checkednr=VALUE(n) |
|||
status=seq="" |
|||
LOOP |
|||
IF (status=="next") EXIT |
|||
DO check |
|||
ENDLOOP |
|||
ENDLOOP</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
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 |
|||
</pre> |
|||
=={{header|Uiua}}== |
|||
{{works with|Uiua|0.10.0-dev.1}} |
|||
<syntaxhighlight lang="Uiua"> |
|||
HC ← /+ⁿ2≡⋕°⋕ # Happiness calc = sum of squares of digits |
|||
IH ← |2 memo⟨IH ⊙⊂.|=1⟩∊,, HC # Apply HC until seen value recurs |
|||
Happy ← ⟨0◌|∘⟩IH : [1] . # Pre-load `seen` with 1. Return start number or 0 |
|||
# Brute force approach isn't too bad with memoisation even for high bounds. |
|||
↙8⊚>0≡Happy⇡10000 |
|||
# But iterative approach is still much faster |
|||
NH ← |1 ⟨NH|∘⟩≠0Happy.+1 # Find next Happy number |
|||
⇌[⍥(NH.) 7 1] |
|||
</syntaxhighlight> |
|||
=={{header|UNIX Shell}}== |
|||
{{works with|Bourne Again SHell}} |
|||
{{works with|Korn Shell}} |
|||
{{works with|Z Shell}} |
|||
<syntaxhighlight lang="bash">function sum_of_square_digits { |
|||
typeset -i n=$1 sum=0 d |
|||
while (( n )); do |
|||
(( d=n%10, sum+=d*d, n=n/10 )) |
|||
done |
|||
printf '%d\n' "$sum" |
|||
} |
|||
function is_happy { |
|||
typeset -i n=$1 |
|||
typeset -a seen=() |
|||
while (( n != 1 )); do |
|||
if [[ -n ${seen[$n]} ]]; then |
|||
return 1 |
|||
fi |
|||
seen[$n]=1 |
|||
(( n=$(sum_of_square_digits "$n") )) |
|||
done |
|||
return 0 |
|||
} |
|||
function first_n_happy { |
|||
typeset -i count=$1 n |
|||
for (( n=1; count; n+=1 )); do |
|||
if is_happy "$n"; then |
|||
printf '%d\n' "$n" |
|||
(( count -= 1 )) |
|||
fi |
|||
done |
|||
return 0 |
|||
} |
|||
first_n_happy 8</syntaxhighlight> |
|||
=={{header|Ursala}}== |
=={{header|Ursala}}== |
||
Line 733: | Line 7,379: | ||
and first(p) defines a function mapping a number n to the first n |
and first(p) defines a function mapping a number n to the first n |
||
positive naturals having property p. |
positive naturals having property p. |
||
< |
<syntaxhighlight lang="ursala">#import std |
||
#import nat |
#import nat |
||
Line 742: | Line 7,388: | ||
#cast %nL |
#cast %nL |
||
main = (first happy) 8</ |
main = (first happy) 8</syntaxhighlight> |
||
output: |
output: |
||
<pre><1,7,10,13,19,23,28,31></pre> |
<pre><1,7,10,13,19,23,28,31></pre> |
||
=={{header|Vala}}== |
|||
{{libheader|Gee}} |
|||
<syntaxhighlight lang="vala">using Gee; |
|||
/* function to sum the square of the digits */ |
|||
int sum(int input){ |
|||
// convert input int to string |
|||
string input_str = input.to_string(); |
|||
int total = 0; |
|||
// read through each character in string, square them and add to total |
|||
for (int x = 0; x < input_str.length; x++){ |
|||
// char.digit_value converts char to the decimal value the char it represents holds |
|||
int digit = input_str[x].digit_value(); |
|||
total += (digit * digit); |
|||
} |
|||
return total; |
|||
} // end sum |
|||
/* function to decide if a number is a happy number */ |
|||
bool is_happy(int total){ |
|||
var past = new HashSet<int>(); |
|||
while(true){ |
|||
total = sum(total); |
|||
if (total == 1){ |
|||
return true;} |
|||
if (total in past){ |
|||
return false;} |
|||
past.add(total); |
|||
} // end while loop |
|||
} // end happy |
|||
public static void main(){ |
|||
var happynums = new ArrayList<int>(); |
|||
int x = 1; |
|||
while (happynums.size < 8){ |
|||
if (is_happy(x) == true) |
|||
happynums.add(x); |
|||
x++; |
|||
} |
|||
foreach(int num in happynums) |
|||
stdout.printf("%d ", num); |
|||
stdout.printf("\n"); |
|||
} // end main</syntaxhighlight> |
|||
The output is: |
|||
<pre> |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|V (Vlang)}}== |
|||
{{trans|go}} |
|||
<syntaxhighlight lang="v (vlang)">fn happy(h int) bool { |
|||
mut m := map[int]bool{} |
|||
mut n := h |
|||
for n > 1 { |
|||
m[n] = true |
|||
mut x := 0 |
|||
for x, n = n, 0; x > 0; x /= 10 { |
|||
d := x % 10 |
|||
n += d * d |
|||
} |
|||
if m[n] { |
|||
return false |
|||
} |
|||
} |
|||
return true |
|||
} |
|||
fn main() { |
|||
for found, n := 0, 1; found < 8; n++ { |
|||
if happy(n) { |
|||
print("$n ") |
|||
found++ |
|||
} |
|||
} |
|||
println('') |
|||
}</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|Wren}}== |
|||
{{trans|Go}} |
|||
<syntaxhighlight lang="wren">var happy = Fn.new { |n| |
|||
var m = {} |
|||
while (n > 1) { |
|||
m[n] = true |
|||
var x = n |
|||
n = 0 |
|||
while (x > 0) { |
|||
var d = x % 10 |
|||
n = n + d*d |
|||
x = (x/10).floor |
|||
} |
|||
if (m[n] == true) return false // m[n] will be null if 'n' is not a key |
|||
} |
|||
return true |
|||
} |
|||
var found = 0 |
|||
var n = 1 |
|||
while (found < 8) { |
|||
if (happy.call(n)) { |
|||
System.write("%(n) ") |
|||
found = found + 1 |
|||
} |
|||
n = n + 1 |
|||
} |
|||
System.print()</syntaxhighlight> |
|||
{{out}} |
|||
<pre> |
|||
1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|XPL0}}== |
|||
The largest possible 32-bit integer is less than 9,999,999,999. The sum of |
|||
the squares of these ten digits is 10*9^2 = 810. If a cycle consisted of all |
|||
the values smaller than 810, an array size of 810 would still be sufficiently |
|||
large to hold them. Actually, tests show that the array only needs to hold 16 |
|||
numbers. |
|||
<syntaxhighlight lang="xpl0">int List(810); \list of numbers in a cycle |
|||
int Inx; \index for List |
|||
include c:\cxpl\codes; |
|||
func HadNum(N); \Return 'true' if number N is in the List |
|||
int N; |
|||
int I; |
|||
[for I:= 0 to Inx-1 do |
|||
if N = List(I) then return true; |
|||
return false; |
|||
]; \HadNum |
|||
func SqDigits(N); \Return the sum of the squares of the digits of N |
|||
int N; |
|||
int S, D; |
|||
[S:= 0; |
|||
while N do |
|||
[N:= N/10; |
|||
D:= rem(0); |
|||
S:= S + D*D; |
|||
]; |
|||
return S; |
|||
]; \SqDigits |
|||
int N0, N, C; |
|||
[N0:= 0; \starting number |
|||
C:= 0; \initialize happy (starting) number counter |
|||
repeat N:= N0; |
|||
Inx:= 0; \reset List index |
|||
loop [N:= SqDigits(N); |
|||
if N = 1 then \happy number |
|||
[IntOut(0, N0); CrLf(0); |
|||
C:= C+1; |
|||
quit; |
|||
]; |
|||
if HadNum(N) then quit; \if unhappy number then quit |
|||
List(Inx):= N; \if neither, add it to the List |
|||
Inx:= Inx+1; \ and continue the cycle |
|||
]; |
|||
N0:= N0+1; \next starting number |
|||
until C=8; \done when 8 happy numbers have been found |
|||
]</syntaxhighlight> |
|||
Output: |
|||
<pre> |
|||
1 |
|||
7 |
|||
10 |
|||
13 |
|||
19 |
|||
23 |
|||
28 |
|||
31 |
|||
</pre> |
|||
=={{header|Zig}}== |
|||
<syntaxhighlight lang="zig"> |
|||
const std = @import("std"); |
|||
const stdout = std.io.getStdOut().outStream(); |
|||
pub fn main() !void { |
|||
try stdout.print("The first 8 happy numbers are: ", .{}); |
|||
var n: u32 = 1; |
|||
var c: u4 = 0; |
|||
while (c < 8) { |
|||
if (isHappy(n)) { |
|||
c += 1; |
|||
try stdout.print("{} ", .{n}); |
|||
} |
|||
n += 1; |
|||
} |
|||
try stdout.print("\n", .{}); |
|||
} |
|||
fn isHappy(n: u32) bool { |
|||
var t = n; |
|||
var h = sumsq(n); |
|||
while (t != h) { |
|||
t = sumsq(t); |
|||
h = sumsq(sumsq(h)); |
|||
} |
|||
return t == 1; |
|||
} |
|||
fn sumsq(n0: u32) u32 { |
|||
var s: u32 = 0; |
|||
var n = n0; |
|||
while (n > 0) : (n /= 10) { |
|||
const m = n % 10; |
|||
s += m * m; |
|||
} |
|||
return s; |
|||
} |
|||
</syntaxhighlight> |
|||
{{Out}} |
|||
<pre> |
|||
The first 8 happy numbers are: 1 7 10 13 19 23 28 31 |
|||
</pre> |
|||
=={{header|zkl}}== |
|||
Here is a function that generates a continuous stream of happy numbers. Given that there are lots of happy numbers, caching them doesn't seem like a good idea memory wise. Instead, a num of squared digits == 4 is used as a proxy for a cycle (see the Wikipedia article, there are several number that will work). |
|||
{{trans|Icon and Unicon}} |
|||
<syntaxhighlight lang="zkl">fcn happyNumbers{ // continously spew happy numbers |
|||
foreach N in ([1..]){ |
|||
n:=N; while(1){ |
|||
n=n.split().reduce(fcn(p,n){ p + n*n },0); |
|||
if(n==1) { vm.yield(N); break; } |
|||
if(n==4) break; // unhappy cycle |
|||
} |
|||
} |
|||
}</syntaxhighlight> |
|||
<syntaxhighlight lang="zkl">h:=Utils.Generator(happyNumbers); |
|||
h.walk(8).println();</syntaxhighlight> |
|||
{{out}} |
|||
<pre>L(1,7,10,13,19,23,28,31)</pre> |
|||
Get the one million-th happy number. Nobody would call this quick. |
|||
<syntaxhighlight lang="zkl">Utils.Generator(happyNumbers).drop(0d1_000_000-1).next().println();</syntaxhighlight> |
|||
{{out}}<pre>7105849</pre> |
Latest revision as of 05:16, 29 July 2024
![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 end in 1 are happy numbers,
- while those numbers that do not end in 1 are unhappy numbers.
- Task
Find and print the first 8 happy numbers.
Display an example of your output here on this page.
- Related tasks
- See also
- The OEIS entry: The happy numbers: A007770
- The OEIS entry: The unhappy numbers; A031177
11l
F happy(=n)
Set[Int] past
L n != 1
n = sum(String(n).map(с -> Int(с)^2))
I n C past
R 0B
past.add(n)
R 1B
print((0.<500).filter(x -> happy(x))[0.<8])
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
8080 Assembly
This is not just a demonstration of 8080 assembly, but also of why it pays to look closely at the problem domain. The following program only does 8-bit unsigned integer math, which not only fits the 8080's instruction set very well, it also means the cycle detection can be done using only an array of 256 flags, and all other state fits in the registers. This makes the program a good deal simpler than it would've been otherwise.
In general, 8-bit math is not good enough for numerical problems, but in this particular case, the problem only asks for the first eight happy numbers, none of which (nor any of the unhappy numbers in between) have a cycle that ever goes above 145, so eight bits is good enough. In fact, for any input under 256, the cycle never goes above 163; this program could be trivially changed to print up to 39 happy numbers.
flags: equ 2 ; 256-byte page in which to keep track of cycles
puts: equ 9 ; CP/M print string
bdos: equ 5 ; CP/M entry point
org 100h
lxi d,0108h ; D=current number to test, E=amount of numbers
;;; Is D happy?
number: mvi a,1 ; We haven't seen any numbers yet, set flags to 1
lxi h,256*flags
init: mov m,a
inr l
jnz init
mov a,d ; Get digits
step: call digits
mov l,a ; L = D1 * D1
mov h,a
xra a
sqr1: add h
dcr l
jnz sqr1
mov l,a
mov h,b ; L += D10 * D10
xra a
sqr10: add h
dcr b
jnz sqr10
add l
mov l,a
mov h,c ; L += D100 * D100
xra a
sqr100: add h
dcr c
jnz sqr100
add l
mov l,a
mvi h,flags ; Look up corresponding flag
dcr m ; Will give 0 the first time and not-0 afterwards
mov a,l ; If we haven't seen the number before, another step
jz step
dcr l ; If we _had_ seen it, then is it 1?
jz happy ; If so, it is happy
next: inr d ; Afterwards, try next number
jmp number
happy: mov a,d ; D is happy - get its digits (for output)
lxi h,string+3
call digits ; Write digits into string for output
call sdgt ; Ones digit,
mov a,b ; Tens digit,
call sdgt
mov a,c ; Hundreds digit
call sdgt
push d ; Keep counters on stack
mvi c,puts ; Print string using CP/M call
xchg
call bdos
pop d ; Restore counters
dcr e ; One fewer happy number left
jnz next ; If we need more, do the next one
ret
;;; Store A as ASCII digit in [HL] and go to previous digit
sdgt: adi '0'
dcx h
mov m,a
ret
;;; Get digits of 8-bit number in A.
;;; Input: A = number
;;; Output: C=100s digit, B=10s digit, A=1s digit
digits: lxi b,-1 ; Set B and C to -1 (correct for extra loop cycle)
d100: inr c ; Calculate hundreds digit
sui 100 ; By trial subtraction of 100
jnc d100 ; Until underflow occurs
adi 100 ; Loop runs one cycle too many, so add 100 back
d10: inr b ; Calculate 10s digit in the same way
sui 10
jnc d10
adi 10
ret ; 1s digit is left in A afterwards
string: db '000',13,10,'$'
- Output:
001 007 010 013 019 023 028 031
8th
: until! "not while!" eval i;
with: w
with: n
: sumsqd \ n -- n
0 swap repeat
0; 10 /mod -rot sqr + swap
again ;
: cycle \ n xt -- n
>r
dup r@ exec \ -- tortoise, hare
repeat
swap r@ exec
swap r@ exec r@ exec
2dup = until!
rdrop drop ;
: happy? ' sumsqd cycle 1 = ;
: .happy \ n --
1 repeat
dup happy? if dup . space swap 1- swap then 1+
over 0 > while!
2drop cr ;
;with
;with
- Output:
ok> 8 .happy 1 7 10 13 19 23 28 31
ABC
HOW TO RETURN square.digit.sum n:
PUT 0 IN sum
WHILE n>0:
PUT n mod 10 IN digit
PUT sum + digit ** 2 IN sum
PUT floor (n/10) IN n
RETURN sum
HOW TO REPORT happy n:
PUT {} IN seen
WHILE n not.in seen:
INSERT n IN seen
PUT square.digit.sum n IN n
REPORT n=1
HOW TO RETURN next.happy n:
PUT n+1 IN n
WHILE NOT happy n: PUT n+1 IN n
RETURN n
PUT 0 IN n
FOR i IN {1..8}:
PUT next.happy n IN n
WRITE n/
- Output:
1 7 10 13 19 23 28 31
ACL2
(include-book "arithmetic-3/top" :dir :system)
(defun sum-of-digit-squares (n)
(if (zp n)
0
(+ (expt (mod n 10) 2)
(sum-of-digit-squares (floor n 10)))))
(defun is-happy-r (n seen)
(let ((next (sum-of-digit-squares n)))
(cond ((= next 1) t)
((member next seen) nil)
(t (is-happy-r next (cons next seen))))))
(defun is-happy (n)
(is-happy-r n nil))
(defun first-happy-nums-r (n i)
(cond ((zp n) nil)
((is-happy i)
(cons i (first-happy-nums-r (1- n) (1+ i))))
(t (first-happy-nums-r n (1+ i)))))
(defun first-happy-nums (n)
(first-happy-nums-r n 1))
Output:
(1 7 10 13 19 23 28 31)
Action!
BYTE FUNC SumOfSquares(BYTE x)
BYTE sum,d
sum=0
WHILE x#0
DO
d=x MOD 10
d==*d
sum==+d
x==/10
OD
RETURN (sum)
BYTE FUNC Contains(BYTE ARRAY a BYTE count,x)
BYTE i
FOR i=0 TO count-1
DO
IF a(i)=x THEN RETURN (1) FI
OD
RETURN (0)
BYTE FUNC IsHappyNumber(BYTE x)
BYTE ARRAY cache(100)
BYTE count
count=0
WHILE x#1
DO
cache(count)=x
count==+1
x=SumOfSquares(x)
IF Contains(cache,count,x) THEN
RETURN (0)
FI
OD
RETURN (1)
PROC Main()
BYTE x,count
x=1 count=0
WHILE count<8
DO
IF IsHappyNumber(x) THEN
count==+1
PrintF("%I: %I%E",count,x)
FI
x==+1
OD
RETURN
- Output:
Screenshot from Atari 8-bit computer
1: 1 2: 7 3: 10 4: 13 5: 19 6: 23 7: 28 8: 31
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();
Sample output:
1 7 10 13 19 23 28 31
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
ALGOL 68
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
ALGOL-M
begin
integer function mod(a,b);
integer a,b;
mod := a-(a/b)*b;
integer function sumdgtsq(n);
integer n;
sumdgtsq :=
if n = 0 then 0
else mod(n,10)*mod(n,10) + sumdgtsq(n/10);
integer function happy(n);
integer n;
begin
integer i;
integer array seen[0:200];
for i := 0 step 1 until 200 do seen[i] := 0;
while seen[n] = 0 do
begin
seen[n] := 1;
n := sumdgtsq(n);
end;
happy := if n = 1 then 1 else 0;
end;
integer i, n;
i := n := 0;
while n < 8 do
begin
if happy(i) = 1 then
begin
write(i);
n := n + 1;
end;
i := i + 1;
end;
end
- Output:
1 7 10 13 19 23 28 31
ALGOL W
begin % find some happy numbers: numbers whose digit-square sums become 1 %
% when repeatedly applied %
% returns true if n is happy, false otherwise %
logical procedure isHappy ( integer value n ) ;
begin
% in base ten, numbers either reach 1 or loop around a sequence %
% containing 4 (see the Wikipedia article) %
integer v, dSum, d;
v := abs n;
if v > 1 then begin
while begin
dSum := 0;
while v not = 0 do begin
d := v rem 10;
v := v div 10;
dSum := dSum + ( d * d )
end while_v_ne_0 ;
v := dSum;
v not = 1 and v not = 4
end do begin end
end if_v_ne_0 ;
v = 1
end isHappy ;
begin % find the first 8 happy numbers %
integer n, hCount;
hCount := 0;
n := 1;
while hCount < 8 do begin
if isHappy( n ) then begin
writeon( i_w := 1, s_w := 0, " ", n );
hCount := hCount + 1
end if_isHappy__n ;
n := n + 1
end while_hCount_lt_10
end
end.
- Output:
1 7 10 13 19 23 28 31
APL
Tradfn
∇ 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
∇
HappyNumbers 100 8 1 7 10 13 19 23 28 31
Dfn
HappyNumbers←{ ⍝ return the first ⍵ Happy Numbers
⍺←⍬ ⍝ initial list
⍵=+/⍺:⍸⍺ ⍝ 1's mark happy numbers
sq←×⍨ ⍝ square function (times selfie)
isHappy←{ ⍝ is ⍵ a happy number?
⍺←⍬ ⍝ previous sums
⍵=1:1 ⍝ if we get to 1, it's happy
n←+/sq∘⍎¨⍕⍵ ⍝ sum of the square of the digits
n∊⍺:0 ⍝ if we hit this sum before, it's not happy
(⍺,n)∇ n} ⍝ recurse until it's happy or not
(⍺,isHappy 1+≢⍺)∇ ⍵ ⍝ recurse until we have ⍵ happy numbers
}
HappyNumbers 8
1 7 10 13 19 23 28 31
AppleScript
Iteration
on run
set howManyHappyNumbers to 8
set happyNumberList to {}
set globalCounter to 1
repeat howManyHappyNumbers times
repeat while not isHappy(globalCounter)
set globalCounter to globalCounter + 1
end repeat
set end of happyNumberList to globalCounter
set globalCounter to globalCounter + 1
end repeat
log happyNumberList
end run
on isHappy(numberToCheck)
set localCycle to {}
repeat while (numberToCheck ≠ 1)
if localCycle contains numberToCheck then
exit repeat
end if
set end of localCycle to numberToCheck
set tempNumber to 0
repeat while (numberToCheck > 0)
set digitOfNumber to numberToCheck mod 10
set tempNumber to tempNumber + (digitOfNumber ^ 2)
set numberToCheck to (numberToCheck - digitOfNumber) / 10
end repeat
set numberToCheck to tempNumber
end repeat
return (numberToCheck = 1)
end isHappy
Result: (*1, 7, 10, 13, 19, 23, 28, 31*)
Functional composition
---------------------- HAPPY NUMBERS -----------------------
-- isHappy :: Int -> Bool
on isHappy(n)
-- endsInOne :: [Int] -> Int -> Bool
script endsInOne
-- sumOfSquaredDigits :: Int -> Int
script sumOfSquaredDigits
-- digitSquared :: Int -> Int -> Int
script digitSquared
on |λ|(a, x)
(a + (x as integer) ^ 2) as integer
end |λ|
end script
on |λ|(n)
foldl(digitSquared, 0, splitOn("", n as string))
end |λ|
end script
-- [Int] -> Int -> Bool
on |λ|(s, n)
if n = 1 then
true
else
if s contains n then
false
else
|λ|(s & n, |λ|(n) of sumOfSquaredDigits)
end if
end if
end |λ|
end script
endsInOne's |λ|({}, n)
end isHappy
--------------------------- TEST ---------------------------
on run
-- seriesLength :: {n:Int, xs:[Int]} -> Bool
script seriesLength
property target : 8
on |λ|(rec)
length of xs of rec = target of seriesLength
end |λ|
end script
-- succTest :: {n:Int, xs:[Int]} -> {n:Int, xs:[Int]}
script succTest
on |λ|(rec)
tell rec to set {xs, n} to {its xs, its n}
script testResult
on |λ|(x)
if isHappy(x) then
xs & x
else
xs
end if
end |λ|
end script
{n:n + 1, xs:testResult's |λ|(n)}
end |λ|
end script
xs of |until|(seriesLength, succTest, {n:1, xs:{}})
--> {1, 7, 10, 13, 19, 23, 28, 31}
end run
-------------------- GENERIC FUNCTIONS ---------------------
-- foldl :: (a -> b -> a) -> a -> [b] -> a
on foldl(f, startValue, xs)
tell mReturn(f)
set v to startValue
set lng to length of xs
repeat with i from 1 to lng
set v to |λ|(v, item i of xs, i, xs)
end repeat
return v
end tell
end foldl
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then
f
else
script
property |λ| : f
end script
end if
end mReturn
-- splitOn :: String -> String -> [String]
on splitOn(pat, src)
set {dlm, my text item delimiters} to ¬
{my text item delimiters, pat}
set xs to text items of src
set my text item delimiters to dlm
return xs
end splitOn
-- until :: (a -> Bool) -> (a -> a) -> a -> a
on |until|(p, f, x)
set mp to mReturn(p)
set v to x
tell mReturn(f)
repeat until mp's |λ|(v)
set v to |λ|(v)
end repeat
end tell
return v
end |until|
- Output:
{1, 7, 10, 13, 19, 23, 28, 31}
Arturo
ord0: to :integer `0`
happy?: function [x][
n: x
past: new []
while [n <> 1][
s: to :string n
n: 0
loop s 'c [
i: (to :integer c) - ord0
n: n + i * i
]
if contains? past n -> return false
'past ++ n
]
return true
]
loop 0..31 'x [
if happy? x -> print x
]
- Output:
1 7 10 13 19 23 28 31
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)
}
The first 8 happy numbers are: 1,7,10,13,19,23,28,31
Alternative version
while h < 8
if (Happy(A_Index)) {
Out .= A_Index A_Space
h++
}
MsgBox, % Out
Happy(n) {
Loop, {
Loop, Parse, n
t += A_LoopField ** 2
if (t = 89)
return, 0
if (t = 1)
return, 1
n := t, t := 0
}
}
1 7 10 13 19 23 28 31
AutoIt
$c = 0
$k = 0
While $c < 8
$k += 1
$n = $k
While $n <> 1
$s = StringSplit($n, "")
$t = 0
For $i = 1 To $s[0]
$t += $s[$i] ^ 2
Next
$n = $t
Switch $n
Case 4,16,37,58,89,145,42,20
ExitLoop
EndSwitch
WEnd
If $n = 1 Then
ConsoleWrite($k & " is Happy" & @CRLF)
$c += 1
EndIf
WEnd
Use a set of numbers (4,16,37,58,89,145,42,20) to indicate a loop and exit. Output: 1 is Happy 7 is Happy 10 is Happy 13 is Happy 19 is Happy 23 is Happy 28 is Happy 31 is Happy
Alternative version
$c = 0
$k = 0
While $c < 8
$a = ObjCreate("System.Collections.ArrayList")
$k += 1
$n = $k
While $n <> 1
If $a.Contains($n) Then
ExitLoop
EndIf
$a.add($n)
$s = StringSplit($n, "")
$t = 0
For $i = 1 To $s[0]
$t += $s[$i] ^ 2
Next
$n = $t
WEnd
If $n = 1 Then
ConsoleWrite($k & " is Happy" & @CRLF)
$c += 1
EndIf
$a.Clear
WEnd
Saves all numbers in a list, duplicate entry indicates a loop. Output: 1 is Happy 7 is Happy 10 is Happy 13 is Happy 19 is Happy 23 is Happy 28 is Happy 31 is Happy
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
}
}
}
Result:
1 7 10 13 19 23 28 31
Alternative version
Alternately, for legibility one might write:
BEGIN {
for (i = 1; i < 50; ++i){
if (isHappy(i)) {
print i;
}
}
exit
}
function isHappy(n, seen) {
delete seen;
while (1) {
n = sumSqrDig(n)
if (seen[n]) {
return n == 1
}
seen[n] = 1
}
}
function sumSqrDig(n, d, tot) {
while (n) {
d = n % 10
tot += d * d
n = int(n/10)
}
return tot
}
BASIC
Applesoft BASIC
0 C = 8: DIM S(16):B = 10: PRINT "THE FIRST "C" HAPPY NUMBERS": FOR R = C TO 0 STEP 0:N = H: GOSUB 1: PRINT MID$ (" " + STR$ (H),1 + (R = C),255 * I);:R = R - I:H = H + 1: NEXT R: END
1 S = 0: GOSUB 3:I = N = 1: IF NOT Q THEN RETURN
2 FOR Q = 1 TO 0 STEP 0:S(S) = N:S = S + 1: GOSUB 6:N = T: GOSUB 3: NEXT Q:I = N = 1: RETURN
3 Q = N > 1: IF NOT Q OR NOT S THEN RETURN
4 Q = 0: FOR I = 0 TO S - 1: IF N = S(I) THEN RETURN
5 NEXT I:Q = 1: RETURN
6 T = 0: FOR I = N TO 0 STEP 0:M = INT (I / B):T = INT (T + (I - M * B) ^ 2):I = M: NEXT I: RETURN
- Output:
THE FIRST 8 HAPPY NUMBERS 1 7 10 13 19 23 28 31
BASIC256
n = 1 : cnt = 0
print "The first 8 isHappy numbers are:"
print
while cnt < 8
if isHappy(n) = 1 then
cnt += 1
print cnt; " => "; n
end if
n += 1
end while
function isHappy(num)
isHappy = 0
cont = 0
while cont < 50 and isHappy <> 1
num$ = string(num)
cont += 1
isHappy = 0
for i = 1 to length(num$)
isHappy += int(mid(num$,i,1)) ^ 2
next i
num = isHappy
end while
end function
BBC BASIC
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)
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
Commodore BASIC
The array sizes here are tuned to the minimum values required to find the first 8 happy numbers in numerical order. The H and U arrays are used for memoization, so the subscripts H(n) and U(n) must exist for the highest n encountered. The array N must have room to hold the longest chain examined in the course of determining whether a single number is happy, which thanks to the memoization is only ten elements long.
100 C=8:DIM H(145),U(145),N(9)
110 PRINT CHR$(147):PRINT "THE FIRST"C"HAPPY NUMBERS:":PRINT
120 H(1)=1:N=1
130 FOR C=C TO 0 STEP 0
140 : GOSUB 200
150 : IF H THEN PRINT N,:C=C-1
160 : N=N+1
170 NEXT C
180 PRINT
190 END
200 K=0:N(K)=N
210 IF H(N(K)) THEN H=1:FOR J=0 TO K:U(N(J))=0:H(N(J))=1:NEXT J:RETURN
220 IF U(N(K)) THEN H=0:RETURN
230 U(N(K))=1
240 N$=MID$(STR$(N(K)),2)
250 L=LEN(N$)
260 K=K+1:N(K)=0
270 FOR I=1 TO L
280 : D = VAL(MID$(N$,I,1))
290 : N(K) = N(K) + D * D
300 NEXT I
310 GOTO 210
- Output:
THE FIRST 8 HAPPY NUMBERS: 1 7 10 13 19 23 28 31 READY.
FreeBASIC
' FB 1.05.0 Win64
Function isHappy(n As Integer) As Boolean
If n < 0 Then Return False
' Declare a dynamic array to store previous sums.
' If a previous sum is duplicated before a sum of 1 is reached
' then the number can't be "happy" as the cycle will just repeat
Dim prevSums() As Integer
Dim As Integer digit, ub, sum = 0
Do
While n > 0
digit = n Mod 10
sum += digit * digit
n \= 10
Wend
If sum = 1 Then Return True
ub = UBound(prevSums)
If ub > -1 Then
For i As Integer = 0 To ub
If sum = prevSums(i) Then Return False
Next
End If
ub += 1
Redim Preserve prevSums(0 To ub)
prevSums(ub) = sum
n = sum
sum = 0
Loop
End Function
Dim As Integer n = 1, count = 0
Print "The first 8 happy numbers are : "
Print
While count < 8
If isHappy(n) Then
count += 1
Print count;" =>"; n
End If
n += 1
Wend
Print
Print "Press any key to quit"
Sleep
- Output:
1 => 1 2 => 7 3 => 10 4 => 13 5 => 19 6 => 23 7 => 28 8 => 31
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
Output:-
1 1 2 7 3 10 4 13 5 19 6 23 7 28 8 31
Locomotive Basic
10 mode 1:defint a-z
20 for i=1 to 100
30 i2=i
40 for l=1 to 20
50 a$=str$(i2)
60 i2=0
70 for j=1 to len(a$)
80 d=val(mid$(a$,j,1))
90 i2=i2+d*d
100 next j
110 if i2=1 then print i;"is a happy number":n=n+1:goto 150
120 if i2=4 then 150 ' cycle found
130 next l
140 ' check if we have reached 8 numbers yet
150 if n=8 then end
160 next i
PureBasic
#ToFind=8
#MaxTests=100
#True = 1: #False = 0
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
Sample output:
#1 1 #2 7 #3 10 #4 13 #5 19 #6 23 #7 28 #8 31
Run BASIC
for i = 1 to 100
if happy(i) = 1 then
cnt = cnt + 1
PRINT cnt;". ";i;" is a happy number "
if cnt = 8 then end
end if
next i
FUNCTION happy(num)
while count < 50 and happy <> 1
num$ = str$(num)
count = count + 1
happy = 0
for i = 1 to len(num$)
happy = happy + val(mid$(num$,i,1)) ^ 2
next i
num = happy
wend
end function
1. 1 is a happy number 2. 7 is a happy number 3. 10 is a happy number 4. 13 is a happy number 5. 19 is a happy number 6. 23 is a happy number 7. 28 is a happy number 8. 31 is a happy number
uBasic/4tH
' ************************
' MAIN
' ************************
PROC _PRINT_HAPPY(20)
END
' ************************
' END MAIN
' ************************
' ************************
' SUBS & FUNCTIONS
' ************************
' --------------------
_is_happy PARAM(1)
' --------------------
LOCAL (5)
f@ = 100
c@ = a@
b@ = 0
DO WHILE b@ < f@
e@ = 0
DO WHILE c@
d@ = c@ % 10
c@ = c@ / 10
e@ = e@ + (d@ * d@)
LOOP
UNTIL e@ = 1
c@ = e@
b@ = b@ + 1
LOOP
RETURN(b@ < f@)
' --------------------
_PRINT_HAPPY PARAM(1)
' --------------------
LOCAL (2)
b@ = 1
c@ = 0
DO
IF FUNC (_is_happy(b@)) THEN
c@ = c@ + 1
PRINT b@
ENDIF
b@ = b@ + 1
UNTIL c@ + 1 > a@
LOOP
RETURN
' ************************
' END SUBS & FUNCTIONS
' ************************
VBA
Option Explicit
Sub Test_Happy()
Dim i&, Cpt&
For i = 1 To 100
If Is_Happy_Number(i) Then
Debug.Print "Is Happy : " & i
Cpt = Cpt + 1
If Cpt = 8 Then Exit For
End If
Next
End Sub
Public Function Is_Happy_Number(ByVal N As Long) As Boolean
Dim i&, Number$, Cpt&
Is_Happy_Number = False 'default value
Do
Cpt = Cpt + 1 'Count Loops
Number = CStr(N) 'conversion Long To String to be able to use Len() function
N = 0
For i = 1 To Len(Number)
N = N + CInt(Mid(Number, i, 1)) ^ 2
Next i
'If Not N = 1 after 50 Loop ==> Number Is Not Happy
If Cpt = 50 Then Exit Function
Loop Until N = 1
Is_Happy_Number = True
End Function
- Output:
Is Happy : 1 Is Happy : 7 Is Happy : 10 Is Happy : 13 Is Happy : 19 Is Happy : 23 Is Happy : 28 Is Happy : 31
VBScript
count = 0
firsteigth=""
For i = 1 To 100
If IsHappy(CInt(i)) Then
firsteight = firsteight & i & ","
count = count + 1
End If
If count = 8 Then
Exit For
End If
Next
WScript.Echo firsteight
Function IsHappy(n)
IsHappy = False
m = 0
Do Until m = 60
sum = 0
For j = 1 To Len(n)
sum = sum + (Mid(n,j,1))^2
Next
If sum = 1 Then
IsHappy = True
Exit Do
Else
n = sum
m = m + 1
End If
Loop
End Function
- Output:
1,7,10,13,19,23,28,31,
Visual Basic .NET
This version uses Linq to carry out the calculations.
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
The output is:
1: 1 2: 7 3: 10 4: 13 5: 19 6: 23 7: 28 8: 31
Cacheless version
Curiously, this runs in about two thirds of the time of the cacheless C# version on Tio.run.
Module Module1
Dim sq As Integer() = {1, 4, 9, 16, 25, 36, 49, 64, 81}
Function isOne(x As Integer) As Boolean
While True
If x = 89 Then Return False
Dim t As Integer, s As Integer = 0
Do
t = (x Mod 10) - 1 : If t >= 0 Then s += sq(t)
x \= 10
Loop While x > 0
If s = 1 Then Return True
x = s
End While
Return False
End Function
Sub Main(ByVal args As String())
Const Max As Integer = 10_000_000
Dim st As DateTime = DateTime.Now
Console.Write("---Happy Numbers---" & vbLf & "The first 8:")
Dim i As Integer = 1, c As Integer = 0
While c < 8
If isOne(i) Then Console.Write("{0} {1}", If(c = 0, "", ","), i, c) : c += 1
i += 1
End While
Dim m As Integer = 10
While m <= Max
Console.Write(vbLf & "The {0:n0}th: ", m)
While c < m
If isOne(i) Then c += 1
i += 1
End While
Console.Write("{0:n0}", i - 1)
m = m * 10
End While
Console.WriteLine(vbLf & "Computation time {0} seconds.", (DateTime.Now - st).TotalSeconds)
End Sub
End Module
- Output:
---Happy Numbers--- The first 8: 1, 7, 10, 13, 19, 23, 28, 31 The 10th: 44 The 100th: 694 The 1,000th: 6,899 The 10,000th: 67,169 The 100,000th: 692,961 The 1,000,000th: 7,105,849 The 10,000,000th: 71,313,350 Computation time 19.235551 seconds.
ZX Spectrum Basic
10 FOR i=1 TO 100
20 GO SUB 1000
30 IF isHappy=1 THEN PRINT i;" is a happy number"
40 NEXT i
50 STOP
1000 REM Is Happy?
1010 LET isHappy=0: LET count=0: LET num=i
1020 IF count=50 OR isHappy=1 THEN RETURN
1030 LET n$=STR$ (num)
1040 LET count=count+1
1050 LET isHappy=0
1060 FOR j=1 TO LEN n$
1070 LET isHappy=isHappy+VAL n$(j)^2
1080 NEXT j
1090 LET num=isHappy
1100 GO TO 1020
Batch File
happy.bat
@echo off
setlocal enableDelayedExpansion
::Define a list with 10 terms as a convenience for defining a loop
set "L10=0 1 2 3 4 5 6 7 8 9"
shift /1 & goto %1
exit /b
:list min count
:: This routine prints all happy numbers > min (arg1)
:: until it finds count (arg2) happy numbers.
set /a "n=%~1, cnt=%~2"
call :listInternal
exit /b
:test min [max]
:: This routine sequentially tests numbers between min (arg1) and max (arg2)
:: to see if they are happy. If max is not specified then it defaults to min.
set /a "min=%~1"
if "%~2" neq "" (set /a "max=%~2") else set max=%min%
::The FOR /L loop does not detect integer overflow, so must protect against
::an infinite loop when max=0x7FFFFFFFF
set end=%max%
if %end% equ 2147483647 set /a end-=1
for /l %%N in (%min% 1 %end%) do (
call :testInternal %%N && (echo %%N is happy :^)) || echo %%N is sad :(
)
if %end% neq %max% call :testInternal %max% && (echo %max% is happy :^)) || echo %max% is sad :(
exit /b
:listInternal
:: This loop sequentially tests each number >= n. The loop conditionally
:: breaks within the body once cnt happy numbers have been found, or if
:: the max integer value is reached. Performance is improved by using a
:: FOR loop to perform most of the looping, with a GOTO only needed once
:: per 100 iterations.
for %%. in (
%L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10% %L10%
) do (
call :testInternal !n! && (
echo !n!
set /a cnt-=1
if !cnt! leq 0 exit /b 0
)
if !n! equ 2147483647 (
>&2 echo ERROR: Maximum integer value reached
exit /b 1
)
set /a n+=1
)
goto :listInternal
:testInternal n
:: This routine loops until the sum of squared digits converges on 1 (happy)
:: or it detects a cycle (sad). It exits with errorlevel 0 for happy and 1 for sad.
:: Performance is improved by using a FOR loop for the looping instead of a GOTO.
:: Numbers less than 1000 never neeed more than 20 iterations, and any number
:: with 4 or more digits shrinks by at least one digit each iteration.
:: Since Windows batch can't handle more than 10 digits, allowance for 27
:: iterations is enough, and 30 is more than adequate.
setlocal
set n=%1
for %%. in (%L10% %L10% %L10%) do (
if !n!==1 exit /b 0
%= Only numbers < 1000 can cycle =%
if !n! lss 1000 (
if defined t.!n! exit /b 1
set t.!n!=1
)
%= Sum the squared digits =%
%= Batch can't handle numbers greater than 10 digits so we can use =%
%= a constrained FOR loop and avoid a slow goto =%
set sum=0
for /l %%N in (1 1 10) do (
if !n! gtr 0 set /a "sum+=(n%%10)*(n%%10), n/=10"
)
set /a n=sum
)
Sample usage and output
>happy list 1 8 1 7 10 13 19 23 28 31 >happy list 1000000000 10 1000000000 1000000003 1000000009 1000000029 1000000030 1000000033 1000000039 1000000067 1000000076 1000000088 >happy test 30 30 is sad :( >happy test 31 31 is happy :) >happy test 1 10 1 is happy :) 2 is sad :( 3 is sad :( 4 is sad :( 5 is sad :( 6 is sad :( 7 is happy :) 8 is sad :( 9 is sad :( 10 is happy :) >happy test "50 + 10 * 5" 100 is happy :) >happy test 0x7fffffff 2147483647 is sad :( >happy test 0x7ffffffd 2147483645 is happy :) >happy list 0x7ffffff0 10 2147483632 2147483645 ERROR: Maximum integer value reached
BCPL
get "libhdr"
let sumdigitsq(n) =
n=0 -> 0, (n rem 10)*(n rem 10)+sumdigitsq(n/10)
let happy(n) = valof
$( let seen = vec 255
for i = 0 to 255 do i!seen := false
$( n!seen := true
n := sumdigitsq(n)
$) repeatuntil n!seen
resultis 1!seen
$)
let start() be
$( let n, i = 0, 0
while n < 8 do
$( if happy(i) do
$( n := n + 1
writef("%N ",i)
$)
i := i + 1
$)
wrch('*N')
$)
- Output:
1 7 10 13 19 23 28 31
Bori
bool isHappy (int n)
{
ints cache;
while (n != 1)
{
int sum = 0;
if (cache.contains(n))
return false;
cache.add(n);
while (n != 0)
{
int digit = n % 10;
sum += (digit * digit);
n = (int)(n / 10);
}
n = sum;
}
return true;
}
void test ()
{
int num = 1;
ints happynums;
while (happynums.count() < 8)
{
if (isHappy(num))
happynums.add(num);
num++;
}
puts("First 8 happy numbers : " + str.newline + happynums);
}
Output:
First 8 happy numbers : [1, 7, 10, 13, 19, 23, 28, 31]
BQN
SumSqDgt ← +´2⋆˜ •Fmt-'0'˙
Happy ← ⟨⟩{𝕨((⊑∊˜ )◶⟨∾𝕊(SumSqDgt⊢),1=⊢⟩)𝕩}⊢
8↑Happy¨⊸/↕50
- Output:
⟨ 1 7 10 13 19 23 28 31 ⟩
Brat
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}"
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
Recursively look up if digit square sum is happy.
#include <stdio.h>
#define CACHE 256
enum { h_unknown = 0, h_yes, h_no };
unsigned char buf[CACHE] = {0, h_yes, 0};
int happy(int n)
{
int sum = 0, x, nn;
if (n < CACHE) {
if (buf[n]) return 2 - buf[n];
buf[n] = h_no;
}
for (nn = n; nn; nn /= 10) x = nn % 10, sum += x * x;
x = happy(sum);
if (n < CACHE) buf[n] = 2 - x;
return x;
}
int main()
{
int i, cnt = 8;
for (i = 1; cnt || !printf("\n"); i++)
if (happy(i)) --cnt, printf("%d ", i);
printf("The %dth happy number: ", cnt = 1000000);
for (i = 1; cnt; i++)
if (happy(i)) --cnt || printf("%d\n", i);
return 0;
}
output
1 7 10 13 19 23 28 31 The 1000000th happy number: 7105849
Without caching, using cycle detection:
#include <stdio.h>
int dsum(int n)
{
int sum, x;
for (sum = 0; n; n /= 10) x = n % 10, sum += x * x;
return sum;
}
int happy(int n)
{
int nn;
while (n > 999) n = dsum(n); /* 4 digit numbers can't cycle */
nn = dsum(n);
while (nn != n && nn != 1)
n = dsum(n), nn = dsum(dsum(nn));
return n == 1;
}
int main()
{
int i, cnt = 8;
for (i = 1; cnt || !printf("\n"); i++)
if (happy(i)) --cnt, printf("%d ", i);
printf("The %dth happy number: ", cnt = 1000000);
for (i = 1; cnt; i++)
if (happy(i)) --cnt || printf("%d\n", i);
return 0;
}
Output is same as above, but much slower.
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
Alternate (cacheless)
Instead of caching and checking for being stuck in a loop, one can terminate on the "unhappy" endpoint of 89. One might be temped to try caching the so-far-found happy and unhappy numbers and checking the cache to speed things up. However, I have found that the cache implementation overhead reduces performance compared to this cacheless version.
Reaching 10 million, the <34 second computation time was from Tio.run. It takes under 5 seconds on a somewhat modern CPU. If you edit it to max out at 100 million, it takes about 50 seconds (on the somewhat modern CPU).
using System;
using System.Collections.Generic;
class Program
{
static int[] sq = { 1, 4, 9, 16, 25, 36, 49, 64, 81 };
static bool isOne(int x)
{
while (true)
{
if (x == 89) return false;
int s = 0, t;
do if ((t = (x % 10) - 1) >= 0) s += sq[t]; while ((x /= 10) > 0);
if (s == 1) return true;
x = s;
}
}
static void Main(string[] args)
{
const int Max = 10_000_000; DateTime st = DateTime.Now;
Console.Write("---Happy Numbers---\nThe first 8:");
int c = 0, i; for (i = 1; c < 8; i++)
if (isOne(i)) Console.Write("{0} {1}", c == 0 ? "" : ",", i, ++c);
for (int m = 10; m <= Max; m *= 10)
{
Console.Write("\nThe {0:n0}th: ", m);
for (; c < m; i++) if (isOne(i)) c++;
Console.Write("{0:n0}", i - 1);
}
Console.WriteLine("\nComputation time {0} seconds.", (DateTime.Now - st).TotalSeconds);
}
}
- Output:
---Happy Numbers--- The first 8: 1, 7, 10, 13, 19, 23, 28, 31 The 10th: 44 The 100th: 694 The 1,000th: 6,899 The 10,000th: 67,169 The 100,000th: 692,961 The 1,000,000th: 7,105,849 The 10,000,000th: 71,313,350 Computation time 33.264518 seconds.
C++
#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;
}
Output:
1 7 10 13 19 23 28 31 32 44 49
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;
}
Output:
1 7 10 13 19 23 28 31
Cycle detection in is_happy()
above is done using Floyd's cycle-finding algorithm.
Clojure
(defn happy? [n]
(loop [n n, seen #{}]
(cond
(= n 1) true
(seen n) false
:else
(recur (->> (str n)
(map #(Character/digit % 10))
(map #(* % %))
(reduce +))
(conj seen n)))))
(def happy-numbers (filter happy? (iterate inc 1)))
(println (take 8 happy-numbers))
Output:
(1 7 10 13 19 23 28 31)
Alternate Version (with caching)
(require '[clojure.set :refer [union]])
(def ^{:private true} cache {:happy (atom #{}) :sad (atom #{})})
(defn break-apart [n]
(->> (str n)
(map str)
(map #(Long/parseLong %))))
(defn next-number [n]
(->> (break-apart n)
(map #(* % %))
(apply +)))
(defn happy-or-sad? [prev n]
(cond (or (= n 1) ((deref (:happy cache)) n)) :happy
(or ((deref (:sad cache)) n) (some #(= % n) prev)) :sad
:else :unknown))
(defn happy-algo [n]
(let [get-next (fn [[prev n]] [(conj prev n) (next-number n)])
my-happy-or-sad? (fn [[prev n]] [(happy-or-sad? prev n) (conj prev n)])
unknown? (fn [[res nums]] (= res :unknown))
[res nums] (->> [#{} n]
(iterate get-next)
(map my-happy-or-sad?)
(drop-while unknown?)
first)
_ (swap! (res cache) union nums)]
res))
(def happy-numbers (->> (iterate inc 1)
(filter #(= :happy (happy-algo %)))))
(println (take 8 happy-numbers))
Same output.
CLU
sum_dig_sq = proc (n: int) returns (int)
sum_sq: int := 0
while n > 0 do
sum_sq := sum_sq + (n // 10) ** 2
n := n / 10
end
return (sum_sq)
end sum_dig_sq
is_happy = proc (n: int) returns (bool)
nn: int := sum_dig_sq(n)
while nn ~= n cand nn ~= 1 do
n := sum_dig_sq(n)
nn := sum_dig_sq(sum_dig_sq(nn))
end
return (nn = 1)
end is_happy
happy_numbers = iter (start, num: int) yields (int)
n: int := start
while num > 0 do
if is_happy(n) then
yield (n)
num := num-1
end
n := n+1
end
end happy_numbers
start_up = proc ()
po: stream := stream$primary_output()
for i: int in happy_numbers(1, 8) do
stream$putl(po, int$unparse(i))
end
end start_up
- Output:
1 7 10 13 19 23 28 31
COBOL
IDENTIFICATION DIVISION.
PROGRAM-ID. HAPPY.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 VARIABLES.
03 CANDIDATE PIC 9(4).
03 SQSUM-IN PIC 9(4).
03 FILLER REDEFINES SQSUM-IN.
05 DIGITS PIC 9 OCCURS 4 TIMES.
03 SQUARE PIC 9(4).
03 SUM-OF-SQUARES PIC 9(4).
03 N PIC 9.
03 TORTOISE PIC 9(4).
03 HARE PIC 9(4).
88 HAPPY VALUE 1.
03 SEEN PIC 9 VALUE ZERO.
03 OUT-FMT PIC ZZZ9.
PROCEDURE DIVISION.
BEGIN.
PERFORM DISPLAY-IF-HAPPY VARYING CANDIDATE FROM 1 BY 1
UNTIL SEEN IS EQUAL TO 8.
STOP RUN.
DISPLAY-IF-HAPPY.
PERFORM CHECK-HAPPY.
IF HAPPY,
MOVE CANDIDATE TO OUT-FMT,
DISPLAY OUT-FMT,
ADD 1 TO SEEN.
CHECK-HAPPY.
MOVE CANDIDATE TO TORTOISE, SQSUM-IN.
PERFORM CALC-SUM-OF-SQUARES.
MOVE SUM-OF-SQUARES TO HARE.
PERFORM CHECK-HAPPY-STEP UNTIL TORTOISE IS EQUAL TO HARE.
CHECK-HAPPY-STEP.
MOVE TORTOISE TO SQSUM-IN.
PERFORM CALC-SUM-OF-SQUARES.
MOVE SUM-OF-SQUARES TO TORTOISE.
MOVE HARE TO SQSUM-IN.
PERFORM CALC-SUM-OF-SQUARES.
MOVE SUM-OF-SQUARES TO SQSUM-IN.
PERFORM CALC-SUM-OF-SQUARES.
MOVE SUM-OF-SQUARES TO HARE.
CALC-SUM-OF-SQUARES.
MOVE ZERO TO SUM-OF-SQUARES.
PERFORM ADD-DIGIT-SQUARE VARYING N FROM 1 BY 1
UNTIL N IS GREATER THAN 4.
ADD-DIGIT-SQUARE.
MULTIPLY DIGITS(N) BY DIGITS(N) GIVING SQUARE.
ADD SQUARE TO SUM-OF-SQUARES.
- Output:
1 7 10 13 19 23 28 31
CoffeeScript
happy = (n) ->
seen = {}
while true
n = sum_digit_squares(n)
return true if n == 1
return false if seen[n]
seen[n] = true
sum_digit_squares = (n) ->
sum = 0
for c in n.toString()
d = parseInt(c)
sum += d*d
sum
i = 1
cnt = 0
while cnt < 8
if happy(i)
console.log i
cnt += 1
i += 1
output
> coffee happy.coffee 1 7 10 13 19 23 28 31
Common Lisp
(defun sqr (n)
(* n n))
(defun sum-of-sqr-dgts (n)
(loop for i = n then (floor i 10)
while (plusp i)
sum (sqr (mod i 10))))
(defun happy-p (n &optional cache)
(or (= n 1)
(unless (find n cache)
(happy-p (sum-of-sqr-dgts n)
(cons n cache)))))
(defun happys (&aux (happys 0))
(loop for i from 1
while (< happys 8)
when (happy-p i)
collect i and do (incf happys)))
(print (happys))
Output:
(1 7 10 13 19 23 28 31)
Cowgol
include "cowgol.coh";
sub sumDigitSquare(n: uint8): (s: uint8) is
s := 0;
while n != 0 loop
var d := n % 10;
s := s + d * d;
n := n / 10;
end loop;
end sub;
sub isHappy(n: uint8): (h: uint8) is
var seen: uint8[256];
MemZero(&seen[0], @bytesof seen);
while seen[n] == 0 loop
seen[n] := 1;
n := sumDigitSquare(n);
end loop;
if n == 1 then
h := 1;
else
h := 0;
end if;
end sub;
var n: uint8 := 1;
var seen: uint8 := 0;
while seen < 8 loop
if isHappy(n) != 0 then
print_i8(n);
print_nl();
seen := seen + 1;
end if;
n := n + 1;
end loop;
- Output:
1 7 10 13 19 23 28 31
Crystal
def happy?(n)
past = [] of Int32 | Int64
until n == 1
sum = 0; while n > 0; sum += (n % 10) ** 2; n //= 10 end
return false if past.includes? (n = sum)
past << n
end
true
end
i = count = 0
until count == 8; (puts i; count += 1) if happy?(i += 1) end
puts
(99999999999900..99999999999999).each { |i| puts i if happy?(i) }
- Output:
1 7 10 13 19 23 28 31 99999999999901 99999999999910 99999999999914 99999999999915 99999999999916 99999999999937 99999999999941 99999999999951 99999999999956 99999999999961 99999999999965 99999999999973
D
bool isHappy(int n) pure nothrow {
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() {
import std.stdio, std.algorithm, std.range;
int.max.iota.filter!isHappy.take(8).writeln;
}
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
Alternative Version
import std.stdio, std.algorithm, std.range, std.conv, std.string;
bool isHappy(int n) pure nothrow {
int[int] seen;
while (true) {
immutable t = n.text.representation.map!q{(a - '0') ^^ 2}.sum;
if (t == 1)
return true;
if (t in seen)
return false;
n = t;
seen[t] = 0;
}
}
void main() {
int.max.iota.filter!isHappy.take(8).writeln;
}
Same output.
Dart
main() {
HashMap<int,bool> happy=new HashMap<int,bool>();
happy[1]=true;
int count=0;
int i=0;
while(count<8) {
if(happy[i]==null) {
int j=i;
Set<int> sequence=new Set<int>();
while(happy[j]==null && !sequence.contains(j)) {
sequence.add(j);
int sum=0;
int val=j;
while(val>0) {
int digit=val%10;
sum+=digit*digit;
val=(val/10).toInt();
}
j=sum;
}
bool sequenceHappy=happy[j];
Iterator<int> it=sequence.iterator();
while(it.hasNext()) {
happy[it.next()]=sequenceHappy;
}
}
if(happy[i]) {
print(i);
count++;
}
i++;
}
}
dc
[lcI~rscd*+lc0<H]sH
[0rsclHxd4<h]sh
[lIp]s_
0sI[lI1+dsIlhx2>_z8>s]dssx
Output:
1 7 10 13 19 23 28 31
DCL
$ happy_1 = 1
$ found = 0
$ i = 1
$ loop1:
$ n = i
$ seen_list = ","
$ loop2:
$ if f$type( happy_'n ) .nes. "" then $ goto happy
$ if f$type( unhappy_'n ) .nes. "" then $ goto unhappy
$ if f$locate( "," + n + ",", seen_list ) .eq. f$length( seen_list )
$ then
$ seen_list = seen_list + f$string( n ) + ","
$ else
$ goto unhappy
$ endif
$ ns = f$string( n )
$ nl = f$length( ns )
$ j = 0
$ sumsq = 0
$ loop3:
$ digit = f$integer( f$extract( j, 1, ns ))
$ sumsq = sumsq + digit * digit
$ j = j + 1
$ if j .lt. nl then $ goto loop3
$ n = sumsq
$ goto loop2
$ unhappy:
$ j = 1
$ loop4:
$ x = f$element( j, ",", seen_list )
$ if x .eqs. "" then $ goto continue
$ unhappy_'x = 1
$ j = j + 1
$ goto loop4
$ happy:
$ found = found + 1
$ found_'found = i
$ if found .eq. 8 then $ goto done
$ j = 1
$ loop5:
$ x = f$element( j, ",", seen_list )
$ if x .eqs. "" then $ goto continue
$ happy_'x = 1
$ j = j + 1
$ goto loop5
$ continue:
$ i = i + 1
$ goto loop1
$ done:
$ show symbol found*
- Output:
FOUND = 8 Hex = 00000008 Octal = 00000000010 FOUND_1 = 1 Hex = 00000001 Octal = 00000000001 FOUND_2 = 7 Hex = 00000007 Octal = 00000000007 FOUND_3 = 10 Hex = 0000000A Octal = 00000000012 FOUND_4 = 13 Hex = 0000000D Octal = 00000000015 FOUND_5 = 19 Hex = 00000013 Octal = 00000000023 FOUND_6 = 23 Hex = 00000017 Octal = 00000000027 FOUND_7 = 28 Hex = 0000001C Octal = 00000000034 FOUND_8 = 31 Hex = 0000001F Octal = 00000000037
Delphi
Adaptation of #Pascal. The lib Boost.Int can be found here [1]
program Happy_numbers;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
Boost.Int;
type
TIntegerDynArray = TArray<Integer>;
TIntHelper = record helper for Integer
function IsHappy: Boolean;
procedure Next;
end;
{ TIntHelper }
function TIntHelper.IsHappy: Boolean;
var
cache: TIntegerDynArray;
sum, n: integer;
begin
n := self;
repeat
sum := 0;
while n > 0 do
begin
sum := sum + (n mod 10) * (n mod 10);
n := n div 10;
end;
if sum = 1 then
exit(True);
if cache.Has(sum) then
exit(False);
n := sum;
cache.Add(sum);
until false;
end;
procedure TIntHelper.Next;
begin
inc(self);
end;
var
count, n: integer;
begin
n := 1;
count := 0;
while count < 8 do
begin
if n.IsHappy then
begin
count.Next;
write(n, ' ');
end;
n.Next;
end;
writeln;
readln;
end.
- Output:
1 7 10 13 19 23 28 31
Draco
proc nonrec dsumsq(byte n) byte:
byte r, d;
r := 0;
while n~=0 do
d := n % 10;
n := n / 10;
r := r + d * d
od;
r
corp
proc nonrec happy(byte n) bool:
[256] bool seen;
byte i;
for i from 0 upto 255 do seen[i] := false od;
while not seen[n] do
seen[n] := true;
n := dsumsq(n)
od;
seen[1]
corp
proc nonrec main() void:
byte n, seen;
n := 1;
seen := 0;
while seen < 8 do
if happy(n) then
writeln(n:3);
seen := seen + 1
fi;
n := n + 1
od
corp
- Output:
1 7 10 13 19 23 28 31
DWScript
function IsHappy(n : Integer) : Boolean;
var
cache : array of Integer;
sum : Integer;
begin
while True do begin
sum := 0;
while n>0 do begin
sum += Sqr(n mod 10);
n := n div 10;
end;
if sum = 1 then
Exit(True);
if sum in cache then
Exit(False);
n := sum;
cache.Add(sum);
end;
end;
var n := 8;
var i : Integer;
while n>0 do begin
Inc(i);
if IsHappy(i) then begin
PrintLn(i);
Dec(n);
end;
end;
Output:
1 7 10 13 19 23 28 31
Dyalect
func happy(n) {
var m = []
while n > 1 {
m.Add(n)
var x = n
n = 0
while x > 0 {
var d = x % 10
n += d * d
x /= 10
}
if m.IndexOf(n) != -1 {
return false
}
}
return true
}
var (n, found) = (1, 0)
while found < 8 {
if happy(n) {
print("\(n) ", terminator: "")
found += 1
}
n += 1
}
print()
- Output:
1 7 10 13 19 23 28 31
Déjà Vu
next-num:
0
while over:
over
* dup % swap 10
+
swap floor / swap 10 swap
drop swap
is-happy happies n:
if has happies n:
return happies! n
local :seq set{ n }
n
while /= 1 dup:
next-num
if has seq dup:
drop
set-to happies n false
return false
if has happies dup:
set-to happies n dup happies!
return
set-to seq over true
drop
set-to happies n true
true
local :h {}
1 0
while > 8 over:
if is-happy h dup:
!print( "A happy number: " over )
swap ++ swap
++
drop
drop
- Output:
A happy number: 1 A happy number: 7 A happy number: 10 A happy number: 13 A happy number: 19 A happy number: 23 A happy number: 28 A happy number: 31
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 }
}
EasyLang
func dsum n .
while n > 0
d = n mod 10
s += d * d
n = n div 10
.
return s
.
func happy n .
while n > 999
n = dsum n
.
len seen[] 999
repeat
n = dsum n
until seen[n] = 1
seen[n] = 1
.
return if n = 1
.
while cnt < 8
n += 1
if happy n = 1
cnt += 1
write n & " "
.
.
- Output:
1 7 10 13 19 23 28 31
Eiffel
class
APPLICATION
create
make
feature {NONE} -- Initialization
make
-- Run application.
local
l_val: INTEGER
do
from
l_val := 1
until
l_val > 100
loop
if is_happy_number (l_val) then
print (l_val.out)
print ("%N")
end
l_val := l_val + 1
end
end
feature -- Happy number
is_happy_number (a_number: INTEGER): BOOLEAN
-- Is `a_number' a happy number?
require
positive_number: a_number > 0
local
l_number: INTEGER
l_set: ARRAYED_SET [INTEGER]
do
from
l_number := a_number
create l_set.make (10)
until
l_number = 1 or l_set.has (l_number)
loop
l_set.put (l_number)
l_number := square_sum_of_digits (l_number)
end
Result := (l_number = 1)
end
feature{NONE} -- Implementation
square_sum_of_digits (a_number: INTEGER): INTEGER
-- Sum of the sqares of digits of `a_number'.
require
positive_number: a_number > 0
local
l_number, l_digit: INTEGER
do
from
l_number := a_number
until
l_number = 0
loop
l_digit := l_number \\ 10
Result := Result + l_digit * l_digit
l_number := l_number // 10
end
end
end
Elena
ELENA 6.x :
import extensions;
import system'collections;
import system'routines;
isHappy(int n)
{
auto cache := new List<int>(5);
int sum := 0;
int num := n;
while (num != 1)
{
if (cache.indexOfElement(num) != -1)
{
^ false
};
cache.append(num);
while (num != 0)
{
int digit := num.mod(10);
sum += (digit*digit);
num /= 10
};
num := sum;
sum := 0
};
^ true
}
public program()
{
auto happynums := new List<int>(8);
int num := 1;
while (happynums.Length < 8)
{
if (isHappy(num))
{
happynums.append(num)
};
num += 1
};
console.printLine("First 8 happy numbers: ", happynums.asEnumerable())
}
- Output:
First 8 happy numbers: 1,7,10,13,19,23,28,31
Elixir
defmodule Happy do
def task(num) do
Process.put({:happy, 1}, true)
Stream.iterate(1, &(&1+1))
|> Stream.filter(fn n -> happy?(n) end)
|> Enum.take(num)
end
defp happy?(n) do
sum = square_sum(n, 0)
val = Process.get({:happy, sum})
if val == nil do
Process.put({:happy, sum}, false)
val = happy?(sum)
Process.put({:happy, sum}, val)
end
val
end
defp square_sum(0, sum), do: sum
defp square_sum(n, sum) do
r = rem(n, 10)
square_sum(div(n, 10), sum + r*r)
end
end
IO.inspect Happy.task(8)
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
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]
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):
-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.
Output:
[1,7,10,13,19,23,28,31]
Euphoria
function is_happy(integer n)
sequence seen
integer k
seen = {}
while n > 1 do
seen &= n
k = 0
while n > 0 do
k += power(remainder(n,10),2)
n = floor(n/10)
end while
n = k
if find(n,seen) then
return 0
end if
end while
return 1
end function
integer n,count
n = 1
count = 0
while count < 8 do
if is_happy(n) then
? n
count += 1
end if
n += 1
end while
Output:
1 7 10 13 19 23 28 31
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
|> Seq.iter (Printf.printf "%d\n") // Print results
Output:
1 7 10 13 19 23 28 31
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 ;
- Output:
8 happy-numbers ! { 1 7 10 13 19 23 28 31 }
FALSE
[$10/$10*@\-$*\]m: {modulo squared and division}
[$m;![$9>][m;!@@+\]#$*+]s: {sum of squares}
[$0[1ø1>][1ø3+ø3ø=|\1-\]#\%]f: {look for duplicates}
{check happy number}
[
$1[f;!~2ø1=~&][1+\s;!@]# {loop over sequence until 1 or duplicate}
1ø1= {return value}
\[$0=~][@%1-]#% {drop sequence and counter}
]h:
0 1
"Happy numbers:"
[1ø8=~][h;![" "$.\1+\]?1+]#
%%
- Output:
Happy numbers: 1 7 10 13 19 23 28 31
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
}
}
}
Output:
1 7 10 13 19 23 28 31
FOCAL
01.10 S J=0;S N=1;T %2
01.20 D 3;I (K-2)1.5
01.30 S N=N+1
01.40 I (J-8)1.2;Q
01.50 T N,!
01.60 S J=J+1
01.70 G 1.3
02.10 S A=K;S R=0
02.20 S B=FITR(A/10)
02.30 S R=R+(A-10*B)^2
02.40 S A=B
02.50 I (-A)2.2
03.10 F X=0,162;S S(X)=-1
03.20 S K=N
03.30 S S(K)=0
03.40 D 2;S K=R
03.50 I (S(K))3.3
- Output:
= 1 = 7 = 10 = 13 = 19 = 23 = 28 = 31
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
Lookup Table
Every sequence either ends in 1, or contains a 4 as part of a cycle. Extending the table through 9 is a (modest) optimization/memoization. This executes '500000 happy-numbers' about 5 times faster than the above solution.
CREATE HAPPINESS 0 C, 1 C, 0 C, 0 C, 0 C, 0 C, 0 C, 1 C, 0 C, 0 C,
: next ( n -- n')
0 swap BEGIN dup WHILE 10 /mod >r dup * + r> REPEAT drop ;
: happy? ( n -- t|f)
BEGIN dup 10 >= WHILE next REPEAT chars HAPPINESS + C@ 0<> ;
: happy-numbers ( n --) >r 0
BEGIN r@ WHILE
BEGIN 1+ dup happy? UNTIL dup . r> 1- >r
REPEAT r> drop drop ;
8 happy-numbers
- Output:
1 7 10 13 19 23 28 31
Produces the 1 millionth happy number with:
: happy-number ( n -- n') \ produce the nth happy number
>r 0 BEGIN r@ WHILE
BEGIN 1+ dup happy? UNTIL r> 1- >r
REPEAT r> drop ;
1000000 happy-number . \ 7105849
in about 9 seconds.
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
Frege
module Happy where
import Prelude.Math
-- ugh, since Frege doesn't have Set, use Map instead
import Data.Map (member, insertMin, empty emptyMap)
digitToInteger :: Char -> Integer
digitToInteger c = fromInt $ (ord c) - (ord '0')
isHappy :: Integer -> Bool
isHappy = p emptyMap
where p _ 1n = true
p s n | n `member` s = false
| otherwise = p (insertMin n () s) (f n)
f = sum . map (sqr . digitToInteger) . unpacked . show
main _ = putStrLn $ unwords $ map show $ take 8 $ filter isHappy $ iterate (+ 1n) 1n
- Output:
1 7 10 13 19 23 28 31 runtime 0.614 wallclock seconds.
FutureBasic
include "NSLog.incl"
local fn IsHappy( num as NSUInteger ) as NSUInteger
NSUInteger i, happy = 0, count = 0
while ( count < 50 ) and ( happy != 1 )
CFStringRef numStr = str( num )
count++ : happy = 0
for i = 1 to len( numStr )
happy = happy + fn StringIntegerValue( mid( numStr, i, 1 ) ) ^ 2
next
num = happy
wend
end fn = num
void local fn HappyNumbers
NSUInteger i, count = 0
for i = 1 to 100
if ( fn IsHappy(i) == 1 )
count++
NSLog( @"%2lu. %2lu is a happy number", count, i )
if count == 8 then exit fn
end if
next
end fn
fn HappyNumbers
HandleEvents
- Output:
1. 1 is a happy number 2. 7 is a happy number 3. 10 is a happy number 4. 13 is a happy number 5. 19 is a happy number 6. 23 is a happy number 7. 28 is a happy number 8. 31 is a happy number
Fōrmulæ
Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text. Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for storage and transfer purposes more than visualization and edition.
Programs in Fōrmulæ are created/edited online in its website.
In this page you can see and run the program(s) related to this task and their results. You can also change either the programs or the parameters they are called with, for experimentation, but remember that these programs were created with the main purpose of showing a clear solution of the task, and they generally lack any kind of validation.
Solution.
The following function returns whether a given number is happy or not:
Retrieving the first 8 happy numbers
Go
package main
import "fmt"
func happy(n int) bool {
m := make(map[int]bool)
for n > 1 {
m[n] = true
var x int
for x, n = n, 0; x > 0; x /= 10 {
d := x % 10
n += d * d
}
if m[n] {
return false
}
}
return true
}
func main() {
for found, n := 0, 1; found < 8; n++ {
if happy(n) {
fmt.Print(n, " ")
found++
}
}
fmt.Println()
}
- Output:
1 7 10 13 19 23 28 31
Groovy
Number.metaClass.isHappy = {
def number = delegate as Long
def cycle = new HashSet<Long>()
while (number != 1 && !cycle.contains(number)) {
cycle << number
number = (number as String).collect { d = (it as Long); d * d }.sum()
}
number == 1
}
def matches = []
for (int i = 0; matches.size() < 8; i++) {
if (i.happy) { matches << i }
}
println matches
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
Harbour
PROCEDURE Main()
LOCAL i := 8, nH := 0
? hb_StrFormat( "The first %d happy numbers are:", i )
?
WHILE i > 0
IF IsHappy( ++nH )
?? hb_NtoS( nH ) + " "
--i
ENDIF
END
RETURN
STATIC FUNCTION IsHappy( nNumber )
STATIC aUnhappy := {}
LOCAL nDigit, nSum := 0, cNumber := hb_NtoS( nNumber )
FOR EACH nDigit IN cNumber
nSum += Val( nDigit ) ^ 2
NEXT
IF nSum == 1
aUnhappy := {}
RETURN .T.
ELSEIF AScan( aUnhappy, nSum ) > 0
RETURN .F.
ENDIF
AAdd( aUnhappy, nSum )
RETURN IsHappy( nSum )
Output:
The first 8 happy numbers are: 1 7 10 13 19 23 28 31
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 . fmap ((^ 2) . toInteger . digitToInt) . show
main :: IO ()
main = mapM_ print $ take 8 $ filter isHappy [1 ..]
- Output:
1 7 10 13 19 23 28 31
We can create a cache for small numbers to greatly speed up the process:
import Data.Array (Array, (!), listArray)
happy :: Int -> Bool
happy x
| xx <= 150 = seen ! xx
| otherwise = happy xx
where
xx = dsum x
seen :: Array Int Bool
seen =
listArray (1, 150) $ True : False : False : False : (happy <$> [5 .. 150])
dsum n
| n < 10 = n * n
| otherwise =
let (q, r) = n `divMod` 10
in r * r + dsum q
main :: IO ()
main = print $ sum $ take 10000 $ filter happy [1 ..]
- Output:
327604323
Icon and Unicon
Usage and Output:
| happynum.exe The first 8 happy numbers are: 1 7 10 13 19 23 28 31
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
Java
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++;
}
}
}
}
Output:
1 7 10 13 19 23 28 31
Java 1.8
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
public class HappyNumbers {
public static void main(String[] args) {
for (int current = 1, total = 0; total < 8; current++)
if (isHappy(current)) {
System.out.println(current);
total++;
}
}
public static boolean isHappy(int number) {
HashSet<Integer> cycle = new HashSet<>();
while (number != 1 && cycle.add(number)) {
List<String> numStrList = Arrays.asList(String.valueOf(number).split(""));
number = numStrList.stream().map(i -> Math.pow(Integer.parseInt(i), 2)).mapToInt(i -> i.intValue()).sum();
}
return number == 1;
}
}
Output:
1 7 10 13 19 23 28 31
JavaScript
ES5
Iteration
function happy(number) {
var m, digit ;
var cycle = [] ;
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++ ;
}
Output:
1 7 10 13 19 23 28 31
ES6
Functional composition
(() => {
// isHappy :: Int -> Bool
const isHappy = n => {
const f = n =>
foldl(
(a, x) => a + raise(read(x), 2), // ^2
0,
splitOn('', show(n))
),
p = (s, n) => n === 1 ? (
true
) : member(n, s) ? (
false
) : p(
insert(n, s), f(n)
);
return p(new Set(), n);
};
// GENERIC FUNCTIONS ------------------------------------------------------
// enumFromTo :: Int -> Int -> [Int]
const enumFromTo = (m, n) =>
Array.from({
length: Math.floor(n - m) + 1
}, (_, i) => m + i);
// filter :: (a -> Bool) -> [a] -> [a]
const filter = (f, xs) => xs.filter(f);
// foldl :: (b -> a -> b) -> b -> [a] -> b
const foldl = (f, a, xs) => xs.reduce(f, a);
// insert :: Ord a => a -> Set a -> Set a
const insert = (e, s) => s.add(e);
// member :: Ord a => a -> Set a -> Bool
const member = (e, s) => s.has(e);
// read :: Read a => String -> a
const read = JSON.parse;
// show :: a -> String
const show = x => JSON.stringify(x);
// splitOn :: String -> String -> [String]
const splitOn = (cs, xs) => xs.split(cs);
// raise :: Num -> Int -> Num
const raise = (n, e) => Math.pow(n, e);
// take :: Int -> [a] -> [a]
const take = (n, xs) => xs.slice(0, n);
// TEST -------------------------------------------------------------------
return show(
take(8, filter(isHappy, enumFromTo(1, 50)))
);
})()
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
Or, to stop immediately at the 8th member of the series, we can preserve functional composition while using an iteratively implemented until() function:
(() => {
// isHappy :: Int -> Bool
const isHappy = n => {
const f = n =>
foldl(
(a, x) => a + raise(read(x), 2), // ^2
0,
splitOn('', show(n))
),
p = (s, n) => n === 1 ? (
true
) : member(n, s) ? (
false
) : p(
insert(n, s), f(n)
);
return p(new Set(), n);
};
// GENERIC FUNCTIONS ------------------------------------------------------
// filter :: (a -> Bool) -> [a] -> [a]
const filter = (f, xs) => xs.filter(f);
// foldl :: (b -> a -> b) -> b -> [a] -> b
const foldl = (f, a, xs) => xs.reduce(f, a);
// insert :: Ord a => a -> Set a -> Set a
const insert = (e, s) => s.add(e);
// member :: Ord a => a -> Set a -> Bool
const member = (e, s) => s.has(e);
// read :: Read a => String -> a
const read = JSON.parse;
// show :: a -> String
const show = x => JSON.stringify(x);
// splitOn :: String -> String -> [String]
const splitOn = (cs, xs) => xs.split(cs);
// raise :: Num -> Int -> Num
const raise = (n, e) => Math.pow(n, e);
// until :: (a -> Bool) -> (a -> a) -> a -> a
const until = (p, f, x) => {
let v = x;
while (!p(v)) v = f(v);
return v;
};
// TEST -------------------------------------------------------------------
return show(
until(
m => m.xs.length === 8,
m => {
const n = m.n;
return {
n: n + 1,
xs: isHappy(n) ? m.xs.concat(n) : m.xs
};
}, {
n: 1,
xs: []
}
)
.xs
);
})();
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
jq
def is_happy_number:
def next: tostring | explode | map( (. - 48) | .*.) | add;
def last(g): reduce g as $i (null; $i);
# state: either 1 or [i, o]
# where o is an an object with the previously encountered numbers as keys
def loop:
recurse( if . == 1 then empty # all done
elif .[0] == 1 then 1 # emit 1
else (.[0]| next) as $n
| if $n == 1 then 1
elif .[1]|has($n|tostring) then empty
else [$n, (.[1] + {($n|tostring):true}) ]
end
end );
1 == last( [.,{}] | loop );
Emit a stream of the first n happy numbers:
# Set n to -1 to continue indefinitely:
def happy(n):
def subtask: # state: [i, found]
if .[1] == n then empty
else .[0] as $n
| if ($n | is_happy_number) then $n, ([ $n+1, .[1]+1 ] | subtask)
else (.[0] += 1) | subtask
end
end;
[0,0] | subtask;
happy($n|tonumber)
- Output:
$ jq --arg n 8 -n -f happy.jq
1
7
10
13
19
23
28
31
Julia
function happy(x)
happy_ints = Int[]
int_try = 1
while length(happy_ints) < x
n = int_try
past = Int[]
while n != 1
n = sum(y^2 for y in digits(n))
n in past && break
push!(past, n)
end
n == 1 && push!(happy_ints,int_try)
int_try += 1
end
return happy_ints
end
Output
julia> happy(8) 8-element Int32 Array: 1 7 10 13 19 23 28 31
A recursive version:
sumhappy(n) = sum(x->x^2, digits(n))
function ishappy(x, mem = Int[])
x == 1 ? true :
x in mem ? false :
ishappy(sumhappy(x), [mem ; x])
end
nexthappy(x) = ishappy(x+1) ? x+1 : nexthappy(x+1)
happy(n) = accumulate((a, b) -> nexthappy(a), 1:n)
- Output:
julia> show(happy(8)) [1,7,10,13,19,23,28,31,32]
Alternate, Translation of C
Faster with use of cache
const CACHE = 256
buf = zeros(Int, CACHE)
buf[begin] = 1
function happy(n)
if n < CACHE
buf[n] > 0 && return 2-buf[n]
buf[n] = 2
end
sqsum = 0
nn = n
while nn != 0
nn, x = divrem(nn, 10)
sqsum += x * x
end
x = happy(sqsum)
n < CACHE && (buf[n] = 2 - x)
return x
end
function main()
i, counter = 1, 1000000
while counter > 0
if happy(i) != 0
counter -= 1
end
i += 1
end
return i - 1
end
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
Another implementation which is easy to follow is given below:
/ happynum.k
/ sum of squares of digits of an integer
dgtsmsqr: {d::(); (0<){d::d,x!10; x%:10}/x; +/d*d}
/ Test if an integer is a Happy number
isHappy: {s::(); while[1<x;a:(dgtsmsqr x); :[(a _in s); :0; s::s,a]; x:a];:1} / Returns 1 if Happy
/ Generate first x Happy numbers and display the list
hnum: {[x]; h::();i:1;while[(#h)<x; :[(isHappy i); h::(h,i)]; i+:1]; `0: ,"List of ", ($x), " Happy Numbers"; h}
The output of a session with this implementation is given below:
- Output:
K Console - Enter \ for help \l happynum hnum 8 List of 8 Happy Numbers 1 7 10 13 19 23 28 31
Kotlin
// version 1.0.5-2
fun isHappy(n: Int): Boolean {
val cache = mutableListOf<Int>()
var sum = 0
var nn = n
var digit: Int
while (nn != 1) {
if (nn in cache) return false
cache.add(nn)
while (nn != 0) {
digit = nn % 10
sum += digit * digit
nn /= 10
}
nn = sum
sum = 0
}
return true
}
fun main(args: Array<String>) {
var num = 1
val happyNums = mutableListOf<Int>()
while (happyNums.size < 8) {
if (isHappy(num)) happyNums.add(num)
num++
}
println("First 8 happy numbers : " + happyNums.joinToString(", "))
}
- Output:
First 8 happy numbers : 1, 7, 10, 13, 19, 23, 28, 31
Lambdatalk
{def happy
{def happy.sum
{lambda {:n}
{if {= {W.length :n} 1}
then {pow {W.first :n} 2}
else {+ {pow {W.first :n} 2}
{happy.sum {W.rest :n}}}}}}
{def happy.is
{lambda {:x :a}
{if {= :x 1}
then true
else {if {> {A.in? :x :a} -1}
then false
else {happy.is {happy.sum :x}
{A.addlast! :x :a}}}}}}
{def happy.rec
{lambda {:n :a :i}
{if {= {A.length :a} :n}
then :a
else {happy.rec :n
{if {happy.is :i {A.new}}
then {A.addlast! :i :a}
else :a}
{+ :i 1}}}}}
{lambda {:n}
{happy.rec :n {A.new} 0}}}
-> happy
{happy 8}
-> [1,7,10,13,19,23,28,31]
Lasso
#!/usr/bin/lasso9
define isHappy(n::integer) => {
local(past = set)
while(#n != 1) => {
#n = with i in string(#n)->values sum math_pow(integer(#i), 2)
#past->contains(#n) ? return false | #past->insert(#n)
}
return true
}
with x in generateSeries(1, 500)
where isHappy(#x)
take 8
select #x
Output:
1, 7, 10, 13, 19, 23, 28, 31
Logo
to sum_of_square_digits :number
output (apply "sum (map [[d] d*d] ` :number))
end
to is_happy? :number [:seen []]
output cond [
[ [:number = 1] "true ]
[ [member? :number :seen] "false ]
[ else (is_happy? (sum_of_square_digits :number) (lput :number :seen))]
]
end
to n_happy :count [:start 1] [:result []]
output cond [
[ [:count <= 0] :result ]
[ [is_happy? :start]
(n_happy (:count-1) (:start+1) (lput :start :result)) ]
[ else
(n_happy :count (:start+1) :result) ]
]
end
print n_happy 8
bye
Output:
1 7 10 13 19 23 28 31
LOLCODE
OBTW
Happy Numbers Rosetta Code task in LOLCODE
Requires 1.3 for BUKKIT availability
TLDR
HAI 1.3
CAN HAS STDIO?
BTW Simple list implementation.
BTW Used for the list of numbers already seen in IZHAPPY
BTW Create a list
HOW IZ I MAEKLIST
I HAS A LIST ITZ A BUKKIT
LIST HAS A LENGTH ITZ 0
FOUND YR LIST
IF U SAY SO
BTW Append an item to list
HOW IZ I PUTIN YR LIST AN YR ITEM
LIST HAS A SRS LIST'Z LENGTH ITZ ITEM
LIST'Z LENGTH R SUM OF LIST'Z LENGTH AN 1
IF U SAY SO
BTW Check for presence of an item in the list
HOW IZ I DUZLISTHAS YR HAYSTACK AN YR NEEDLE
IM IN YR BARN UPPIN YR INDEX WILE DIFFRINT INDEX AN HAYSTACK'Z LENGTH
I HAS A ITEM ITZ HAYSTACK'Z SRS INDEX
BOTH SAEM ITEM AN NEEDLE
O RLY?
YA RLY
FOUND YR WIN
OIC
IM OUTTA YR BARN
FOUND YR FAIL
IF U SAY SO
BTW Calculate the next number using the happy formula
HOW IZ I HAPPYSTEP YR NUM
I HAS A NEXT ITZ 0
IM IN YR LOOP
BOTH SAEM NUM AN 0
O RLY?
YA RLY
GTFO
OIC
I HAS A DIGIT ITZ MOD OF NUM AN 10
NUM R QUOSHUNT OF NUM AN 10
I HAS A SQUARE ITZ PRODUKT OF DIGIT AN DIGIT
NEXT R SUM OF NEXT AN SQUARE
IM OUTTA YR LOOP
FOUND YR NEXT
IF U SAY SO
BTW Check to see if a number is happy
HOW IZ I IZHAPPY YR NUM
I HAS A SEENIT ITZ I IZ MAEKLIST MKAY
IM IN YR LOOP
BOTH SAEM NUM AN 1
O RLY?
YA RLY
FOUND YR WIN
OIC
I IZ DUZLISTHAS YR SEENIT AN YR NUM MKAY
O RLY?
YA RLY
FOUND YR FAIL
OIC
I IZ PUTIN YR SEENIT AN YR NUM MKAY
NUM R I IZ HAPPYSTEP YR NUM MKAY
IM OUTTA YR LOOP
IF U SAY SO
BTW Print out the first 8 happy numbers
I HAS A KOUNT ITZ 0
IM IN YR LOOP UPPIN YR NUM WILE DIFFRINT KOUNT AN 8
I IZ IZHAPPY YR NUM MKAY
O RLY?
YA RLY
KOUNT R SUM OF KOUNT AN 1
VISIBLE NUM
OIC
IM OUTTA YR LOOP
KTHXBYE
Output:
1 7 10 13 19 23 28 31
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
Output:
1 7 10 13 19 23 28 31
M2000 Interpreter
Lambda Function PrintHappy has a closure another lambda function IsHappy which has a closure of another lambda function the sumOfSquares.
Function FactoryHappy {
sumOfSquares= lambda (n) ->{
k$=str$(abs(n),"")
Sum=0
For i=1 to len(k$)
sum+=val(mid$(k$,i,1))**2
Next i
=sum
}
IsHappy=Lambda sumOfSquares (n) ->{
Inventory sequence
While n<>1 {
Append sequence, n
n=sumOfSquares(n)
if exist(sequence, n) then =false : Break
}
=True
}
=Lambda IsHappy ->{
numleft=8
numToTest=1
While numleft {
if ishappy(numToTest) Then {
Print numToTest
numleft--
}
numToTest++
}
}
}
PrintHappy=factoryHappy()
Call PrintHappy()
- Output:
1 7 10 13 19 23 28 31
MACRO-11
.TITLE HAPPY
.MCALL .TTYOUT,.EXIT
HAPPY:: MOV #^D8,R5 ; 8 HAPPY NUMBERS
CLR R4
1$: INC R4
MOV R4,R0
JSR PC,CHECK
BNE 1$
MOV R4,R0
JSR PC,PR0
SOB R5,1$
.EXIT
; CHECK IF R0 IS HAPPY: ZERO FLAG SET IF TRUE
CHECK: MOV #200,R1
MOV #3$,R2
1$: CLR (R2)+
SOB R1,1$
2$: INCB 3$(R0)
JSR PC,SUMSQ
TST 3$(R0)
BEQ 2$
DEC R0
RTS PC
3$: .BLKW 200
; LET R0 = SUM OF SQUARES OF DIGITS OF R0
SUMSQ: CLR R2
1$: MOV #-1,R1
2$: INC R1
SUB #12,R0
BCC 2$
ADD #12,R0
MOVB 3$(R0),R0
ADD R0,R2
MOV R1,R0
BNE 1$
MOV R2,R0
RTS PC
3$: .BYTE ^D 0,^D 1,^D 4,^D 9,^D16
.BYTE ^D25,^D36,^D49,^D64,^D81
; PRINT NUMBER IN R0 AS DECIMAL.
PR0: MOV #4$,R1
1$: MOV #-1,R2
2$: INC R2
SUB #12,R0
BCC 2$
ADD #72,R0
MOVB R0,-(R1)
MOV R2,R0
BNE 1$
3$: MOVB (R1)+,R0
.TTYOUT
BNE 3$
RTS PC
.ASCII /...../
4$: .BYTE 15,12,0
.END HAPPY
- Output:
1 7 10 13 19 23 28 31
MAD
NORMAL MODE IS INTEGER
BOOLEAN CYCLE
DIMENSION CYCLE(200)
VECTOR VALUES OUTFMT = $I2*$
SEEN = 0
I = 0
NEXNUM THROUGH ZERO, FOR K=0, 1, K.G.200
ZERO CYCLE(K) = 0B
I = I + 1
SUMSQR = I
CHKLP N = SUMSQR
SUMSQR = 0
SUMLP DIG = N-N/10*10
SUMSQR = SUMSQR + DIG*DIG
N = N/10
WHENEVER N.NE.0, TRANSFER TO SUMLP
WHENEVER SUMSQR.E.1, TRANSFER TO HAPPY
WHENEVER CYCLE(SUMSQR), TRANSFER TO NEXNUM
CYCLE(SUMSQR) = 1B
TRANSFER TO CHKLP
HAPPY PRINT FORMAT OUTFMT,I
SEEN = SEEN+1
WHENEVER SEEN.L.8, TRANSFER TO NEXNUM
END OF PROGRAM
- Output:
1 7 10 13 19 23 28 31
Maple
To begin, here is a procedure to compute the sum of the squares of the digits of a positive integer. It uses the built-in procedure irem, which computes the integer remainder and, if passed a name as the optional third argument, assigns it the corresponding quotient. (In other words, it performs integer division with remainder. There is also a dual, companion procedure iquo, which returns the integer quotient and assigns the remainder to the (optional) third argument.)
SumSqDigits := proc( n :: posint )
local s := 0;
local m := n;
while m <> 0 do
s := s + irem( m, 10, 'm' )^2
end do;
s
end proc:
(Note that the unevaluation quotes on the third argument to irem are essential here, as that argument must be a name and, if m were passed without quotes, it would evaluate to a number.)
For example,
> SumSqDigits( 1234567890987654321 );
570
We can check this by computing it another way (more directly).
> n := 1234567890987654321:
> `+`( op( map( parse, StringTools:-Explode( convert( n, 'string' ) ) )^~2) );
570
The most straight-forward way to check whether a number is happy or sad seems also to be the fastest (that I could think of).
Happy? := proc( n )
if n = 1 then
true
elif n = 4 then
false
else
local s := SumSqDigits( n );
while not ( s in { 1, 4 } ) do
s := SumSqDigits( s )
end do;
evalb( s = 1 )
end if
end proc:
We can use this to determine the number of happy (H) and sad (S) numbers up to one million as follows.
> H, S := selectremove( Happy?, [seq]( 1 .. N ) ):
> nops( H ), nops( S );
143071, 856929
Finally, to solve the stated problem, here is a completely straight-forward routine to locate the first N happy numbers, returning them in a set.
FindHappiness := proc( N )
local count := 0;
local T := table();
for local i while count < N do
if Happy?( i ) then
count := 1 + count;
T[ count ] := i
end if
end do;
{seq}( T[ i ], i = 1 .. count )
end proc:
With input equal to 8, we get
> FindHappiness( 8 );
{1, 7, 10, 13, 19, 23, 28, 31}
For completeness, here is an implementation of the cycle detection algorithm for recognizing happy numbers. It is much slower, however.
Happy? := proc( n :: posint )
local a, b;
a, b := n, SumSqDigits( n );
while a <> b do
a := SumSqDigits( a );
b := (SumSqDigits@@2)( b )
end do;
evalb( a = 1 )
end proc:
Mathematica / Wolfram Language
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}
MATLAB
Recursive version:
function findHappyNumbers
nHappy = 0;
k = 1;
while nHappy < 8
if isHappyNumber(k, [])
fprintf('%d ', k)
nHappy = nHappy+1;
end
k = k+1;
end
fprintf('\n')
end
function hap = isHappyNumber(k, prev)
if k == 1
hap = true;
elseif ismember(k, prev)
hap = false;
else
hap = isHappyNumber(sum((sprintf('%d', k)-'0').^2), [prev k]);
end
end
- Output:
1 7 10 13 19 23 28 31
Maxima
/* Function that decomposes te number into a list */
decompose(N) := block(
digits: [],
while N > 0 do
(remainder: mod(N, 10),
digits: cons(remainder, digits),
N: floor(N/10)),
digits
)$
/* Function that given a number returns the sum of their digits */
sum_squares_digits(n):=block(
decompose(n),
map(lambda([x],x^2),%%),
apply("+",%%))$
/* Predicate function based on the task iterated digits squaring */
happyp(n):=if n=1 then true else if n=89 then false else block(iter:n,while not member(iter,[1,89]) do iter:sum_squares_digits(iter),iter,if iter=1 then true)$
/* Test case */
/* First eight happy numbers */
block(
happy:[],i:1,
while length(happy)<8 do (if happyp(i) then happy:endcons(i,happy),i:i+1),
happy);
- Output:
[1,7,10,13,19,23,28,31]
MAXScript
fn isHappyNumber n =
(
local pastNumbers = #()
while n != 1 do
(
n = n as string
local newNumber = 0
for i = 1 to n.count do
(
local digit = n[i] as integer
newNumber += pow digit 2
)
n = newNumber
if (finditem pastNumbers n) != 0 do return false
append pastNumbers newNumber
)
n == 1
)
printed = 0
for i in (for h in 1 to 500 where isHappyNumber h collect h) do
(
if printed == 8 do exit
print i as string
printed += 1
)
Output:
1
7
10
13
19
23
28
31
Mercury
:- module happy.
:- interface.
:- import_module io.
:- pred main(io::di, io::uo) is det.
:- implementation.
:- import_module int, list, set_tree234.
main(!IO) :-
print_line(get_n_happy_numbers(8, 1), !IO).
:- func get_n_happy_numbers(int, int) = list(int).
get_n_happy_numbers(NumToFind, N) =
( if NumToFind > 0 then
( if is_happy(N, init)
then [N | get_n_happy_numbers(NumToFind - 1, N + 1)]
else get_n_happy_numbers(NumToFind, N + 1)
)
else
[]
).
:- pred is_happy(int::in, set_tree234(int)::in) is semidet.
is_happy(1, _).
is_happy(N, !.Seen) :-
not member(N, !.Seen),
insert(N, !Seen),
is_happy(sum_sqr_digits(N), !.Seen).
:- func sum_sqr_digits(int) = int.
sum_sqr_digits(N) =
( if N < 10 then sqr(N) else sqr(N mod 10) + sum_sqr_digits(N div 10) ).
:- func sqr(int) = int.
sqr(X) = X * X.
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
MiniScript
This solution uses the observation that any infinite cycle of this algorithm hits the number 89, and so that can be used to know when we've found an unhappy number.
isHappy = function(x)
while true
if x == 89 then return false
sum = 0
while x > 0
sum = sum + (x % 10)^2
x = floor(x / 10)
end while
if sum == 1 then return true
x = sum
end while
end function
found = []
i = 1
while found.len < 8
if isHappy(i) then found.push i
i = i + 1
end while
print "First 8 happy numbers: " + found
- Output:
First 8 happy numbers: [1, 7, 10, 13, 19, 23, 28, 31]
Miranda
main :: [sys_message]
main = [Stdout (lay (map show (take 8 happynumbers)))]
happynumbers :: [num]
happynumbers = filter ishappy [1..]
ishappy :: num->bool
ishappy n = 1 $in loop (iterate sumdigitsquares n)
sumdigitsquares :: num->num
sumdigitsquares 0 = 0
sumdigitsquares n = (n mod 10)^2 + sumdigitsquares (n div 10)
loop :: [*]->[*]
loop = loop' []
where loop' mem (a:as) = mem, if a $in mem
= loop' (a:mem) as, otherwise
in :: *->[*]->bool
in val [] = False
in val (a:as) = True, if a=val
= val $in as, otherwise
- Output:
1 7 10 13 19 23 28 31
ML
mLite
(*
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. Display an example of your
output here.
*)
local
fun get_digits
(d, s) where (d = 0) = s
| (d, s) = get_digits( d div 10, (d mod 10) :: s)
| n = get_digits( n div 10, [n mod 10] )
;
fun mem
(x, []) = false
| (x, a :: as) where (x = a) = true
| (x, _ :: as) = mem (x, as)
in
fun happy
1 = "happy"
| n =
let
val this = (fold (+,0) ` map (fn n = n ^ 2) ` get_digits n);
val sads = [2, 4, 16, 37, 58, 89, 145, 42, 20]
in
if (mem (n,sads)) then
"unhappy"
else
happy this
end
end
;
foreach (fn n = (print n; print " is "; println ` happy n)) ` iota 10;
Output:
1 is happy 2 is unhappy 3 is unhappy 4 is unhappy 5 is unhappy 6 is unhappy 7 is happy 8 is unhappy 9 is unhappy 10 is happy
Modula-2
MODULE HappyNumbers;
FROM InOut IMPORT WriteCard, WriteLn;
CONST Amount = 8;
VAR seen, num: CARDINAL;
PROCEDURE SumDigitSquares(n: CARDINAL): CARDINAL;
VAR sum, digit: CARDINAL;
BEGIN
sum := 0;
WHILE n>0 DO
digit := n MOD 10;
n := n DIV 10;
sum := sum + digit * digit;
END;
RETURN sum;
END SumDigitSquares;
PROCEDURE Happy(n: CARDINAL): BOOLEAN;
VAR i: CARDINAL;
seen: ARRAY [0..255] OF BOOLEAN;
BEGIN
FOR i := 0 TO 255 DO
seen[i] := FALSE;
END;
REPEAT
seen[n] := TRUE;
n := SumDigitSquares(n);
UNTIL seen[n];
RETURN seen[1];
END Happy;
BEGIN
seen := 0;
num := 0;
WHILE seen < Amount DO
IF Happy(num) THEN
INC(seen);
WriteCard(num,2);
WriteLn();
END;
INC(num);
END;
END HappyNumbers.
- Output:
1 7 10 13 19 23 28 31
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>
NetRexx
/*NetRexx program to display the 1st 8 (or specified arg) happy numbers*/
limit = arg[0] /*get argument for LIMIT. */
say limit
if limit = null, limit ='' then limit=8 /*if not specified, set LIMIT to 8*/
haps = 0 /*count of happy numbers so far. */
loop n=1 while haps < limit /*search integers starting at one.*/
q=n /*Q may or may not be "happy". */
a=0
loop 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. */
loop j=1 for q.length /*add the squares of the numerals.*/
sum = sum + q.substr(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
- 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
Nim
import intsets
proc happy(n: int): bool =
var
n = n
past = initIntSet()
while n != 1:
let s = $n
n = 0
for c in s:
let i = ord(c) - ord('0')
n += i * i
if n in past:
return false
past.incl(n)
return true
for x in 0..31:
if happy(x):
echo x
Output:
1 7 10 13 19 23 28 31
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->Print("First 8 happy numbers: ");
each(i : happynums) {
Console->Print(happynums->Get(i))->Print(",");
};
Console->PrintLine("");
}
}
}
output:
First 8 happy numbers: 1,7,10,13,19,23,28,31,
OCaml
Using Floyd's cycle-finding algorithm.
open Num
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.iter print_endline (
List.rev_map string_of_num (first 8)) ;;
Output:
$ ocaml nums.cma happy_numbers.ml 1 7 10 13 19 23 28 31
Oforth
: isHappy(n)
| cycle |
ListBuffer new ->cycle
while(n 1 <>) [
cycle include(n) ifTrue: [ false return ]
cycle add(n)
0 n asString apply(#[ asDigit sq + ]) ->n
]
true ;
: happyNum(N)
| numbers |
ListBuffer new ->numbers
1 while(numbers size N <>) [ dup isHappy ifTrue: [ dup numbers add ] 1+ ]
numbers println ;
Output:
>happyNum(8) [1, 7, 10, 13, 19, 23, 28, 31]
Ol
(define (number->list num)
(let loop ((num num) (lst #null))
(if (zero? num)
lst
(loop (quotient num 10) (cons (remainder num 10) lst)))))
(define (** x) (* x x))
(define (happy? num)
(let loop ((num num) (seen #null))
(cond
((= num 1) #true)
((memv num seen) #false)
(else
(loop (apply + (map ** (number->list num)))
(cons num seen))))))
(display "happy numbers: ")
(let loop ((n 1) (count 0))
(unless (= count 8)
(if (happy? n)
then
(display n) (display " ")
(loop (+ n 1) (+ count 1))
else
(loop (+ n 1) count))))
(print)
happy numbers: 1 7 10 13 19 23 28 31
ooRexx
count = 0
say "First 8 happy numbers are:"
loop i = 1 while count < 8
if happyNumber(i) then do
count += 1
say i
end
end
::routine happyNumber
use strict arg number
-- use to trace previous cycle results
previous = .set~new
loop forever
-- stop when we hit the target
if number = 1 then return .true
-- stop as soon as we start cycling
if previous[number] \== .nil then return .false
previous~put(number)
next = 0
-- loop over all of the digits
loop digit over number~makearray('')
next += digit * digit
end
-- and repeat the cycle
number = next
end
First 8 happy numbers are: 1 7 10 13 19 23 28 31
Oz
functor
import
System
define
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
{System.show {List.take HappyNumbers 8}}
end
Output:
[1 7 10 13 19 23 28 31]
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.
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))
Output:
%1 = [1, 7, 10, 13, 19, 23, 28, 31]
Pascal
Program HappyNumbers (output);
uses
Math;
function find(n: integer; cache: array of integer): boolean;
var
i: integer;
begin
find := false;
for i := low(cache) to high(cache) do
if cache[i] = n then
find := true;
end;
function is_happy(n: integer): boolean;
var
cache: array of integer;
sum: integer;
begin
setlength(cache, 1);
repeat
sum := 0;
while n > 0 do
begin
sum := sum + (n mod 10)**2;
n := n div 10;
end;
if sum = 1 then
begin
is_happy := true;
break;
end;
if find(sum, cache) then
begin
is_happy := false;
break;
end;
n := sum;
cache[high(cache)]:= sum;
setlength(cache, length(cache)+1);
until false;
end;
var
n, count: integer;
begin
n := 1;
count := 0;
while count < 8 do
begin
if is_happy(n) then
begin
inc(count);
write(n, ' ');
end;
inc(n);
end;
writeln;
end.
Output:
:> ./HappyNumbers 1 7 10 13 19 23 28 31
alternative for counting fast
The Cache is limited to maximum value of the sum of squared digits and filled up in a blink of an eye.Even for cDigit2=1e9 takes 0.7s.Calculation of sum of squared digits is improved.Saving this SqrdSumCache speeds up tremendous. So i am able to check if the 1'000'000 th happy number is 7105849 as stated in C language.This seems to be true. Extended to 10e18 Tested with Free Pascal 3.0.4
Program HappyNumbers (output);
{$IFDEF FPC}
{$MODE DELPHI}
{$OPTIMIZATION ON,All}
{$ELSE}
{$APPLICATION CONSOLE}
{$ENDIF}
//{$DEFINE Use1E9}
uses
sysutils,//Timing
strutils;//Numb2USA
const
base = 10;
HighCache = 20*(sqr(base-1));//sum of sqr digit of Uint64
{$IFDEF Use1E9}
cDigit1 = sqr(base)*sqr(base);//must be power of base
cDigit2 = Base*sqr(cDigit1);// 1e9
cMaxPot = 18;
{$ELSE}
cDigit1 = base*sqr(base);//must be power of base
cDigit2 = sqr(cDigit1);// 1e6
cMaxPot = 14;
{$ENDIF}
type
tSumSqrDgts = array[0..cDigit2] of word;
tCache = array[0..2*HighCache] of word;
tSqrdSumCache = array[0..2*HighCache] of Uint32;
var
SumSqrDgts :tSumSqrDgts;
Cache : tCache;
SqrdSumCache1,
SqrdSumCache2 :tSqrdSumCache;
T1,T0 : TDateTime;
MAX2,Max1 : NativeInt;
procedure InitSumSqrDgts;
//calc all sum of squared digits 0..cDigits2
//using already calculated values
var
i,j,n,sq,Base1: NativeInt;
begin
For i := 0 to Base-1 do
SumSqrDgts[i] := i*i;
Base1 := Base;
n := Base;
repeat
For i := 1 to base-1 do
Begin
sq := SumSqrDgts[i];
For j := 0 to base1-1 do
Begin
SumSqrDgts[n] := sq+SumSqrDgts[j];
inc(n);
end;
end;
Base1 := Base1*base;
until Base1 >= cDigit2;
SumSqrDgts[n] := 1;
end;
function SumSqrdDgt(n: Uint64):NativeUint;inline;
var
r: Uint64;
begin
result := 0;
while n>cDigit2 do
Begin
r := n;
n := n div cDigit2;
r := r-n*cDigit2;
inc(result,SumSqrDgts[r]);
end;
inc(result,SumSqrDgts[n]);
end;
procedure CalcSqrdSumCache1;
var
Count : tSqrdSumCache;
i,sq,result : NativeInt;
begin
For i :=High(Count) downto 0 do
Count[i] := 0;
//count the manifold
For i := cDigit1-1 downto 0 do
inc(count[SumSqrDgts[i]]);
For i := High(Count) downto 0 do
if count[i] <> 0 then
Begin
Max1 := i;
BREAK;
end;
For sq := 0 to (20-3)*81 do
Begin
result := 0;
For i := Max1 downto 0 do
inc(result,Count[i]*Cache[sq+i]);
SqrdSumCache1[sq] := result;
end;
end;
procedure CalcSqrdSumCache2;
var
Count : tSqrdSumCache;
i,sq,result : NativeInt;
begin
For i :=High(Count) downto 0 do
Count[i] := 0;
For i := cDigit2-1 downto 0 do
inc(count[SumSqrDgts[i]]);
For i := High(Count) downto 0 do
if count[i] <> 0 then
Begin
Max2 := i;
BREAK;
end;
For sq := 0 to (20-6)*81 do
Begin
result := 0;
For i := Max2 downto 0 do
inc(result,Count[i]*Cache[sq+i]);
SqrdSumCache2[sq] := result;
end;
end;
procedure Inithappy;
var
n,s,p : NativeUint;
Begin
fillchar(SqrdSumCache1,SizeOf(SqrdSumCache1),#0);
fillchar(SqrdSumCache2,SizeOf(SqrdSumCache2),#0);
InitSumSqrDgts;
fillChar(Cache,SizeOf(Cache),#0);
Cache[1] := 1;
For n := 1 to High(Cache) do
Begin
If Cache[n] = 0 then
Begin
//start a linked list
Cache[n] := n;
p := n;
s := SumSqrdDgt(p);
while Cache[s] = 0 do
Begin
Cache[s] := p;
p := s;
s := SumSqrdDgt(p);
end;
//mark linked list backwards as happy number
IF Cache[s] = 1 then
Begin
repeat
s := Cache[p];
Cache[p] := 1;
p := s;
until s = n;
Cache[n] := 1;
end;
end;
end;
//mark all unhappy numbers with 0
For n := 1 to High(Cache) do
If Cache[n] <> 1 then
Cache[n] := 0;
CalcSqrdSumCache1;
CalcSqrdSumCache2;
end;
function is_happy(n: NativeUint): boolean;inline;
begin
is_happy := Boolean(Cache[SumSqrdDgt(n)])
end;
function nthHappy(Limit: Uint64):Uint64;
var
d,e,sE: NativeUint;
begin
result := 0;
d := 0;
e := 0;
sE := SumSqrDgts[e];
//big steps
while Limit >= cDigit2 do
begin
dec(Limit,SqrdSumCache2[SumSqrDgts[d]+sE]);
inc(result,cDigit2);
inc(d);
IF d >=cDigit2 then
Begin
inc(e);
sE := SumSqrdDgt(e);//SumSqrDgts[e];
d :=0;
end;
end;
//small steps
while Limit >= cDigit1 do
Begin
dec(Limit,SqrdSumCache1[SumSqrdDgt(result)]);
inc(result,cDigit1);
end;
//ONE BY ONE
while Limit > 0 do
begin
dec(Limit,Cache[SumSqrdDgt(result)]);
inc(result);
end;
result -= 1;
end;
var
n, count :Uint64;
Limit: NativeUint;
begin
write('cDigit1 = ',Numb2USA(IntToStr(cDigit1)));
writeln(' cDigit2 = ',Numb2USA(IntToStr(cDigit2)));
T0 := now;
Inithappy;
writeln('Init takes ',FormatDateTime(' HH:NN:SS.ZZZ',now-T0));
n := 1;
count := 0;
while count < 10 do
begin
if is_happy(n) then
begin
inc(count);
write(n, ' ');
end;
inc(n);
end;
writeln;
T0 := now;
T1 := T0;
n := 1;
Limit := 10;
repeat
writeln('1E',n:2,' n.th happy number ',Numb2USA(IntToStr(nthHappy(Limit))):26,
FormatDateTime(' HH:NN:SS.ZZZ',now-T1));
T1 := now;
inc(n);
Limit := limit*10;
until n> cMaxPot;
writeln('Total time counting ',FormatDateTime('HH:NN:SS.ZZZ',now-T0));
end.
- output
cDigit1 = 1,000 cDigit2 = 1,000,000 Init takes 00:00:00.004 1 7 10 13 19 23 28 31 32 44 1E 1 n.th happy number 44 00:00:00.000 1E 2 n.th happy number 694 00:00:00.000 1E 3 n.th happy number 6,899 00:00:00.000 1E 4 n.th happy number 67,169 00:00:00.000 1E 5 n.th happy number 692,961 00:00:00.000 1E 6 n.th happy number 7,105,849 00:00:00.000 1E 7 n.th happy number 71,313,350 00:00:00.000 1E 8 n.th happy number 698,739,425 00:00:00.000 1E 9 n.th happy number 6,788,052,776 00:00:00.000 1E10 n.th happy number 66,305,148,869 00:00:00.000 1E11 n.th happy number 660,861,957,662 00:00:00.001 1E12 n.th happy number 6,745,877,698,967 00:00:00.008 1E13 n.th happy number 70,538,879,028,725 00:00:00.059 1E14 n.th happy number 744,083,563,164,178 00:00:00.612 Total time counting 00:00:00.680 real 0m0,685s cDigit1 = 10,000 cDigit2 = 1,000,000,000 Init takes 00:00:02.848 1 7 10 13 19 23 28 31 32 44 1E 1 n.th happy number 44 00:00:00.000 1E 2 n.th happy number 694 00:00:00.000 1E 3 n.th happy number 6,899 00:00:00.000 1E 4 n.th happy number 67,169 00:00:00.000 1E 5 n.th happy number 692,961 00:00:00.000 1E 6 n.th happy number 7,105,849 00:00:00.000 1E 7 n.th happy number 71,313,350 00:00:00.000 1E 8 n.th happy number 698,739,425 00:00:00.001 1E 9 n.th happy number 6,788,052,776 00:00:00.008 1E10 n.th happy number 66,305,148,869 00:00:00.010 1E11 n.th happy number 660,861,957,662 00:00:00.009 1E12 n.th happy number 6,745,877,698,967 00:00:00.008 1E13 n.th happy number 70,538,879,028,725 00:00:00.008 1E14 n.th happy number 744,083,563,164,178 00:00:00.011 1E15 n.th happy number 7,888,334,045,397,315 00:00:00.019 1E16 n.th happy number 82,440,929,809,838,249 00:00:00.079 1E17 n.th happy number 845,099,936,580,193,833 00:00:00.698 1E18 n.th happy number 8,489,964,903,498,345,213 00:00:06.920 Total time counting 00:00:07.771 real 0m10,627s
PascalABC.NET
uses School;
function IsHappy(n: integer): boolean;
begin
Result := False;
var cache := new HashSet<integer>;
while n <> 1 do
begin
if n in cache then
exit;
cache.Add(n);
n := n.Digits.Sum(d -> d*d);
end;
Result := True;
end;
begin
var n := 1;
var happyNums := new List<integer>;
while happyNums.Count < 8 do
begin
if IsHappy(n) then
happyNums.Add(n);
n += 1;
end;
happyNums.Print
end.
- Output:
1 7 10 13 19 23 28 31
Perl
Since all recurrences end with 1 or repeat (37,58,89,145,42,20,4,16), we can do this test very quickly without having to make hashes of seen numbers.
use List::Util qw(sum);
sub ishappy {
my $s = shift;
while ($s > 6 && $s != 89) {
$s = sum(map { $_*$_ } split(//,$s));
}
$s == 1;
}
my $n = 0;
print join(" ", map { 1 until ishappy(++$n); $n; } 1..8), "\n";
- Output:
1 7 10 13 19 23 28 31
Or we can solve using only the rudimentary task knowledge as below. Note the slightly different ways of doing the digit sum and finding the first 8 numbers where ishappy(n) is true -- this shows there's more than one way to do even these small sub-tasks.
use List::Util qw(sum);
sub is_happy {
my ($n) = @_;
my %seen;
while (1) {
$n = sum map { $_ ** 2 } split //, $n;
return 1 if $n == 1;
return 0 if $seen{$n}++;
}
}
my $n;
is_happy( ++$n ) and print "$n " or redo for 1..8;
- Output:
1 7 10 13 19 23 28 31
Phix
Copy of Euphoria tweaked to give a one-line output
function is_happy(integer n) sequence seen = {} while n>1 do seen &= n integer k = 0 while n>0 do k += power(remainder(n,10),2) n = floor(n/10) end while n = k if find(n,seen) then return false end if end while return true end function integer n = 1 sequence s = {} while length(s)<8 do if is_happy(n) then s &= n end if n += 1 end while ?s
- Output:
{1,7,10,13,19,23,28,31}
PHP
function isHappy($n) {
while (1) {
$total = 0;
while ($n > 0) {
$total += pow(($n % 10), 2);
$n /= 10;
}
if ($total == 1)
return true;
if (array_key_exists($total, $past))
return false;
$n = $total;
$past[$total] = 0;
}
}
$i = $cnt = 0;
while ($cnt < 8) {
if (isHappy($i)) {
echo "$i ";
$cnt++;
}
$i++;
}
1 7 10 13 19 23 28 31
Picat
go =>
println(happy_len(8)).
happy(N) =>
S = [N],
Happy = 1,
while (Happy == 1, N > 1)
N := sum([to_integer(I)**2 : I in N.to_string()]),
if member(N,S) then
Happy := 0
else
S := S ++ [N]
end
end,
Happy == 1.
happy_len(Limit) = S =>
S = [],
N = 1,
while (S.length < Limit)
if happy(N) then
S := S ++ [N]
end,
N := N + 1
end.
- Output:
[1,7,10,13,19,23,28,31]
PicoLisp
(de happy? (N)
(let Seen NIL
(loop
(T (= N 1) T)
(T (member N Seen))
(setq N
(sum '((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
PILOT
C :max=8
:n=0
:i=0
*test
U :*happy
T (a=1):#n
C (a=1):i=i+1
C :n=n+1
J (i<max):*test
E :
*happy
C :a=n
:x=n
U :*sumsq
C :b=s
*loop
C :x=a
U :*sumsq
C :a=s
C :x=b
U :*sumsq
C :x=s
U :*sumsq
C :b=s
J (a<>b):*loop
E :
*sumsq
C :s=0
*digit
C :y=x/10
:z=x-y*10
:s=s+z*#z
:x=y
J (x):*digit
E :
- Output:
1 7 10 13 19 23 28 31
PL/I
test: proc options (main); /* 19 November 2011 */
declare (i, j, n, m, nh initial (0) ) fixed binary (31);
main_loop:
do j = 1 to 100;
n = j;
do i = 1 to 100;
m = 0;
/* Form the sum of squares of the digits. */
do until (n = 0);
m = m + mod(n, 10)**2;
n = n/10;
end;
if m = 1 then
do;
put skip list (j || ' is a happy number');
nh = nh + 1;
if nh = 8 then return;
iterate main_loop;
end;
n = m; /* Replace n with the new number formed from digits. */
end;
end;
end test;
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
PL/M
100H:
/* FIND SUM OF SQUARE OF DIGITS OF NUMBER */
DIGIT$SQUARE: PROCEDURE (N) BYTE;
DECLARE (N, T, D) BYTE;
T = 0;
DO WHILE N > 0;
D = N MOD 10;
T = T + D * D;
N = N / 10;
END;
RETURN T;
END DIGIT$SQUARE;
/* CHECK IF NUMBER IS HAPPY */
HAPPY: PROCEDURE (N) BYTE;
DECLARE (N, I) BYTE;
DECLARE FLAG (256) BYTE;
DO I=0 TO 255;
FLAG(I) = 0;
END;
DO WHILE NOT FLAG(N);
FLAG(N) = 1;
N = DIGIT$SQUARE(N);
END;
RETURN N = 1;
END HAPPY;
/* CP/M BDOS CALL */
BDOS: PROCEDURE (FN, ARG);
DECLARE FN BYTE, ARG ADDRESS;
GO TO 5;
END BDOS;
/* PRINT STRING */
PRINT: PROCEDURE (STR);
DECLARE STR ADDRESS;
CALL BDOS(9, STR);
END PRINT;
/* PRINT NUMBER */
PRINT$NUMBER: PROCEDURE (N);
DECLARE S (6) BYTE INITIAL ('...',13,10,'$');
DECLARE P ADDRESS;
DECLARE (N, C BASED P) BYTE;
P = .S(3);
DIGIT:
P = P - 1;
C = (N MOD 10) + '0';
N = N / 10;
IF N > 0 THEN GO TO DIGIT;
CALL PRINT(P);
END PRINT$NUMBER;
/* FIND FIRST 8 HAPPY NUMBERS */
DECLARE SEEN BYTE INITIAL (0);
DECLARE N BYTE INITIAL (1);
DO WHILE SEEN < 8;
IF HAPPY(N) THEN DO;
CALL PRINT$NUMBER(N);
SEEN = SEEN + 1;
END;
N = N + 1;
END;
CALL BDOS(0,0);
EOF
- Output:
1 7 10 13 19 23 28 31
Potion
sqr = (n): n * n.
isHappy = (n) :
loop :
if (n == 1): return true.
if (n == 4): return false.
sum = 0
n = n string
n length times (i): sum = sum + sqr(n(i) number integer).
n = sum
.
.
firstEight = ()
i = 0
while (firstEight length < 8) :
i++
if (isHappy(i)): firstEight append(i).
.
firstEight string print
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
}
$hist[$sum]=$sum
$sum2=0
foreach($j in $sum.ToString().ToCharArray()) {
$k=([int]$j)-0x30
$sum2+=$k*$k
}
$sum=$sum2
}
}
$a -join ','
}
Output :
happy(8)
7,10,13,19,23,28,31,32
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.
Output :
?- happy_numbers(L, 8).
L = [1,7,10,13,19,23,28,31].
Python
Procedural
>>> def happy(n):
past = set()
while n != 1:
n = sum(int(i)**2 for i in str(n))
if n in past:
return False
past.add(n)
return True
>>> [x for x in xrange(500) if happy(x)][:8]
[1, 7, 10, 13, 19, 23, 28, 31]
Composition of pure functions
Drawing 8 terms from a non finite stream, rather than assuming prior knowledge of the finite sample size required:
'''Happy numbers'''
from itertools import islice
# main :: IO ()
def main():
'''Test'''
print(
take(8)(
happyNumbers()
)
)
# happyNumbers :: Gen [Int]
def happyNumbers():
'''Generator :: non-finite stream of happy numbers.'''
x = 1
while True:
x = until(isHappy)(succ)(x)
yield x
x = succ(x)
# isHappy :: Int -> Bool
def isHappy(n):
'''Happy number sequence starting at n reaches 1 ?'''
seen = set()
# p :: Int -> Bool
def p(x):
if 1 == x or x in seen:
return True
else:
seen.add(x)
return False
# f :: Int -> Int
def f(x):
return sum(int(d)**2 for d in str(x))
return 1 == until(p)(f)(n)
# GENERIC -------------------------------------------------
# succ :: Int -> Int
def succ(x):
'''The successor of an integer.'''
return 1 + x
# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.'''
return lambda xs: (
xs[0:n]
if isinstance(xs, list)
else list(islice(xs, n))
)
# until :: (a -> Bool) -> (a -> a) -> a -> a
def until(p):
'''The result of repeatedly applying f until p holds.
The initial seed value is x.'''
def go(f, x):
v = x
while not p(v):
v = f(v)
return v
return lambda f: lambda x: go(f, x)
if __name__ == '__main__':
main()
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
Quackery
[ 0 swap
[ 10 /mod 2 **
rot + swap
dup 0 = until ]
drop ] is digitsquare ( n --> n )
[ [ digitsquare
dup 1 != while
dup 42 != while
again ]
1 = ] is happy ( n --> b )
[ [] 1
[ dip
[ 2dup size > ]
swap while
dup happy if
[ tuck join swap ]
1+ again ]
drop nip ] is happies ( n --> [ )
8 happies echo
- Output:
[ 1 7 10 13 19 23 28 31 ]
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
Racket
#lang racket
(define (sum-of-squared-digits number (result 0))
(if (zero? number)
result
(sum-of-squared-digits (quotient number 10)
(+ result (expt (remainder number 10) 2)))))
(define (happy-number? number (seen null))
(define next (sum-of-squared-digits number))
(cond ((= 1 next)
#t)
((memq next seen)
#f)
(else
(happy-number? next (cons number seen)))))
(define (get-happys max)
(for/list ((x (in-range max))
#:when (happy-number? x))
x))
(display (take (get-happys 100) 8)) ;displays (1 7 10 13 19 23 28 31)
Raku
(formerly Perl 6)
sub happy (Int $n is copy --> Bool) {
loop {
state %seen;
$n = [+] $n.comb.map: { $_ ** 2 }
return True if $n == 1;
return False if %seen{$n}++;
}
}
say join ' ', grep(&happy, 1 .. *)[^8];
- Output:
1 7 10 13 19 23 28 31
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 = lazy gather for 1..* -> $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];
Output is the same as above.
Here is a version using a subset and an anonymous recursion (we cheat a little bit by using the knowledge that 7 is the second happy number):
subset Happy of Int where sub ($n) {
$n == 1 ?? True !!
$n < 7 ?? False !!
&?ROUTINE([+] $n.comb »**» 2);
}
say (grep Happy, 1 .. *)[^8];
Again, output is the same as above. It is not clear whether this version returns in finite time for any integer, though.
There's more than one way to do it...
Refal
$ENTRY Go {
= <ShowFirst 8 Happy 1>;
};
ShowFirst {
0 s.F s.I = ;
s.N s.F s.I, <Mu s.F s.I>: T =
<Prout s.I>
<ShowFirst <- s.N 1> s.F <+ s.I 1>>;
s.N s.F s.I =
<ShowFirst s.N s.F <+ s.I 1>>;
};
Happy {
1 e.X = T;
s.N e.X s.N e.Y = F;
s.N e.X = <Happy <SqDigSum s.N> s.N e.X>;
};
SqDigSum {
0 = 0;
s.N, <Symb s.N>: s.Ds e.Rs,
<Numb s.Ds>: s.D,
<Numb e.Rs>: s.R =
<+ <* s.D s.D> <SqDigSum s.R>>;
};
- Output:
1 7 10 13 19 23 28 31
Relation
function happy(x)
set y = x
set lasty = 0
set found = " "
while y != 1 and not (found regex "\s".y."\s")
set found = found . y . " "
set m = 0
while y > 0
set digit = y mod 10
set m = m + digit * digit
set y = (y - digit) / 10
end while
set y = format(m,"%1d")
end while
set found = found . y . " "
if y = 1
set result = 1
else
set result = 0
end if
end function
set c = 0
set i = 1
while c < 8 and i < 100
if happy(i)
echo i
set c = c + 1
end if
set i = i + 1
end while
1 7 10 13 19 23 28 31
REXX
/*REXX program computes and displays a specified range of happy numbers. */
Call time 'R'
linesize=80
Parse Arg low high /* obtain range of happy numbers */
If low='?' Then Call help
If low='' Then low=10
If high='' Then
Parse Value 1 low With low high
Do i=0 To 9 /*build a squared decimal digit table. */
square.i=i*i
End
happy.=0 /* happy.m=1 - m is a happy number */
unhappy.=0 /* unhappy.n=1 - n is an unhappy number*/
hapn=0 /* count of the happy numbers */
ol=''
Do n=1 While hapn<high /* test integers starting with 1 */
If unhappy.n Then /* if n is unhappy, */
Iterate /* then try next number */
work=n
suml='' /* list of computed sums */
Do Forever
sum=0
Do length(work) /* compute sum of squared digits */
Parse Var work digit +1 work
sum=sum+square.digit
End
Select
When unhappy.sum |, /* sum is known to be unhappy */
wordpos(sum,suml)>0 Then Do /* or was already encountered */
-- If wordpos(sum,suml)>0 Then say 'Loop' n':' suml sum
-- If n<7 Then say n':' suml sum
unhappy.n=1 /* n is unhappy */
Call set suml /* amd so are all sums so far */
Iterate n
End
When sum=1 Then Do /* we reached sum=1 */
hapn+=1 /* increment number of happy numbers */
happy.n=1 /* n is happy */
If hapn>=low Then /* if it is in specified range */
Call out n /* output it */
If hapn=high Then /* end of range reached */
Leave n /* we are done */
Iterate n /* otherwise proceed */
End
Otherwise Do /* otherwise */
suml=suml sum /* add sum to list of sums */
work=sum /* proceed with the new sum */
End
End
End
End
If ol>'' Then /* more output data */
Say strip(ol) /* write to console */
-- Say time('E')
Exit
set: /* all intermediate sums are unhappy */
Parse Arg list
Do While list<>''
Parse Var list s list
unhappy.s=1
End
Return
out: /* output management */
Parse Arg hn /* the happy number */
If length(ol hn)>linesize Then Do /* if it does not fit */
Say strip(ol) /* output the line */
ol=hn /* and start a new line */
End
Else /* otherwise */
ol=ol hn /* append is to the output line */
Return
help:
Say 'rexx hno n compute and show the first n happy numbers'
Say 'rexx hno low high show happy numbers from index low to high'
Exit
- Output:
K:\_B\HN>rexx hno ? rexx hno n compute and show the first n happy numbers rexx hno low high show happy numbers from index low to high K:\_B\HN>rexx hno 8 1 7 10 13 19 23 28 31 K:\_B\HN>rexx hno 1000 1003 6899 6904 6917 6923
Ring
n = 1
found = 0
While found < 8
If IsHappy(n)
found += 1
see string(found) + " : " + string(n) + nl
ok
n += 1
End
Func IsHappy n
cache = []
While n != 1
Add(cache,n)
t = 0
strn = string(n)
for e in strn
t += pow(number(e),2)
next
n = t
If find(cache,n) Return False ok
End
Return True
- Output:
1 : 1 2 : 7 3 : 10 4 : 13 5 : 19 6 : 23 7 : 28 8 : 31
RPL
≪ { } SWAP DO SWAP OVER + 0 ROT DO MANT RND DUP IP SQ ROT + SWAP FP UNTIL DUP NOT END DROP UNTIL DUP2 POS END SWAP DROP 1 == ≫ 'HAPY?' STO ≪ { } 0 DO 1 + IF DUP HAPY? THEN SWAP OVER + SWAP END UNTIL OVER SIZE 8 == END ≫ EVAL
- Output:
1: { 1 7 10 13 19 23 28 31 }
Ruby
require 'set' # Set: Fast array lookup / Simple existence hash
@seen_numbers = Set.new
@happy_numbers = Set.new
def happy?(n)
return true if n == 1 # Base case
return @happy_numbers.include?(n) if @seen_numbers.include?(n) # Use performance cache, and stop unhappy cycles
@seen_numbers << n
digit_squared_sum = n.digits.sum{|n| n*n}
if happy?(digit_squared_sum)
@happy_numbers << n
true # Return true
else
false # Return false
end
end
Helper method to produce output:
def print_happy
happy_numbers = []
1.step do |i|
break if happy_numbers.length >= 8
happy_numbers << i if happy?(i)
end
p happy_numbers
end
print_happy
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
Alternative version
@memo = [0,1]
def happy(n)
sum = n.digits.sum{|n| n*n}
return @memo[sum] if @memo[sum]==0 or @memo[sum]==1
@memo[sum] = 0 # for the cycle check
@memo[sum] = happy(sum) # return 1:Happy number, 0:other
end
i = count = 0
while count < 8
i += 1
puts i or count+=1 if happy(i)==1
end
puts
for i in 99999999999900..99999999999999
puts i if happy(i)==1
end
- Output:
1 7 10 13 19 23 28 31 99999999999901 99999999999910 99999999999914 99999999999915 99999999999916 99999999999937 99999999999941 99999999999951 99999999999956 99999999999961 99999999999965 99999999999973
Simpler Alternative
def happy?(n)
past = []
until n == 1
n = n.digits.sum { |d| d * d }
return false if past.include? n
past << n
end
true
end
i = count = 0
until count == 8; puts i or count += 1 if happy?(i += 1) end
puts
(99999999999900..99999999999999).each { |i| puts i if happy?(i) }
- Output:
1 7 10 13 19 23 28 31 99999999999901 99999999999910 99999999999914 99999999999915 99999999999916 99999999999937 99999999999941 99999999999951 99999999999956 99999999999961 99999999999965 99999999999973
Rust
In Rust, using a tortoise/hare cycle detection algorithm (generic for integer types)
#![feature(core)]
fn sumsqd(mut n: i32) -> i32 {
let mut sq = 0;
while n > 0 {
let d = n % 10;
sq += d*d;
n /= 10
}
sq
}
use std::num::Int;
fn cycle<T: Int>(a: T, f: fn(T) -> T) -> T {
let mut t = a;
let mut h = f(a);
while t != h {
t = f(t);
h = f(f(h))
}
t
}
fn ishappy(n: i32) -> bool {
cycle(n, sumsqd) == 1
}
fn main() {
let happy = std::iter::count(1, 1)
.filter(|&n| ishappy(n))
.take(8)
.collect::<Vec<i32>>();
println!("{:?}", happy)
}
- Output:
[1, 7, 10, 13, 19, 23, 28, 31]
Salmon
variable happy_count := 0;
outer:
iterate(x; [1...+oo])
{
variable seen := <<(* --> false)>>;
variable now := x;
while (true)
{
if (seen[now])
{
if (now == 1)
{
++happy_count;
print(x, " is happy.\n");
if (happy_count == 8)
break from outer;;
};
break;
};
seen[now] := true;
variable new := 0;
while (now != 0)
{
new += (now % 10) * (now % 10);
now /::= 10;
};
now := new;
};
};
This Salmon program produces the following output:
1 is happy. 7 is happy. 10 is happy. 13 is happy. 19 is happy. 23 is happy. 28 is happy. 31 is happy.
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
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
Scratch
Scratch is a free visual programming language. Click the link, then "See inside" to view the code.
https://scratch.mit.edu/projects/78912620/
This code will allow you to check if a positive interger (<=9999) is a happy number. It will also output a list of the first 8 happy numbers. (1 7 10 13 19 23 28 31)
Seed7
$ include "seed7_05.s7i";
const type: cacheType is hash [integer] boolean;
var cacheType: cache is cacheType.value;
const func boolean: happy (in var integer: number) is func
result
var boolean: isHappy is FALSE;
local
var bitset: cycle is bitset.value;
var integer: newnumber is 0;
var integer: cycleNum is 0;
begin
while number > 1 and number not in cycle do
if number in cache then
number := ord(cache[number]);
else
incl(cycle, number);
newnumber := 0;
while number > 0 do
newnumber +:= (number rem 10) ** 2;
number := number div 10;
end while;
number := newnumber;
end if;
end while;
isHappy := number = 1;
for cycleNum range cycle do
cache @:= [cycleNum] isHappy;
end for;
end func;
const proc: main is func
local
var integer: number is 0;
begin
for number range 1 to 50 do
if happy(number) then
writeln(number);
end if;
end for;
end func;
Output:
1 7 10 13 19 23 28 31 32 44 49
SequenceL
import <Utilities/Math.sl>;
import <Utilities/Conversion.sl>;
main(argv(2)) := findHappys(stringToInt(head(argv)));
findHappys(count) := findHappysHelper(count, 1, []);
findHappysHelper(count, n, happys(1)) :=
happys when size(happys) = count
else
findHappysHelper(count, n + 1, happys ++ [n]) when isHappy(n)
else
findHappysHelper(count, n + 1, happys);
isHappy(n) := isHappyHelper(n, []);
isHappyHelper(n, cache(1)) :=
let
digits[i] := (n / integerPower(10, i - 1)) mod 10
foreach i within 1 ... ceiling(log(10, n + 1));
newN := sum(integerPower(digits, 2));
in
false when some(n = cache)
else
true when n = 1
else
isHappyHelper(newN, cache ++ [n]);
- Output:
$>happy.exe 8 [1,7,10,13,19,23,28,31]
SETL
proc is_happy(n);
s := [n];
while n > 1 loop
if (n := +/[val(i)**2: i in str(n)]) in s then
return false;
end if;
s with:= n;
end while;
return true;
end proc;
happy := [];
n := 1;
until #happy = 8 loop
if is_happy(n) then happy with:= n; end if;
n +:= 1;
end loop;
print(happy);
Output:
[1 7 10 13 19 23 28 31]
Alternative version:
print([n : n in [1..100] | is_happy(n)](1..8));
Output:
[1 7 10 13 19 23 28 31]
Sidef
func happy(n) is cached {
static seen = Hash()
return true if n.is_one
return false if seen.exists(n)
seen{n} = 1
happy(n.digits.sum { _*_ })
}
say happy.first(8)
- Output:
[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.
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: 31 do: [ :i |
(happy isHappy: i)
ifTrue: [ i displayNl ]
].
Output:
1 7 10 13 19 23 28 31
an alternative version is:
|next isHappy happyNumbers|
next :=
[:n |
(n printString collect:[:ch | ch digitValue squared] as:Array) sum
].
isHappy :=
[:n | | t already |
already := Set new.
t := n.
[ t == 1 or:[ (already includes:t)]] whileFalse:[
already add:t.
t := next value:t.
].
t == 1
].
happyNumbers := OrderedCollection new.
try := 1.
[happyNumbers size < 8] whileTrue:[
(isHappy value:try) ifTrue:[ happyNumbers add:try].
try := try + 1
].
happyNumbers printCR
Output: OrderedCollection(1 7 10 13 19 23 28 31)
Swift
func isHappyNumber(var n:Int) -> Bool {
var cycle = [Int]()
while n != 1 && !cycle.contains(n) {
cycle.append(n)
var m = 0
while n > 0 {
let d = n % 10
m += d * d
n = (n - d) / 10
}
n = m
}
return n == 1
}
var found = 0
var count = 0
while found != 8 {
if isHappyNumber(count) {
print(count)
found++
}
count++
}
- Output:
1 7 10 13 19 23 28 31
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}
TUSCRIPT
$$ MODE TUSCRIPT
SECTION check
IF (n!=1) THEN
n = STRINGS (n,":>/:")
LOOP/CLEAR nr=n
square=nr*nr
n=APPEND (n,square)
ENDLOOP
n=SUM(n)
r_table=QUOTES (n)
BUILD R_TABLE/word/EXACT chk=r_table
IF (seq.ma.chk) THEN
status="next"
ELSE
seq=APPEND (seq,n)
ENDIF
RELEASE r_table chk
ELSE
PRINT checkednr," is a happy number"
happynrs=APPEND (happynrs,checkednr)
status="next"
ENDIF
ENDSECTION
happynrs=""
LOOP n=1,100
sz_happynrs=SIZE(happynrs)
IF (sz_happynrs==8) EXIT
checkednr=VALUE(n)
status=seq=""
LOOP
IF (status=="next") EXIT
DO check
ENDLOOP
ENDLOOP
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
Uiua
HC ← /+ⁿ2≡⋕°⋕ # Happiness calc = sum of squares of digits
IH ← |2 memo⟨IH ⊙⊂.|=1⟩∊,, HC # Apply HC until seen value recurs
Happy ← ⟨0◌|∘⟩IH : [1] . # Pre-load `seen` with 1. Return start number or 0
# Brute force approach isn't too bad with memoisation even for high bounds.
↙8⊚>0≡Happy⇡10000
# But iterative approach is still much faster
NH ← |1 ⟨NH|∘⟩≠0Happy.+1 # Find next Happy number
⇌[⍥(NH.) 7 1]
UNIX Shell
function sum_of_square_digits {
typeset -i n=$1 sum=0 d
while (( n )); do
(( d=n%10, sum+=d*d, n=n/10 ))
done
printf '%d\n' "$sum"
}
function is_happy {
typeset -i n=$1
typeset -a seen=()
while (( n != 1 )); do
if [[ -n ${seen[$n]} ]]; then
return 1
fi
seen[$n]=1
(( n=$(sum_of_square_digits "$n") ))
done
return 0
}
function first_n_happy {
typeset -i count=$1 n
for (( n=1; count; n+=1 )); do
if is_happy "$n"; then
printf '%d\n' "$n"
(( count -= 1 ))
fi
done
return 0
}
first_n_happy 8
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>
Vala
using Gee;
/* function to sum the square of the digits */
int sum(int input){
// convert input int to string
string input_str = input.to_string();
int total = 0;
// read through each character in string, square them and add to total
for (int x = 0; x < input_str.length; x++){
// char.digit_value converts char to the decimal value the char it represents holds
int digit = input_str[x].digit_value();
total += (digit * digit);
}
return total;
} // end sum
/* function to decide if a number is a happy number */
bool is_happy(int total){
var past = new HashSet<int>();
while(true){
total = sum(total);
if (total == 1){
return true;}
if (total in past){
return false;}
past.add(total);
} // end while loop
} // end happy
public static void main(){
var happynums = new ArrayList<int>();
int x = 1;
while (happynums.size < 8){
if (is_happy(x) == true)
happynums.add(x);
x++;
}
foreach(int num in happynums)
stdout.printf("%d ", num);
stdout.printf("\n");
} // end main
The output is:
1 7 10 13 19 23 28 31
V (Vlang)
fn happy(h int) bool {
mut m := map[int]bool{}
mut n := h
for n > 1 {
m[n] = true
mut x := 0
for x, n = n, 0; x > 0; x /= 10 {
d := x % 10
n += d * d
}
if m[n] {
return false
}
}
return true
}
fn main() {
for found, n := 0, 1; found < 8; n++ {
if happy(n) {
print("$n ")
found++
}
}
println('')
}
- Output:
1 7 10 13 19 23 28 31
Wren
var happy = Fn.new { |n|
var m = {}
while (n > 1) {
m[n] = true
var x = n
n = 0
while (x > 0) {
var d = x % 10
n = n + d*d
x = (x/10).floor
}
if (m[n] == true) return false // m[n] will be null if 'n' is not a key
}
return true
}
var found = 0
var n = 1
while (found < 8) {
if (happy.call(n)) {
System.write("%(n) ")
found = found + 1
}
n = n + 1
}
System.print()
- Output:
1 7 10 13 19 23 28 31
XPL0
The largest possible 32-bit integer is less than 9,999,999,999. The sum of the squares of these ten digits is 10*9^2 = 810. If a cycle consisted of all the values smaller than 810, an array size of 810 would still be sufficiently large to hold them. Actually, tests show that the array only needs to hold 16 numbers.
int List(810); \list of numbers in a cycle
int Inx; \index for List
include c:\cxpl\codes;
func HadNum(N); \Return 'true' if number N is in the List
int N;
int I;
[for I:= 0 to Inx-1 do
if N = List(I) then return true;
return false;
]; \HadNum
func SqDigits(N); \Return the sum of the squares of the digits of N
int N;
int S, D;
[S:= 0;
while N do
[N:= N/10;
D:= rem(0);
S:= S + D*D;
];
return S;
]; \SqDigits
int N0, N, C;
[N0:= 0; \starting number
C:= 0; \initialize happy (starting) number counter
repeat N:= N0;
Inx:= 0; \reset List index
loop [N:= SqDigits(N);
if N = 1 then \happy number
[IntOut(0, N0); CrLf(0);
C:= C+1;
quit;
];
if HadNum(N) then quit; \if unhappy number then quit
List(Inx):= N; \if neither, add it to the List
Inx:= Inx+1; \ and continue the cycle
];
N0:= N0+1; \next starting number
until C=8; \done when 8 happy numbers have been found
]
Output:
1 7 10 13 19 23 28 31
Zig
const std = @import("std");
const stdout = std.io.getStdOut().outStream();
pub fn main() !void {
try stdout.print("The first 8 happy numbers are: ", .{});
var n: u32 = 1;
var c: u4 = 0;
while (c < 8) {
if (isHappy(n)) {
c += 1;
try stdout.print("{} ", .{n});
}
n += 1;
}
try stdout.print("\n", .{});
}
fn isHappy(n: u32) bool {
var t = n;
var h = sumsq(n);
while (t != h) {
t = sumsq(t);
h = sumsq(sumsq(h));
}
return t == 1;
}
fn sumsq(n0: u32) u32 {
var s: u32 = 0;
var n = n0;
while (n > 0) : (n /= 10) {
const m = n % 10;
s += m * m;
}
return s;
}
- Output:
The first 8 happy numbers are: 1 7 10 13 19 23 28 31
zkl
Here is a function that generates a continuous stream of happy numbers. Given that there are lots of happy numbers, caching them doesn't seem like a good idea memory wise. Instead, a num of squared digits == 4 is used as a proxy for a cycle (see the Wikipedia article, there are several number that will work).
fcn happyNumbers{ // continously spew happy numbers
foreach N in ([1..]){
n:=N; while(1){
n=n.split().reduce(fcn(p,n){ p + n*n },0);
if(n==1) { vm.yield(N); break; }
if(n==4) break; // unhappy cycle
}
}
}
h:=Utils.Generator(happyNumbers);
h.walk(8).println();
- Output:
L(1,7,10,13,19,23,28,31)
Get the one million-th happy number. Nobody would call this quick.
Utils.Generator(happyNumbers).drop(0d1_000_000-1).next().println();
- Output:
7105849
- Programming Tasks
- Arithmetic operations
- 11l
- 8080 Assembly
- 8th
- ABC
- ACL2
- Action!
- ActionScript
- Ada
- ALGOL 68
- ALGOL-M
- ALGOL W
- APL
- AppleScript
- Arturo
- AutoHotkey
- AutoIt
- AWK
- BASIC
- Applesoft BASIC
- BASIC256
- BBC BASIC
- Commodore BASIC
- FreeBASIC
- Liberty BASIC
- Locomotive Basic
- PureBasic
- Run BASIC
- UBasic/4tH
- VBA
- VBScript
- Visual Basic .NET
- ZX Spectrum Basic
- Batch File
- BCPL
- Bori
- BQN
- Brat
- C
- C sharp
- C++
- Clojure
- CLU
- COBOL
- CoffeeScript
- Common Lisp
- Cowgol
- Crystal
- D
- Dart
- Dc
- DCL
- Delphi
- System.SysUtils
- Boost.Int
- Draco
- DWScript
- Dyalect
- Déjà Vu
- E
- E examples needing attention
- Examples needing attention
- EasyLang
- Eiffel
- Elena
- Elixir
- Erlang
- Euphoria
- F Sharp
- Factor
- FALSE
- Fantom
- FOCAL
- Forth
- Fortran
- Frege
- FutureBasic
- Fōrmulæ
- Go
- Groovy
- Harbour
- Haskell
- Icon
- Unicon
- J
- Java
- JavaScript
- Jq
- Julia
- K
- Kotlin
- Lambdatalk
- Lasso
- Logo
- LOLCODE
- Lua
- M2000 Interpreter
- MACRO-11
- MAD
- Maple
- Mathematica
- Wolfram Language
- MATLAB
- Maxima
- MAXScript
- Mercury
- MiniScript
- Miranda
- ML
- MLite
- Modula-2
- MUMPS
- NetRexx
- Nim
- Objeck
- OCaml
- Oforth
- Ol
- OoRexx
- Oz
- PARI/GP
- Pascal
- PascalABC.NET
- Perl
- Phix
- PHP
- Picat
- PicoLisp
- PILOT
- PL/I
- PL/M
- Potion
- PowerShell
- Prolog
- Python
- Quackery
- R
- Racket
- Raku
- Refal
- Relation
- REXX
- Ring
- RPL
- Ruby
- Rust
- Salmon
- Scala
- Scheme
- Scratch
- Seed7
- SequenceL
- SETL
- Sidef
- Smalltalk
- Swift
- Tcl
- TUSCRIPT
- Uiua
- UNIX Shell
- Ursala
- Vala
- Gee
- V (Vlang)
- Wren
- XPL0
- Zig
- Zkl
- Pages with too many expensive parser function calls