Humble numbers: Difference between revisions
m
syntax highlighting fixup automation
Alpha bravo (talk | contribs) (Added AutoHotkey) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 36:
{{trans|C++}}
<
I i <= 1
R 1B
Line 65:
I num !C humble
L.break
print(‘#5 have #. digits’.format(humble[num], num))</
{{out}}
Line 84:
=={{header|Ada}}==
<
procedure Show_Humble is
Line 149:
Count_Humble_Digits;
Show_Digit_Counts;
end Show_Humble;</
{{out}}
Line 168:
=={{header|ALGOL 68}}==
<
INT max humble = 2048;
INT max shown humble = 49;
Line 212:
)
OD
END</
{{out}}
<pre>
Line 226:
=={{header|ALGOL W}}==
As noted by other samples, this is similar to the Hamming Numbers task. This is a modified version of the Algol W solution for Hamming Numbers. The numbers are generated in sequence.
<
% returns the minimum of a and b %
integer procedure min ( integer value a, b ) ; if a < b then a else b;
Line 290:
write( "there are", h6, " Humble numbers with 6 digits" )
end
end.</
{{out}}
<pre>
Line 303:
=={{header|AutoHotkey}}==
<
while (c < 50)
{
Line 362:
ans.push(n)
return ans
}</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 372:
=={{header|AWK}}==
<syntaxhighlight lang="awk">
# syntax: GAWK -f HUMBLE_NUMBERS.AWK
#
Line 404:
return(0)
}
</syntaxhighlight>
{{out}}
<pre>
Line 422:
=={{header|C}}==
{{trans|C++}}
<
#include <stdbool.h>
#include <stdio.h>
Line 469:
return 0;
}</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 486:
=={{header|C sharp|C#}}==
{{trans|D}}
<
using System.Collections.Generic;
Line 535:
}
}
}</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 553:
{{trans|Go}}
{{libheader|System.Numerics}}
<
using System;
Line 594:
Console.WriteLine("The first {0} humble numbers are: {1}", firstAmt, string.Join(" ",h.Take(firstAmt)));
}
}</
{{out}}
Results from a core i7-7700 @ 3.6Ghz.<br/>BigIntegers: (tabulates up to 100 digits in about 3/4 of a minute, but a lot of memory is consumed - 4.2 GB)
Line 732:
Why use fixed-point logarithms of UIint64 instead of double? Because the rounding of the doubles when added together throws the sums off a bit so they don't match properly when incrementing the i, j, k, & l variables. If one were to change the 'fac" variable to a larger number, such as 1e15, there is too much "noise" on the least significant bits and the ''ijkl'' variables advance unevenly enough to throw off some of the counts. Some of the solutions presented here implement an "error banding" check to defeat this issue, but it seems a bit over complicated.
<
using UI = System.UInt64;
Line 773:
humLog(255); // see tabulation for digits 1 to 255
}
}</
{{out}}
verified results against the Pascal entry:
Line 1,038:
=={{header|C++}}==
{{trans|Kotlin}}
<
#include <iostream>
#include <map>
Line 1,097:
return 0;
}</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 1,114:
=== Direct Generation - Variant ===
A direct generation variant. Rather quick, as the humble numbers are not generated in order. And the digits are not counted individually, the log representation of each humble number is just binned into the decade tally with a simple division by log(10). Note: g++ compiler options: <code>-O3 -std=c++17</code>
<
#include <cmath>
#include <locale>
Line 1,151:
delete [] bins;
printf("Counting took %8f seconds\n", duration<double>(steady_clock::now() - st).count());
}</
{{out}}
Seems to give correct values as compared to the pascal (modification of hamming numbers fast alternative) version. And goes noticeably faster, up to 877 digits in about 3 1/4 minutes, where as pascal takes 1 1/3 hours to get to 877 digits.
Line 2,040:
Checks if each number upto limit is humble number.
{{trans|C++}}
<
return true if (i < 2)
return humble?(i // 2) if (i % 2 == 0)
Line 2,063:
print "\n\nOf the first #{count} humble numbers:\n"
(1..digits).each { |num| printf("%5d have %2d digits\n", humble[num], num) }</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 2,082:
Generate humble numbers directly.
{{trans|Zkl}}
<
def humble(digits)
Line 2,106:
print "First 50 Humble Numbers: \n"; (0...50).each { |i| print "#{h[i]} " }
print "\n\nOf the first #{count} humble numbers:\n"
(1..digits).each { |num| printf("%6d have %2d digits\n", counts[num], num) }</
{{out}}
<pre>First 50 Humble Numbers:
Line 2,165:
=={{header|D}}==
{{trans|C++}}
<
import std.stdio;
Line 2,206:
}
}
}</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 2,225:
=={{header|F_Sharp|F#}}==
===The Functions===
<
// Generate humble numbers. Nigel Galloway: June 18th., 2020
let fN g=let mutable n=1UL in (fun()->n<-n*g;n)
Line 2,238:
|r->vg<-fG vg (fI vn (g()));vn<-n();v<-Some r;vg()
let humble = seq{yield 1UL;yield! fE(fL (fN 7UL) (fun()->fL (fN 5UL) (fun()->fL (fN 3UL) (fun()->fN 2UL))))}
</syntaxhighlight>
===The Tasks===
<
humble |> Seq.take 50 |> Seq.iter (printf "%d ");printfn ""
</syntaxhighlight>
{{out}}
<pre>
1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
</pre>
<
for n in [1..18] do let g=pown 10UL n in printfn "There are %d humble numbers with %d digits" (humble|>Seq.skipWhile(fun n->n<g/10UL)|>Seq.takeWhile(fun n->n<g)|>Seq.length) n
</syntaxhighlight>
{{out}}
<pre>
Line 2,272:
</pre>
=={{header|Factor}}==
<
generalizations io kernel make math math.functions math.order
prettyprint sequences tools.memory.private ;
Line 2,330:
] tri ] time ;
MAIN: humble-numbers</
{{out}}
<pre style="height:45ex">
Line 2,440:
=={{header|FreeBASIC}}==
{{trans|Visual Basic .NET}}
<
If i <= 1 Then Return True
If i Mod 2 = 0 Then Return IsHumble(i \ 2)
Line 2,483:
Exit While
End If
Wend</
{{out}}
<pre>Los 50 primeros números de Humble son:
Line 2,507:
=={{header|Go}}==
Not particularly fast and uses a lot of memory but easier to understand than the 'log' based methods for generating 7-smooth numbers.
<
import (
Line 2,601:
fmt.Printf("%9s have %2d digit%s\n", commatize(counts[i]), i, s)
}
}</
{{out}}
Line 2,682:
=={{header|Haskell}}==
<
import Data.List.Split (chunksOf)
import Data.List (group)
Line 2,708:
------------------------- DISPLAY -------------------------
justifyRight :: Int -> a -> [a] -> [a]
justifyRight n c = (drop . length) <*> (replicate n c ++)</
{{Out}}
<pre>First 50 Humble numbers:
Line 2,746:
=={{header|J}}==
Multiply all the humble numbers by all the factors appending the next largest value.
<syntaxhighlight lang="text">
humble=: 4 : 0
NB. x humble y generates x humble numbers based on factors y
Line 2,755:
end.
)
</syntaxhighlight>
<pre>
p: i.4
Line 2,774:
Use a class to simulate the python generator. This is a more efficient implementation of the first method.
<syntaxhighlight lang="text">
FACTORS_h_=: p: i. 4
HUMBLE_h_=: 1
Line 2,784:
)
reset_h_=: 3 :'0 $ HUMBLE=: 1'
</syntaxhighlight>
<pre>
3 :0 [ 50 [ reset_h_''
Line 2,826:
=={{header|Java}}==
<
import java.math.BigInteger;
import java.util.ArrayList;
Line 2,890:
}
</syntaxhighlight>
{{Out}}
<pre>
Line 2,936:
=={{header|JavaScript}}==
<
'use strict';
Line 3,170:
// MAIN ---
return main();
})();</
{{Out}}
<pre>First 50 humble numbers:
Line 3,197:
===Brute force===
First, brute force (because we can) ...
<syntaxhighlight lang="text">
# Input: a positive integer
# Output: true iff the input is humble
Line 3,228:
(.humble | range(1;length) as $i | " \($i): \(.[$i])") ;
task(6; 50)</
{{out}}
<pre>First 50:
Line 3,243:
Having already shown one way to display the first few humble numbers, this subsection will focus on the more difficult problem.
<syntaxhighlight lang="jq">
# A generator
def humbles($digits):
Line 3,267:
(distribution(humbles($digits)) | range(0;length) as $i | " \($i+1): \(.[$i])") ;
task(16)</
{{out}}
<pre>Distribution of the number of decimal digits up to 16 digits:
Line 3,291:
=={{header|Julia}}==
To spare heap memory, keeps only the last 2 million values found for use in the generation of further values.
<
function counthumbledigits(maxdigits, returnsequencelength=50)
n, count, adjustindex, maxdiff = BigInt(1), 0, BigInt(0), 0
Line 3,334:
println(lpad(digitcounts[ndigits], 10), " have ", lpad(ndigits, 3), " digits.")
end
</
<pre>
828.693164 seconds (3.61 G allocations: 64.351 GiB, 51.37% gc time)
Line 3,447:
=={{header|Kotlin}}==
<
if (i <= 1) return true
if (i % 2 == 0) return isHumble(i / 2)
Line 3,486:
}
}
}</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 3,503:
=={{header|Lua}}==
{{trans|C}}
<
local n2 = math.floor(n)
Line 3,555:
end
main()</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 3,573:
Create a simple function which efficiently generates humble numbers up to an inputted max number, then call it twice to generate the output. Finds the number of humble numbers with digits up to 100 in 5 minutes.
<
Sort[Flatten@ParallelTable[
2^i 3^j 5^k 7^m, {i, 0, Log[2, max]}, {j, 0, Log[3, max/2^i]}, {k,
Line 3,582:
"\nDigits\[Rule]Count",
Rule @@@ Tally[IntegerLength /@ Drop[HumbleGenerator[10^100], -1]] //
Column} // Column</
{{out}}
Line 3,692:
=={{header|Nim}}==
A simple algorithm efficient enough to get the number of humble numbers with 18 digits in less than four seconds. To get further, we would have to use big numbers and a more efficient algorithm.
<
Line 3,749:
echo ""
echo "Count of humble numbers with n digits:"
showHumbleCount(18)</
{{out}}
Line 3,785:
float32 get wrong at 37 digits,->37 104925 instead of 104926<BR>
runtime: 2 x digits => ~ runtime 2^4 <BR>
<
{$IFDEF FPC}
{$MODE DELPHI}
Line 4,164:
first50;
GetDigitCounts(100);
End.</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 4,299:
=={{header|Perl}}==
<
use warnings;
use List::Util 'min';
Line 4,337:
printf "Digits: %2d - Count: %s\n", $digits++, $count;
$count = 1;
}</
{{out}}
<pre style="height:20ex">1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 4,398:
It will go all the way to 100 digits if you give it time (18 mins, on 64bit - 32bit runs out of memory after printing the 99th line)<br>
I also tried a log version (similar to [[Hamming_numbers#A_much_faster_logarithmic_version|Hamming_numbers]]) but inaccuracies with floor(h[n][LOG]) crept in quite early, at just 10 digits.
<!--<
<span style="color: #000080;font-style:italic;">-- demo/rosetta/humble.exw</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
Line 4,457:
<span style="color: #000000;">humble</span><span style="color: #0000FF;">(</span><span style="color: #000000;">50</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">humble</span><span style="color: #0000FF;">(</span><span style="color: #000000;">42</span><span style="color: #0000FF;">,</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
<!--</
{{out}}
<pre>
Line 4,513:
{{Trans|ALGOL W}}This can be compiled with the original 8080 PL/M compiler and run under CP/M or an emulator or clone.
Only handles Humble numbers with up to 4 digits as 8080 PL/M only has unsigned 8 and 16 bit integers.
<
BDOS: PROCEDURE( FN, ARG ); /* CP/M BDOS SYSTEM CALL */
DECLARE FN BYTE, ARG ADDRESS;
Line 4,588:
CALL PRINT$H$STAT( H3, 3 );
CALL PRINT$H$STAT( H4, 4 );
EOF</
{{out}}
<pre>
Line 4,607:
Note the use of text in column 81 onwards to hide the PL/I specifics from the PL/M compiler.<br><br>
Based on the PL/M version, note PL/I does not have the "walrus operator" (:=) which allows assignments to be nested in expressions, so it can't be used in the non-PL/M specific parts of this.
<
humble_100H: procedure options (main);
Line 4,721:
CALL PRHUMBLESTAT( H4, 4 );
EOF: end humble_100H;</
{{out}}
<pre>
Line 4,736:
=={{header|Python}}==
{{Works with|Python|3.7}}
<
from itertools import groupby, islice
Line 4,804:
# MAIN ---
if __name__ == '__main__':
main()</
{{Out}}
<pre>First 50 Humble numbers:
Line 4,831:
Uses <code>smoothwith</code> from [[N-smooth numbers#Quackery]], and <code>searchwith</code> from [[Binary search#Quackery]].
<
[ -1 peek [ 10 12 ** ] constant = ]
-1 split drop
Line 4,842:
say "-digit humble numbers" cr ]
drop
</syntaxhighlight>
{{out}}
Line 4,865:
{{trans|Go}}
<
(define (gen-humble-numbers N (kons #f) (k0 (void)))
Line 4,908:
(module+ main
(Humble-numbers))
</syntaxhighlight>
{{out}}
Line 4,948:
{{works with|Rakudo|2019.07.1}}
<syntaxhighlight lang="raku"
cache my \Smooth := gather {
my %i = (flat @list) Z=> (Smooth.iterator for ^@list);
Line 4,977:
$count = 1;
last if $digits > $upto;
}</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 5,033:
=={{header|REXX}}==
<
parse arg n m . /*obtain optional arguments from the CL*/
if n=='' | n=="," then n= 50 /*Not specified? Then use the default.*/
Line 5,076:
$.L= $.L + 1 /*bump the digit count for this number.*/
end /*h*/ /*the humble numbers are in the @ array*/
return /* " count results " " " $ " */</
{{out|output|text= when using the default inputs:}}
Line 5,152:
=={{header|Ring}}==
{{Improve|Ring|Makes zero attempt at the second part of the task}}
<
load "stdlib.ring"
Line 5,176:
see "" + numList[n] + " "
next
</syntaxhighlight>
Output:
<pre>
Line 5,187:
Checks if each number upto limit is humble number.
{{trans|Crystal}}
<
while i % 2 == 0; i /= 2 end
while i % 3 == 0; i /= 3 end
Line 5,209:
print "\n\nOf the first #{count} humble numbers:\n"
(1..digits).each { |num| printf("%5d have %2d digits\n", humble[num], num) }</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 5,228:
Generate humble numbers directly.
{{trans|Zkl}}
<
h = [1]
x2, x3, x5, x7 = 2, 3, 5, 7
Line 5,252:
print "First 50 Humble Numbers: \n"; (0...50).each { |i| print "#{h[i]} " }
print "\n\nOf the first #{count} humble numbers:\n"
(1..digits).each { |num| printf("%6d have %2d digits\n", counts[num], num) }</
{{out}}
<pre>First 50 Humble Numbers:
Line 5,310:
=={{header|Sidef}}==
<
var s = primes.len.of { [1] }
Line 5,338:
(c, d) = (0, n.len)
}
}</
{{out}}
<pre>
Line 5,368:
=={{header|Tcl}}==
<
proc humble? x {
foreach f {2 3 5 7} {
Line 5,380:
}
puts $t1
</syntaxhighlight>
Task 1:
{{out}}
Line 5,387:
Task 2, took a long while due to brute force:
<
proc task2 {nmax} {
puts "Distribution of digit length for the first $nmax humble numbers"
Line 5,400:
}
task2 4096
</syntaxhighlight>
{{out}}
<pre>~ $ time ./humble.tcl
Line 5,421:
=={{header|Visual Basic .NET}}==
{{trans|C#}}
<
Function IsHumble(i As Long) As Boolean
Line 5,482:
End Sub
End Module</
{{out}}
<pre>1 2 3 4 5 6 7 8 9 10 12 14 15 16 18 20 21 24 25 27 28 30 32 35 36 40 42 45 48 49 50 54 56 60 63 64 70 72 75 80 81 84 90 96 98 100 105 108 112 120
Line 5,503:
{{libheader|Wren-sort}}
Wren doesn't have arbitrary precision arithmetic and 'safe' integer operations are limited to a maximum absolute value of 2^53-1 (a 16 digit number). So there is no point in trying to generate humble numbers beyond that.
<
import "/math" for Int, Nums
import "/sort" for Find
Line 5,564:
var s = (i != 1) ? "s" : ""
System.print("%(Fmt.dc(9, counts[i])) have %(Fmt.d(2, i)) digit%(s)")
}</
{{out}}
Line 5,593:
{{trans|Go}}
{{libheader|GMP}} GNU Multiple Precision Arithmetic Library
<
var one = BI(1), two = BI(2), three = BI(3),
five = BI(5), seven = BI(7);
Line 5,610:
}
h
}</
<
const N = 5 * 1e6; // calculate the first 1 million humble numbers, say
h:=humble(N);
Line 5,624:
println("%2d %,9d".fmt(n,counts[n], n));
}
}</
{{out}}
<pre style="height:45ex">
|