xref: /netbsd-src/sys/modules/examples/luareadhappy/happy.lua (revision 502c2ed2bab0e0ff46d5bd8e78a0b316972820ed)
1*502c2ed2Skamil--	$NetBSD: happy.lua,v 1.1 2017/04/15 04:27:30 kamil Exp $
2*502c2ed2Skamil--
3*502c2ed2Skamil-- Copyright (c) 2015 The NetBSD Foundation, Inc.
4*502c2ed2Skamil-- All rights reserved.
5*502c2ed2Skamil--
6*502c2ed2Skamil-- Redistribution and use in source and binary forms, with or without
7*502c2ed2Skamil-- modification, are permitted provided that the following conditions
8*502c2ed2Skamil-- are met:
9*502c2ed2Skamil-- 1. Redistributions of source code must retain the above copyright
10*502c2ed2Skamil--    notice, this list of conditions and the following disclaimer.
11*502c2ed2Skamil-- 2. Redistributions in binary form must reproduce the above copyright
12*502c2ed2Skamil--    notice, this list of conditions and the following disclaimer in the
13*502c2ed2Skamil--    documentation and/or other materials provided with the distribution.
14*502c2ed2Skamil--
15*502c2ed2Skamil-- THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16*502c2ed2Skamil-- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17*502c2ed2Skamil-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18*502c2ed2Skamil-- PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19*502c2ed2Skamil-- BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20*502c2ed2Skamil-- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21*502c2ed2Skamil-- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22*502c2ed2Skamil-- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*502c2ed2Skamil-- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24*502c2ed2Skamil-- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25*502c2ed2Skamil-- POSSIBILITY OF SUCH DAMAGE.
26*502c2ed2Skamil--
27*502c2ed2Skamil--
28*502c2ed2Skamil-- Commentary:
29*502c2ed2Skamil-- A happy number is a number defined by the following process: Starting with
30*502c2ed2Skamil-- any positive integer, replace the number by the sum of the squares of its
31*502c2ed2Skamil-- digits, and repeat the process until the number equals 1 (where it will
32*502c2ed2Skamil-- stay), or it loops endlessly in a cycle which does not include 1. Those
33*502c2ed2Skamil-- numbers for which this process ends in 1 are happy numbers, while those that
34*502c2ed2Skamil-- do not end in 1 are unhappy numbers (or sad numbers).
35*502c2ed2Skamil--
36*502c2ed2Skamil-- For more information on happy numbers, and the algorithms, see
37*502c2ed2Skamil--      http://en.wikipedia.org/wiki/Happy_number
38*502c2ed2Skamil--
39*502c2ed2Skamil-- The happy number generator is here only to have something that the user
40*502c2ed2Skamil-- can read from our device.  Any other arbitrary data generator could
41*502c2ed2Skamil-- have been used.  The algorithm is not critical to the implementation
42*502c2ed2Skamil-- of the module.
43*502c2ed2Skamil
44*502c2ed2Skamillocal HAPPY_NUMBER = 1
45*502c2ed2Skamil
46*502c2ed2Skamil-- If n is not happy then its sequence ends in the cycle:
47*502c2ed2Skamil-- 4, 16, 37, 58, 89, 145, 42, 20, 4, ...
48*502c2ed2Skamillocal SAD_NUMBER = 4
49*502c2ed2Skamil
50*502c2ed2Skamil-- This following algorithm is designed for numbers of the integer type.
51*502c2ed2Skamil-- Integer numbers are used by default in the NetBSD kernel, as there would be
52*502c2ed2Skamil-- need for additional overhead in context-switch with support for floats.
53*502c2ed2Skamil
54*502c2ed2Skamilfunction dsum(n)
55*502c2ed2Skamil	local sum = 0
56*502c2ed2Skamil	while n > 0 do
57*502c2ed2Skamil		local x = n % 10
58*502c2ed2Skamil		sum = sum + (x * x)
59*502c2ed2Skamil		n = n / 10
60*502c2ed2Skamil	end
61*502c2ed2Skamil	return sum
62*502c2ed2Skamilend
63*502c2ed2Skamil
64*502c2ed2Skamilfunction is_happy(n)
65*502c2ed2Skamil	while true do
66*502c2ed2Skamil		local total = dsum(n)
67*502c2ed2Skamil
68*502c2ed2Skamil		if total == HAPPY_NUMBER then
69*502c2ed2Skamil			return 1
70*502c2ed2Skamil		end
71*502c2ed2Skamil		if total == SAD_NUMBER then
72*502c2ed2Skamil			return 0
73*502c2ed2Skamil		end
74*502c2ed2Skamil
75*502c2ed2Skamil		n = total
76*502c2ed2Skamil	end
77*502c2ed2Skamilend
78