Munchausen numbers: Difference between revisions
({{header|AppleScript}}) |
|||
Line 10: | Line 10: | ||
=={{header|ALGOL 68}}== |
=={{header|ALGOL 68}}== |
||
<lang algol68># Find Munchausen Numbers between 1 and 5000 # |
<lang algol68># Find Munchausen Numbers between 1 and 5000 # |
||
# note that 6^6 is 46 656 so we only need to |
# note that 6^6 is 46 656 so we only need to consider numbers consisting of 0 to 5 # |
||
# table of Nth powers # |
# table of Nth powers # |
||
Line 51: | Line 51: | ||
3435 |
3435 |
||
</pre> |
</pre> |
||
=={{header|AppleScript}}== |
|||
<lang AppleScript> |
|||
on run |
|||
filter(isMunchausen, range(1, 5000)) |
|||
--> {1, 3435} |
|||
end run |
|||
-- isMunchausen :: Int -> Bool |
|||
on isMunchausen(n) |
|||
(class of n is integer) and ¬ |
|||
foldl(my digitPowerSum, 0, characters of (n as string)) = n |
|||
end isMunchausen |
|||
-- digitPowerSum :: Int -> Character -> Int |
|||
on digitPowerSum(a, c) |
|||
set d to c as integer |
|||
a + (d ^ d) |
|||
end digitPowerSum |
|||
-- GENERIC LIBRARY FUNCTIONS |
|||
-- filter :: (a -> Bool) -> [a] -> [a] |
|||
on filter(f, xs) |
|||
set mf to mReturn(f) |
|||
set lst to {} |
|||
set lng to length of xs |
|||
repeat with i from 1 to lng |
|||
set v to item i of xs |
|||
if mf's lambda(v, i, xs) then |
|||
set end of lst to v |
|||
end if |
|||
end repeat |
|||
return lst |
|||
end filter |
|||
-- foldl :: (a -> b -> a) -> a -> [b] -> a |
|||
on foldl(f, startValue, xs) |
|||
set mf to mReturn(f) |
|||
set v to startValue |
|||
set lng to length of xs |
|||
repeat with i from 1 to lng |
|||
set v to mf's lambda(v, item i of xs, i, xs) |
|||
end repeat |
|||
return v |
|||
end foldl |
|||
-- range :: Int -> Int -> [Int] |
|||
on range(m, n) |
|||
if n < m then |
|||
set d to -1 |
|||
else |
|||
set d to 1 |
|||
end if |
|||
set lst to {} |
|||
repeat with i from m to n by d |
|||
set end of lst to i |
|||
end repeat |
|||
return lst |
|||
end range |
|||
-- Lift 2nd class handler function into 1st class script wrapper |
|||
-- mReturn :: Handler -> Script |
|||
on mReturn(f) |
|||
if class of f is script then return f |
|||
script |
|||
property lambda : f |
|||
end script |
|||
end mReturn |
|||
-- mClosure :: Handler -> Record -> Script |
|||
on mClosure(f, recBindings) |
|||
script |
|||
property closure : recBindings |
|||
property lambda : f |
|||
end script |
|||
end mClosure</lang> |
|||
{{Out}} |
|||
<lang AppleScript>{1, 3435}</lang> |
|||
=={{header|C}}== |
=={{header|C}}== |
Revision as of 11:00, 23 September 2016
- Definition of Munchausen numbers
A Munchausen number is a natural number n the sum of whose digits (in base 10), each raised to the power of itself, is n itself.
- Task requirements
Finds all Munchausen numbers between 1 and 5000
ALGOL 68
<lang algol68># Find Munchausen Numbers between 1 and 5000 #
- note that 6^6 is 46 656 so we only need to consider numbers consisting of 0 to 5 #
- table of Nth powers #
[]INT nth power = ([]INT( 1, 1, 2 * 2, 3 * 3 * 3, 4 * 4 * 4 * 4, 5 * 5 * 5 * 5 * 5 ))[ AT 0 ];
FOR d1 FROM 0 TO 5 DO
INT d1 part = d1 * 1000; FOR d2 FROM 0 TO 5 DO INT d2 part = d2 * 100; FOR d3 FROM 0 TO 5 DO INT d3 part = d3 * 10; FOR d4 FROM 0 TO 5 DO INT digit power sum := 0; IF d1 > 0 THEN digit power sum := nth power[ d1 ] + nth power[ d2 ] + nth power[ d3 ] + nth power[ d4 ] ELIF d2 > 0 THEN digit power sum := nth power[ d2 ] + nth power[ d3 ] + nth power[ d4 ] ELIF d3 > 0 THEN digit power sum := nth power[ d3 ] + nth power[ d4 ] ELSE digit power sum := nth power[ d4 ] FI; INT number = d1 part + d2 part + d3 part + d4; IF digit power sum = number THEN print( ( whole( number, 0 ), newline ) ) FI OD OD OD
OD</lang>
- Output:
1 3435
AppleScript
<lang AppleScript> on run
filter(isMunchausen, range(1, 5000)) --> {1, 3435}
end run
-- isMunchausen :: Int -> Bool on isMunchausen(n)
(class of n is integer) and ¬ foldl(my digitPowerSum, 0, characters of (n as string)) = n
end isMunchausen
-- digitPowerSum :: Int -> Character -> Int on digitPowerSum(a, c)
set d to c as integer a + (d ^ d)
end digitPowerSum
-- GENERIC LIBRARY FUNCTIONS
-- filter :: (a -> Bool) -> [a] -> [a] on filter(f, xs)
set mf to mReturn(f) set lst to {} set lng to length of xs repeat with i from 1 to lng set v to item i of xs if mf's lambda(v, i, xs) then set end of lst to v end if end repeat return lst
end filter
-- foldl :: (a -> b -> a) -> a -> [b] -> a on foldl(f, startValue, xs)
set mf to mReturn(f) set v to startValue set lng to length of xs repeat with i from 1 to lng set v to mf's lambda(v, item i of xs, i, xs) end repeat return v
end foldl
-- range :: Int -> Int -> [Int]
on range(m, n)
if n < m then set d to -1 else set d to 1 end if set lst to {} repeat with i from m to n by d set end of lst to i end repeat return lst
end range
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
if class of f is script then return f script property lambda : f end script
end mReturn
-- mClosure :: Handler -> Record -> Script on mClosure(f, recBindings)
script property closure : recBindings property lambda : f end script
end mClosure</lang>
- Output:
<lang AppleScript>{1, 3435}</lang>
C
Adapted from Zack Denton's code posted on Munchausen Numbers and How to Find Them. <lang C>#include <stdio.h>
- include <math.h>
int main() {
for (int i = 1; i < 5000; i++) { // loop through each digit in i // e.g. for 1000 we get 0, 0, 0, 1. int sum = 0; for (int number = i; number > 0; number /= 10) { int digit = number % 10; // find the sum of the digits // raised to themselves sum += pow(digit, digit); } if (sum == i) { // the sum is equal to the number // itself; thus it is a // munchausen number printf("%i\n", i); } } return 0;
}</lang>
- Output:
1 3435
C#
<lang csharp>Func<char, int> toInt = c => c-'0';
foreach (var i in Enumerable.Range(1,5000) .Where(n => n == n.ToString() .Sum(x => Math.Pow(toInt(x), toInt(x))))) Console.WriteLine(i);</lang>
- Output:
1 3435
Haskell
<lang haskell>import Data.List (unfoldr)
isMunchausen :: Integer -> Bool isMunchausen n = (n ==) $ sum $ map (\x -> x^x) $ unfoldr digit n where
digit 0 = Nothing digit n = Just (r,q) where (q,r) = n `divMod` 10
main :: IO () main = print $ filter isMunchausen [1..5000]</lang>
- Output:
[1,3435]
J
Here, it would be useful to have a function which sums the powers of the digits of a number. Once we have that we can use it with an equality test to filter those integers:
<lang J> munch=: +/@(^~@(10&#.inv))
(#~ ] = munch"0) 1+i.5000
1 3435</lang>
Java
Adapted from Zack Denton's code posted on Munchausen Numbers and How to Find Them. <lang Java> public class Main {
public static void main(String[] args) { for(int i = 0 ; i <= 5000 ; i++ ){ int val = String.valueOf(i).chars().map(x -> (int) Math.pow( x-48 ,x-48)).sum(); if( i == val){ System.out.println( i + " (munchausen)"); } } }
}
</lang>
- Output:
1 (munchausen) 3435 (munchausen)
JavaScript
ES6
<lang javascript>for (let i of [...Array(5000).keys()] .filter(n => n == n.toString().split() .reduce((a, b) => a+Math.pow(parseInt(b),parseInt(b)), 0))) console.log(i);</lang>
- Output:
1 3435
Or, composing reusable primitives:
<lang JavaScript>(function () {
'use strict';
// isMunchausen :: Int -> Bool let isMunchausen = n => !isNaN(n) && ( n.toString() .split() .reduce((a, c) => { let d = parseInt(c, 10); return a + Math.pow(d, d); }, 0) === n ),
// range(intFrom, intTo, intStep?) // Int -> Int -> Maybe Int -> [Int] range = (m, n, step) => { let d = (step || 1) * (n >= m ? 1 : -1);
return Array.from({ length: Math.floor((n - m) / d) + 1 }, (_, i) => m + (i * d)); };
return range(1, 5000) .filter(isMunchausen);
})();</lang>
- Output:
<lang JavaScript>[1, 3435]</lang>
Lua
<lang Lua>function isMunchausen (n)
local sum, nStr, digit = 0, tostring(n) for pos = 1, #nStr do digit = tonumber(nStr:sub(pos, pos)) sum = sum + digit ^ digit end return sum == n
end
for i = 1, 5000 do
if isMunchausen(i) then print(i) end
end</lang>
- Output:
1 3435
Perl 6
<lang perl6>sub is_munchausen ( Int $n ) {
constant @powers = 0, |map { $_ ** $_ }, 1..9; $n == @powers[$n.comb].sum;
} .say if .&is_munchausen for 1..5000;</lang>
- Output:
1 3435
Scala
Adapted from Zack Denton's code posted on Munchausen Numbers and How to Find Them. <lang Scala> object Munch {
def main(args: Array[String]): Unit = { import scala.math.pow (1 to 5000).foreach { i => if (i == (i.toString.toCharArray.map(d => pow(d.asDigit,d.asDigit))).sum) println( i + " (munchausen)") } }
} </lang>
- Output:
1 (munchausen) 3435 (munchausen)
zkl
<lang zkl>[1..5000].filter(fcn(n){ n==n.split().reduce(fcn(s,n){ s + n.pow(n) },0) }) .println();</lang>
- Output:
L(1,3435)