Talk:Weird numbers: Difference between revisions

→‎A faster and less ambitious algorithm ?: Added a Haskell version of an anySum (for testing)
(→‎A faster and less ambitious algorithm ?: Added a Haskell version of an anySum (for testing))
 
(3 intermediate revisions by the same user not shown)
Line 20:
[[User:Hout|Hout]] ([[User talk:Hout|talk]]) 11:52, 24 March 2019 (UTC)
 
: PS I think we may be able to see and test the operation of '''hasSum''' more clearly if we enrich its type from Bool to [Int] (with a return value of the empty list for '''False''', and the integers of the first sum found for '''True'''). Let's call this richer-typed variant '''anySum''', and sketch it in Python 3.
 
::<lang python># anySum :: Int -> [Int] -> [Int]
def anySum(n, xs):
'''First subset of xs found to sum to n.
(Probably more efficient where xs is sorted in descending
descending order of magnitude)'''
def go(n, xs):
if xs:
Line 45:
 
 
# Search for sum through descending numbers (more efficient)
print(anySum(7, [1,1,1,1,1,6]))
print(anySum(196, range(100, 0, -1)))
# -> [1100, 696]
 
# Search for sum through ascending numbers (less efficient)
print(anySum(7196, [range(1,1,1,1,1,6] 101)))
# -> [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 25]
 
print(anySum(7, [6, 3]))
# -> []</lang>
 
or similarly, rewriting '''hasSum''' to '''anySum''' (with comments) in a Haskell idiom:
 
:<lang haskell>module AnySum where
 
hasSum :: Int -> [Int] -> Bool
hasSum _ [] = False
hasSum n (x:xs)
| n < x = hasSum n xs
| otherwise = (n == x) || hasSum (n - x) xs || hasSum n xs
 
 
-- Or, enriching the return type from Bool to [Int]
-- with [] for False and a populated list (first sum found) for True
 
anySum :: Int -> [Int] -> [Int]
anySum _ [] = []
anySum n (x:xs)
| n < x = anySum n xs -- x too large for a sum to n
| n == x = [x] -- We have a sum
| otherwise =
let ys = anySum (n - x) xs -- Any sum for (n - x) in the tail ?
in if null ys
then anySum n xs -- Any sum (not involving x) in the tail ?
else x : ys -- x and the rest of the sum that was found.
 
main :: IO ()
main = do
-- xs ascending - the test is less efficient
print $ anySum 196 [1 .. 100]
-- -> [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,25]
-- xs descending - the test is more efficent
print $ anySum 196 [100,99 ..]
-- -> [100,96]</lang>
9,655

edits