Harmonic series
You are encouraged to solve this task according to the task description, using any language you may know.
This page uses content from Wikipedia. The original article was at Harmonic number. The list of authors can be seen in the page history. As with Rosetta Code, the text of Wikipedia is available under the GNU FDL. (See links for details on variance) |
In mathematics, the n-th harmonic number is the sum of the reciprocals of the first n natural numbers:
Hn = 1 + 1/2 + 1/3 + ... + 1/n
The series of harmonic numbers thus obtained is often loosely referred to as the harmonic series.
Harmonic numbers are closely related to the Riemann zeta function, and roughly approximate the natural logarithm function; differing by γ (lowercase Gamma), the Euler–Mascheroni constant.
The harmonic series is divergent, albeit quite slowly, and grows toward infinity.
- Task
- Write a function (routine, procedure, whatever it may be called in your language) to generate harmonic numbers.
- Use that procedure to show the values of the first 20 harmonic numbers.
- Find and show the position in the series of the first value greater than the integers 1 through 5
- Stretch
- Find and show the position in the series of the first value greater than the integers 6 through 10
- Related
ALGOL 68
Using standard lenghth REAL numbers this can find the first Harmonic number > 10, would probably need higher precision to find Harmonic numbers with larger values.
BEGIN # find some harmonic numbers, Hn is the sum of the reciprocals of 1..n #
# returns the first n Harmonic numbers #
OP HARMONIC = ( INT n )[]REAL:
BEGIN
[ 1 : n ]REAL h;
h[ 1 ] := 1;
FOR i FROM 2 TO n DO
h[ i ] := h[ i - 1 ] + ( 1 / i )
OD;
h
END # HARMONIC # ;
# find the first 20 000 harmonic numbers #
[]REAL h = HARMONIC 20 000;
# show the first 20 harmonic numbers #
FOR i TO 20 DO
print( ( whole( i, -2 ), ":", fixed( h[ i ], -14, 8 ), newline ) )
OD;
# find the positions of the first harmonic number > n where n in 1... #
INT rqd int := 1;
REAL rqd real := 1;
FOR i TO UPB h DO
IF h[ i ] > rqd real THEN
# found the first harmonic number greater than rqd real #
print( ( "Position of the first harmonic number > ", whole( rqd int, -2 ) ) );
print( ( ": ", whole( i, 0 ), newline ) );
rqd int +:= 1;
rqd real +:= 1
FI
OD
END
- Output:
1: 1.00000000 2: 1.50000000 3: 1.83333333 4: 2.08333333 5: 2.28333333 6: 2.45000000 7: 2.59285714 8: 2.71785714 9: 2.82896825 10: 2.92896825 11: 3.01987734 12: 3.10321068 13: 3.18013376 14: 3.25156233 15: 3.31822899 16: 3.38072899 17: 3.43955252 18: 3.49510808 19: 3.54773966 20: 3.59773966 Position of the first harmonic number > 1: 2 Position of the first harmonic number > 2: 4 Position of the first harmonic number > 3: 11 Position of the first harmonic number > 4: 31 Position of the first harmonic number > 5: 83 Position of the first harmonic number > 6: 227 Position of the first harmonic number > 7: 616 Position of the first harmonic number > 8: 1674 Position of the first harmonic number > 9: 4550 Position of the first harmonic number > 10: 12367
Arturo
H: function [n][
sum map 1..n => reciprocal
]
firstAbove: function [lim][
i: 1
while ø [
if lim < to :floating H i ->
return i
i: i + 1
]
]
print "The first 20 harmonic numbers:"
print map 1..20 => H
print ""
loop 1..4 'l [
print ["Position of first term >" l ":" firstAbove l]
]
- Output:
The first 20 harmonic numbers: 1/1 3/2 11/6 25/12 137/60 49/20 363/140 761/280 7129/2520 7381/2520 83711/27720 86021/27720 1145993/360360 1171733/360360 1195757/360360 2436559/720720 42142223/12252240 14274301/4084080 275295799/77597520 55835135/15519504 Position of first term > 1 : 2 Position of first term > 2 : 4 Position of first term > 3 : 11 Position of first term > 4 : 31
AWK
# syntax: GAWK -f HARMONIC_SERIES.AWK
# converted from FreeBASIC
BEGIN {
limit = 20
printf("The first %d harmonic numbers:\n",limit)
for (n=1; n<=limit; n++) {
h += 1/n
printf("%2d %11.8f\n",n,h)
}
print("")
h = 1
n = 2
for (i=2; i<=10; i++) {
while (h < i) {
h += 1/n
n++
}
printf("The first harmonic number > %2d is %11.8f at position %d\n",i,h,n-1)
}
exit(0)
}
- Output:
The first 20 harmonic numbers: 1 1.00000000 2 1.50000000 3 1.83333333 4 2.08333333 5 2.28333333 6 2.45000000 7 2.59285714 8 2.71785714 9 2.82896825 10 2.92896825 11 3.01987734 12 3.10321068 13 3.18013376 14 3.25156233 15 3.31822899 16 3.38072899 17 3.43955252 18 3.49510808 19 3.54773966 20 3.59773966 The first harmonic number > 2 is 2.08333333 at position 4 The first harmonic number > 3 is 3.01987734 at position 11 The first harmonic number > 4 is 4.02724520 at position 31 The first harmonic number > 5 is 5.00206827 at position 83 The first harmonic number > 6 is 6.00436671 at position 227 The first harmonic number > 7 is 7.00127410 at position 616 The first harmonic number > 8 is 8.00048557 at position 1674 The first harmonic number > 9 is 9.00020806 at position 4550 The first harmonic number > 10 is 10.00004301 at position 12367
BASIC
Applesoft BASIC
The MSX BASIC solution works without any changes.
BASIC256
h = 0.0
print "The first twenty harmonic numbers are:"
for n = 1 to 20
h += 1.0 / n
print n, h
next n
print
h = 1 : n = 2
for i = 2 to 10
while h < i
h += 1.0 / n
n += 1
end while
print "The first harmonic number greater than "; i; " is "; h; ", at position "; n-1
next i
end
CBASIC
limit = 20
h = 0
print "First";limit;"numbers in the harmonic series"
for i = 1 to 20
h = h + 1 / i
print using "## #.#####"; i; h
next i
for i = 1 to 5
h = 1
n = 2
while h <= i
h = h + 1 / n
n = n + 1
wend
print "Position of first harmonic number >"; i; "is at"; n-1
next i
end
- Output:
First 20 numbers in the harmonic series 1 1.00000 2 1.50000 3 1.83333 4 2.08333 5 2.28333 6 2.45000 7 2.59286 8 2.71786 9 2.82897 10 2.92897 11 3.01988 12 3.10321 13 3.18013 14 3.25156 15 3.31823 14 3.25156 15 3.31823 16 3.38073 17 3.43955 18 3.49511 19 3.54774 20 3.59774 Position of first harmonic number > 1 is at 2 Position of first harmonic number > 2 is at 4 Position of first harmonic number > 3 is at 11 Position of first harmonic number > 4 is at 31 Position of first harmonic number > 5 is at 83
Chipmunk Basic
100 cls
110 print "The first twenty harmonic numbers are:"
120 for n = 1 to 20
130 h = h+(1/n)
140 print n,h
150 next n
160 print
170 h = 1
180 n = 2
190 for i = 2 to 10
200 while h < i
210 h = h+(1/n)
220 n = n+1
230 wend
240 print "The first harmonic number greater than ";i;"is ";h;" at position ";n-1
250 next i
260 end
Craft Basic
precision 5
print "the first twenty harmonic numbers are:"
for n = 1 to 20
let h = h + 1 / n
print n, tab, h
next n
print newline, "the nth index of the first harmonic number that exceeds the nth integer:"
let h = 1
let n = 2
for i = 2 to 10
do
if h < i then
let h = h + 1 / n
let n = n + 1
endif
wait
loop h < i
print tab, n - 1,
next i
- Output:
the first twenty harmonic numbers are: 1 1 2 1.50000 3 1.83333 4 2.08333 5 2.28333 6 2.45000 7 2.59286 8 2.71786 9 2.82897 10 2.92897 11 3.01988 12 3.10321 13 3.18013 14 3.25156 15 3.31823 16 3.38073 17 3.43955 18 3.49511 19 3.54774 20 3.59774
The nth index of the first harmonic number that exceeds the nth integer: 4 11 31 83 227 616 1674 4550 12375
Gambas
Public Sub Main()
Dim h As Float = 0
Dim n As Integer, i As Integer
Print "The first twenty harmonic numbers are:"
For n = 1 To 20
h += 1 / n
Print n, h
Next
Print
h = 1
n = 2
For i = 2 To 10
While h < i
h += 1 / n
n += 1
Wend
Print "The first harmonic number greater than "; i; " is "; h; ", at position "; n - 1
Next
End
- Output:
Same as FreeBASIC entry.
GW-BASIC
The MSX BASIC solution works without any changes.
MSX Basic
100 CLS : REM HOME 100 HOME for Applesoft BASIC
110 PRINT "The first twenty harmonic numbers are:"
120 FOR n = 1 TO 20
130 h = h+(1/n)
140 PRINT n,h
150 NEXT n
160 PRINT
170 h = 1
180 n = 2
190 FOR i = 2 TO 10
200 IF NOT(h < i) THEN GOTO 240
210 h = h+(1/n)
220 n = n+1
230 GOTO 200
240 PRINT "The first harmonic number greater than " i "is " h "at position " n-1
250 NEXT i
260 END
QBasic
h = 0!
PRINT "The first twenty harmonic numbers are:"
FOR n = 1 TO 20
h = h + 1! / n
PRINT n, h
NEXT n
PRINT
h = 1: n = 2
FOR i = 2 TO 10
WHILE h < i
h = h + 1! / n
n = n + 1
WEND
PRINT "The first harmonic number greater than "; i; " is "; h; ", at position "; n - 1
NEXT i
END
Run BASIC
print "The first twenty harmonic numbers are:"
for n = 1 to 20
h = h + 1 / n
print n; chr$(9);h ' print n,h for Just BASIC and Liberty BASIC
next n
print
h = 1
n = 2
for i = 2 to 10
while h < i
h = h + 1 / n
n = n +1
wend
print "The first harmonic number greater than ";i; " is ";h;" at position ";n-1
next i
end
S-BASIC
var i, n = integer
var h = real.double
print "First 20 harmonic numbers:"
h = 0
for i = 1 to 20
h = h + 1 / i
print using "## #.######"; i; h
next i
for i = 1 to 5
h = 1
n = 2
while h <= i do
begin
h = h + 1 / n
n = n + 1
end
print "First term >"; i; " is at position"; n-1
next i
end
- Output:
First 20 harmonic numbers: 1 1.000000 2 1.500000 3 1.833333 4 2.083333 5 2.283333 6 2.450000 7 2.592857 8 2.717857 9 2.828968 10 2.928968 11 3.019877 12 3.103211 13 3.180134 14 3.251562 15 3.318229 16 3.380729 17 3.439553 18 3.495108 19 3.547740 20 3.597740 First term > 1 is at position 2 First term > 2 is at position 4 First term > 3 is at position 11 First term > 4 is at position 31 First term > 5 is at position 83
True BASIC
LET h = 0
PRINT "The first twenty harmonic numbers are:"
FOR n = 1 TO 20
LET h = h + 1 / n
PRINT n, h
NEXT n
PRINT
LET h = 1
LET n = 2
FOR i = 2 TO 10
DO WHILE h < i
LET h = h + 1 / n
LET n = n + 1
LOOP
PRINT "The first harmonic number greater than "; i; " is "; h; ", at position "; n - 1
NEXT i
END
Yabasic
h = 0.0
print "The first twenty harmonic numbers are:"
for n = 1 to 20
h = h + 1.0 / n
print n, chr$(9), h
next n
print
h = 1 : n = 2
for i = 2 to 10
while h < i
h = h + 1.0 / n
n = n + 1
wend
print "The first harmonic number greater than ", i, " is ", h, ", at position ", n-1
next i
end
BQN
Harmonic ← +`1÷∘+↕
⟨
> 8↑⟜•Fmt¨ 5e¯7+ Harmonic 20
1+⍉(⊣≍(⌈ Harmonic 12400)⊐2+⊢)↕10
⟩
- Output:
┌─ · ┌─ ┌─ ╵"1.000000 ╵ 1 2 1.500000 2 4 1.833333 3 11 2.083333 4 31 2.283333 5 83 2.450000 6 227 2.592857 7 616 2.717857 8 1674 2.828968 9 4550 2.928968 10 12367 3.019877 ┘ 3.103211 3.180134 3.251562 3.318229 3.380729 3.439553 3.495108 3.547740 3.597740" ┘ ┘
Bruijn
:import std/List .
:import std/Combinator .
:import std/Math/Rational Q
:import std/Number N
# fun Church iteration hack
harmonic [0 &[[(Q.add 1 op) : N.++0]] start [[1]]] ⧗ Unary → Rational
op (+1) : N.--0
start (+0.0f) : (+1)
custom-gt? &[[[N.gt? 2 (N.mul 0 N.++1)]]] ⧗ Rational → Νumber → Boolean
main [φ cons first-20 first-10-above (harmonic <$> (iterate [[[1 (2 1 0)]]] (+0u)))]
first-20 take (+20)
first-10-above [take (+10) first-above]
first-above [find-index [custom-gt? 0 1] 1] <$> (iterate N.inc (+0))
Takes a *long* time, but will return the correct result.
C
Isolating the calculation in a function is inefficient when simply generating a sequence, since the computation of each term repeats, rather than builds upon, the preceding term. But it may prove useful in other contexts, and, in any event, is what the task description seems to require.
#include <stdio.h>
#include <stdlib.h>
/* return nth harmonic number */
double harmonic(int n) {
double h, i;
h = 0;
for (i = 1; i <= (double) n; i += 1.0)
h += 1 / i;
return h;
}
int main(void) {
int i, n;
printf("First 20 harmonic numbers:\n");
for (i = 1; i <= 20; i++)
printf("%2d %8.6lf\n", i, harmonic(i));
for (i = 1; i <= 5; i++) {
int n = 2;
while (harmonic(n) <= (double) i) n++;
printf("First term > %d is at position %d\n", i, n);
}
return EXIT_SUCCESS;
}
- Output:
First 20 numbers in the harmonic series: 1 1.000000 2 1.500000 3 1.833333 4 2.083333 5 2.283333 6 2.450000 7 2.592857 8 2.717857 9 2.828968 10 2.928968 11 3.019877 12 3.103211 13 3.180134 14 3.251562 15 3.318229 16 3.380729 17 3.439553 18 3.495108 19 3.547740 20 3.597740 First term > 1 is at position 2 First term > 2 is at position 4 First term > 3 is at position 11 First term > 4 is at position 31 First term > 5 is at position 83
C#
using System;
using System.Numerics;
public class BigRational
{
public BigInteger Numerator { get; private set; }
public BigInteger Denominator { get; private set; }
public BigRational(BigInteger numerator, BigInteger denominator)
{
if (denominator == 0)
throw new ArgumentException("Denominator cannot be zero.", nameof(denominator));
BigInteger gcd = BigInteger.GreatestCommonDivisor(numerator, denominator);
Numerator = numerator / gcd;
Denominator = denominator / gcd;
if (Denominator < 0)
{
Numerator = -Numerator;
Denominator = -Denominator;
}
}
public static BigRational operator +(BigRational a, BigRational b)
{
return new BigRational(a.Numerator * b.Denominator + b.Numerator * a.Denominator, a.Denominator * b.Denominator);
}
public override string ToString()
{
return $"{Numerator}/{Denominator}";
}
}
class Program
{
static BigRational Harmonic(int n)
{
BigRational sum = new BigRational(0, 1);
for (int i = 1; i <= n; i++)
{
BigRational r = new BigRational(1, i);
sum += r;
}
return sum;
}
static void Main(string[] args)
{
Console.WriteLine("The first 20 harmonic numbers and the 100th, expressed in rational form, are:");
int[] numbers = new int[21];
for (int i = 1; i <= 20; i++)
{
numbers[i - 1] = i;
}
numbers[20] = 100;
foreach (int i in numbers)
{
Console.WriteLine($"{i,3} : {Harmonic(i)}");
}
Console.WriteLine("\nThe first harmonic number to exceed the following integers is:");
const int limit = 10;
for (int i = 1, n = 1; i <= limit; n++)
{
double h = 0;
for (int j = 1; j <= n; j++)
{
h += 1.0 / j;
}
if (h > i)
{
Console.WriteLine($"integer = {i,2} -> n = {n,6} -> harmonic number = {h,9:F6} (to 6dp)");
i++;
}
}
}
}
- Output:
The first 20 harmonic numbers and the 100th, expressed in rational form, are: 1 : 1/1 2 : 3/2 3 : 11/6 4 : 25/12 5 : 137/60 6 : 49/20 7 : 363/140 8 : 761/280 9 : 7129/2520 10 : 7381/2520 11 : 83711/27720 12 : 86021/27720 13 : 1145993/360360 14 : 1171733/360360 15 : 1195757/360360 16 : 2436559/720720 17 : 42142223/12252240 18 : 14274301/4084080 19 : 275295799/77597520 20 : 55835135/15519504 100 : 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 The first harmonic number to exceed the following integers is: integer = 1 -> n = 2 -> harmonic number = 1.500000 (to 6dp) integer = 2 -> n = 4 -> harmonic number = 2.083333 (to 6dp) integer = 3 -> n = 11 -> harmonic number = 3.019877 (to 6dp) integer = 4 -> n = 31 -> harmonic number = 4.027245 (to 6dp) integer = 5 -> n = 83 -> harmonic number = 5.002068 (to 6dp) integer = 6 -> n = 227 -> harmonic number = 6.004367 (to 6dp) integer = 7 -> n = 616 -> harmonic number = 7.001274 (to 6dp) integer = 8 -> n = 1674 -> harmonic number = 8.000486 (to 6dp) integer = 9 -> n = 4550 -> harmonic number = 9.000208 (to 6dp) integer = 10 -> n = 12367 -> harmonic number = 10.000043 (to 6dp)
C++
#include <iomanip>
#include <iostream>
#include <boost/rational.hpp>
#include <boost/multiprecision/gmp.hpp>
using integer = boost::multiprecision::mpz_int;
using rational = boost::rational<integer>;
class harmonic_generator {
public:
rational next() {
rational result = term_;
term_ += rational(1, ++n_);
return result;
}
void reset() {
n_ = 1;
term_ = 1;
}
private:
integer n_ = 1;
rational term_ = 1;
};
int main() {
std::cout << "First 20 harmonic numbers:\n";
harmonic_generator hgen;
for (int i = 1; i <= 20; ++i)
std::cout << std::setw(2) << i << ". " << hgen.next() << '\n';
rational h;
for (int i = 1; i <= 80; ++i)
h = hgen.next();
std::cout << "\n100th harmonic number: " << h << "\n\n";
int n = 1;
hgen.reset();
for (int i = 1; n <= 10; ++i) {
if (hgen.next() > n)
std::cout << "Position of first term > " << std::setw(2) << n++ << ": " << i << '\n';
}
}
- Output:
First 20 harmonic numbers: 1. 1/1 2. 3/2 3. 11/6 4. 25/12 5. 137/60 6. 49/20 7. 363/140 8. 761/280 9. 7129/2520 10. 7381/2520 11. 83711/27720 12. 86021/27720 13. 1145993/360360 14. 1171733/360360 15. 1195757/360360 16. 2436559/720720 17. 42142223/12252240 18. 14274301/4084080 19. 275295799/77597520 20. 55835135/15519504 100th harmonic number: 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 Position of first term > 1: 2 Position of first term > 2: 4 Position of first term > 3: 11 Position of first term > 4: 31 Position of first term > 5: 83 Position of first term > 6: 227 Position of first term > 7: 616 Position of first term > 8: 1674 Position of first term > 9: 4550 Position of first term > 10: 12367
COBOL
IDENTIFICATION DIVISION.
PROGRAM-ID. HARMONIC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 VARS.
03 N PIC 9(5) VALUE ZERO.
03 HN PIC 9(2)V9(12) VALUE ZERO.
03 INT PIC 99 VALUE ZERO.
01 OUT-VARS.
03 POS PIC Z(4)9.
03 FILLER PIC X(3) VALUE SPACES.
03 H-OUT PIC Z9.9(12).
PROCEDURE DIVISION.
BEGIN.
DISPLAY "First 20 harmonic numbers:"
PERFORM SHOW-HARMONIC 20 TIMES.
DISPLAY SPACES.
MOVE ZERO TO N, HN.
DISPLAY "First harmonic number to exceed whole number:"
PERFORM EXCEED-INT 10 TIMES.
STOP RUN.
SHOW-HARMONIC.
PERFORM NEXT-HARMONIC.
MOVE HN TO H-OUT.
DISPLAY H-OUT.
EXCEED-INT.
ADD 1 TO INT.
PERFORM NEXT-HARMONIC UNTIL HN IS GREATER THAN INT.
MOVE N TO POS.
MOVE HN TO H-OUT.
DISPLAY OUT-VARS.
NEXT-HARMONIC.
ADD 1 TO N.
COMPUTE HN = HN + 1 / N.
- Output:
First 20 harmonic numbers: 1.000000000000 1.500000000000 1.833333333333 2.083333333333 2.283333333333 2.449999999999 2.592857142856 2.717857142856 2.828968253967 2.928968253967 3.019877344876 3.103210678209 3.180133755132 3.251562326560 3.318228993226 3.380728993226 3.439552522637 3.495108078192 3.547739657139 3.597739657139 First harmonic number to exceed whole number: 2 1.500000000000 4 2.083333333333 11 3.019877344876 31 4.027245195428 83 5.002068272651 227 6.004366708257 616 7.001274096877 1674 8.000485571261 4550 9.000208060802 12367 10.000043002313
Delphi
function HarmonicNumber(N: integer): double;
{Calculate sum of }
var I: integer;
begin
Result:=0;
for I:=1 to N do Result:=Result+1/I;
end;
function FirstHarmonicOver(Limit: integer): integer;
{Find first harmonic number over limit}
var HN: double;
begin
for Result:=1 to high(Integer) do
begin
HN:=HarmonicNumber(Result);
if HN>Limit then exit;
end
end;
procedure ShowHarmonicNumbers(Memo: TMemo);
var I,Inx: integer;
var HN: double;
begin
{Show first 20 harmonic numbers}
for I:=1 to 20 do
begin
HN:=HarmonicNumber(I);
Memo.Lines.Add(Format('%2D: %8.8f',[I,HN]));
end;
{Show the position of the number that exceeds 1..10 }
for I:=1 to 10 do
begin
Inx:=FirstHarmonicOver(I);
Memo.Lines.Add(Format('Position of the first harmonic number > %2D: %4D',[I,Inx]))
end;
end;
- Output:
1: 1.00000000 2: 1.50000000 3: 1.83333333 4: 2.08333333 5: 2.28333333 6: 2.45000000 7: 2.59285714 8: 2.71785714 9: 2.82896825 10: 2.92896825 11: 3.01987734 12: 3.10321068 13: 3.18013376 14: 3.25156233 15: 3.31822899 16: 3.38072899 17: 3.43955252 18: 3.49510808 19: 3.54773966 20: 3.59773966 Position of the first harmonic number > 1: 2 Position of the first harmonic number > 2: 4 Position of the first harmonic number > 3: 11 Position of the first harmonic number > 4: 31 Position of the first harmonic number > 5: 83 Position of the first harmonic number > 6: 227 Position of the first harmonic number > 7: 616 Position of the first harmonic number > 8: 1674 Position of the first harmonic number > 9: 4550 Position of the first harmonic number > 10: 12367
EasyLang
numfmt 5 2
print "The first twenty harmonic numbers are:"
for n = 1 to 20
h += 1 / n
print n & " " & h
.
print ""
print "The first harmonic number greater than: "
h = 1
n = 2
for i = 2 to 10
while h < i
h += 1 / n
n += 1
.
print i & " is " & h & ", at position " & n - 1
.
- Output:
The first twenty harmonic numbers are: 1 1 2 1.50000 3 1.83333 4 2.08333 5 2.28333 6 2.45000 7 2.59286 8 2.71786 9 2.82897 10 2.92897 11 3.01988 12 3.10321 13 3.18013 14 3.25156 15 3.31823 16 3.38073 17 3.43955 18 3.49511 19 3.54774 20 3.59774 The first harmonic number greater than: 2 is 2.08333, at position 4 3 is 3.01988, at position 11 4 is 4.02725, at position 31 5 is 5.00207, at position 83 6 is 6.00437, at position 227 7 is 7.00127, at position 616 8 is 8.00049, at position 1674 9 is 9.00021, at position 4550 10 is 10.00004, at position 12367
Factor
This solution uses the following (rather accurate) approximation of the harmonic numbers to find the first indices greater than the integers:
Hn ≈ ln(n) + γ + 1/2n - 1/12n2
where γ
is the Euler-Mascheroni constant, approximately 0.5772156649
.
USING: formatting grouping io kernel lists lists.lazy math
math.functions math.ranges math.statistics math.text.english
prettyprint sequences tools.memory.private ;
! Euler-Mascheroni constant
CONSTANT: γ 0.5772156649
: Hn-approx ( n -- ~Hn )
[ log γ + 1 2 ] [ * /f + 1 ] [ sq 12 * /f - ] tri ;
: lharmonics ( -- list ) 1 lfrom [ Hn-approx ] lmap-lazy ;
: first-gt ( m -- n ) lharmonics swap '[ _ < ] lwhile llength ;
"First twenty harmonic numbers as mixed numbers:" print
100 [1,b] [ recip ] map cum-sum
[ 20 head 5 group simple-table. nl ]
[ "One hundredth:" print last . nl ] bi
"(zero based) Index of first value:" print
10 [1,b] [
dup first-gt [ commas ] [ 1 + number>text ] bi
" greater than %2d: %6s (term number %s)\n" printf
] each
- Output:
First twenty harmonic numbers as mixed numbers: 1 1+1/2 1+5/6 2+1/12 2+17/60 2+9/20 2+83/140 2+201/280 2+2089/2520 2+2341/2520 3+551/27720 3+2861/27720 3+64913/360360 3+90653/360360 3+114677/360360 3+274399/720720 3+5385503/12252240 3+2022061/4084080 3+42503239/77597520 3+9276623/15519504 One hundredth: 5+522561233577855727314756256041670736351/2788815009188499086581352357412492142272 (zero based) Index of first value: greater than 1: 1 (term number two) greater than 2: 3 (term number four) greater than 3: 10 (term number eleven) greater than 4: 30 (term number thirty-one) greater than 5: 82 (term number eighty-three) greater than 6: 226 (term number two hundred and twenty-seven) greater than 7: 615 (term number six hundred and sixteen) greater than 8: 1,673 (term number one thousand, six hundred and seventy-four) greater than 9: 4,549 (term number four thousand, five hundred and fifty) greater than 10: 12,366 (term number twelve thousand, three hundred and sixty-seven)
Forth
Uses fixed point computation which is more traditional in FORTH.
warnings off
1.000.000.000.000.000 drop constant 1.0fx \ fractional part is 15 decimal digits.
: .h ( n -- )
s>d <# 14 for # next [char] . hold #s #> type space ;
1.0fx 1 2constant first-harmonic
: round 5 + 10 / ;
: next-harmonic ( h n -- h' n' )
1+ tuck [ 1.0fx 10 * ] literal swap / round + swap ;
: task1
first-harmonic 19 for over cr .h next-harmonic next 2drop ;
: task2
first-harmonic
11 1 do
begin over i 1.0fx * <= while
next-harmonic
repeat
dup .
loop 2drop ;
." The first 10 harmonic numbers: " task1 cr cr
." The nth index of the first harmonic number that exceeds the nth integer: " cr task2 cr
bye
- Output:
The first 10 harmonic numbers: 1.000000000000000 1.500000000000000 1.833333333333333 2.083333333333333 2.283333333333333 2.450000000000000 2.592857142857143 2.717857142857143 2.828968253968254 2.928968253968254 3.019877344877345 3.103210678210678 3.180133755133755 3.251562326562326 3.318228993228993 3.380728993228993 3.439552522640758 3.495108078196314 3.547739657143682 3.597739657143682 The nth index of the first harmonic number that exceeds the nth integer: 2 4 11 31 83 227 616 1674 4550 12367
FreeBASIC
dim as double h = 0.0
dim as uinteger n, i
print "The first twenty harmonic numbers are:"
for n = 1 to 20
h += 1.0/n
print n, h
next n
h = 1 : n = 2
for i=2 to 10
while h<i
h+=1.0/n
n+=1
wend
print "The first harmonic number greater than ";i;" is ";h;", at position ";n-1
next i
- Output:
The first twenty harmonic numbers are:1 1 2 1.5 3 1.833333333333333 4 2.083333333333333 5 2.283333333333333 6 2.45 7 2.592857142857143 8 2.717857142857143 9 2.828968253968254 10 2.928968253968254 11 3.019877344877345 12 3.103210678210678 13 3.180133755133755 14 3.251562326562327 15 3.318228993228994 16 3.380728993228994 17 3.439552522640758 18 3.495108078196314 19 3.547739657143682 20 3.597739657143682 The first harmonic number greater than 2 is 2.083333333333333, at position 4 The first harmonic number greater than 3 is 3.019877344877345, at position 11 The first harmonic number greater than 4 is 4.02724519543652, at position 31 The first harmonic number greater than 5 is 5.002068272680166, at position 83 The first harmonic number greater than 6 is 6.004366708345567, at position 227 The first harmonic number greater than 7 is 7.001274097134162, at position 616 The first harmonic number greater than 8 is 8.000485571995782, at position 1674 The first harmonic number greater than 9 is 9.000208062931115, at position 4550
The first harmonic number greater than 10 is 10.00004300827578, at position 12367
FutureBasic
include "NSLog.incl"
void local fn BuildHamonics
double h = 0.0
long i, n
NSLog( @"The first twenty harmonic numbers are:\n" )
for i = 1 to 20
h = h + 1.0 / i
NSLog( @"%3d. %.8f", i, h )
next
NSLog( @"\n" )
h = 1 : n = 2
for i = 2 to 10
while h < i
h = h + 1.0 / n
n = n + 1
wend
NSLog( @"The first harmonic number > %2d is %11.8f at position %d.", i, h, n -1 )
next
end fn
fn BuildHamonics
HandleEvents
- Output:
The first twenty harmonic numbers are: 1. 1.00000000 2. 1.50000000 3. 1.83333333 4. 2.08333333 5. 2.28333333 6. 2.45000000 7. 2.59285714 8. 2.71785714 9. 2.82896825 10. 2.92896825 11. 3.01987734 12. 3.10321068 13. 3.18013376 14. 3.25156233 15. 3.31822899 16. 3.38072899 17. 3.43955252 18. 3.49510808 19. 3.54773966 20. 3.59773966 The first harmonic number > 2 is 2.08333333 at position 4. The first harmonic number > 3 is 3.01987734 at position 11. The first harmonic number > 4 is 4.02724520 at position 31. The first harmonic number > 5 is 5.00206827 at position 83. The first harmonic number > 6 is 6.00436671 at position 227. The first harmonic number > 7 is 7.00127410 at position 616. The first harmonic number > 8 is 8.00048557 at position 1674. The first harmonic number > 9 is 9.00020806 at position 4550. The first harmonic number > 10 is 10.00004301 at position 12367.
Go
package main
import (
"fmt"
"math/big"
)
func harmonic(n int) *big.Rat {
sum := new(big.Rat)
for i := int64(1); i <= int64(n); i++ {
r := big.NewRat(1, i)
sum.Add(sum, r)
}
return sum
}
func main() {
fmt.Println("The first 20 harmonic numbers and the 100th, expressed in rational form, are:")
numbers := make([]int, 21)
for i := 1; i <= 20; i++ {
numbers[i-1] = i
}
numbers[20] = 100
for _, i := range numbers {
fmt.Printf("%3d : %s\n", i, harmonic(i))
}
fmt.Println("\nThe first harmonic number to exceed the following integers is:")
const limit = 10
for i, n, h := 1, 1, 0.0; i <= limit; n++ {
h += 1.0 / float64(n)
if h > float64(i) {
fmt.Printf("integer = %2d -> n = %6d -> harmonic number = %9.6f (to 6dp)\n", i, n, h)
i++
}
}
}
- Output:
The first 20 harmonic numbers and the 100th, expressed in rational form, are: 1 : 1/1 2 : 3/2 3 : 11/6 4 : 25/12 5 : 137/60 6 : 49/20 7 : 363/140 8 : 761/280 9 : 7129/2520 10 : 7381/2520 11 : 83711/27720 12 : 86021/27720 13 : 1145993/360360 14 : 1171733/360360 15 : 1195757/360360 16 : 2436559/720720 17 : 42142223/12252240 18 : 14274301/4084080 19 : 275295799/77597520 20 : 55835135/15519504 100 : 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 The first harmonic number to exceed the following integers is: integer = 1 -> n = 2 -> harmonic number = 1.500000 (to 6dp) integer = 2 -> n = 4 -> harmonic number = 2.083333 (to 6dp) integer = 3 -> n = 11 -> harmonic number = 3.019877 (to 6dp) integer = 4 -> n = 31 -> harmonic number = 4.027245 (to 6dp) integer = 5 -> n = 83 -> harmonic number = 5.002068 (to 6dp) integer = 6 -> n = 227 -> harmonic number = 6.004367 (to 6dp) integer = 7 -> n = 616 -> harmonic number = 7.001274 (to 6dp) integer = 8 -> n = 1674 -> harmonic number = 8.000486 (to 6dp) integer = 9 -> n = 4550 -> harmonic number = 9.000208 (to 6dp) integer = 10 -> n = 12367 -> harmonic number = 10.000043 (to 6dp)
Haskell
import Data.List (find)
import Data.Ratio
--------------------- HARMONIC SERIES --------------------
harmonic :: [Rational]
harmonic =
scanl1
(\a x -> a + 1 / x)
[1 ..]
-------------------------- TESTS -------------------------
main :: IO ()
main = do
putStrLn "First 20 terms:"
mapM_ putStrLn $
showRatio <$> take 20 harmonic
putStrLn "\n100th term:"
putStrLn $ showRatio (harmonic !! 99)
putStrLn ""
putStrLn "One-based indices of first terms above threshold values:"
let indexedHarmonic = zip [0 ..] harmonic
mapM_
putStrLn
$ fmap
( showFirstLimit
<*> \n -> find ((> n) . snd) indexedHarmonic
)
[1 .. 10]
-------------------- DISPLAY FORMATTING ------------------
showFirstLimit n (Just (i, r)) =
"Term "
<> show (succ i)
<> " is the first above "
<> show (numerator n)
showRatio :: Ratio Integer -> String
showRatio =
((<>) . show . numerator)
<*> (('/' :) . show . denominator)
- Output:
First 20 terms: 1/1 3/2 11/6 25/12 137/60 49/20 363/140 761/280 7129/2520 7381/2520 83711/27720 86021/27720 1145993/360360 1171733/360360 1195757/360360 2436559/720720 42142223/12252240 14274301/4084080 275295799/77597520 55835135/15519504 100th term: 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 One-based indices of first terms above threshold values: Term 2 is the first above 1 Term 4 is the first above 2 Term 11 is the first above 3 Term 31 is the first above 4 Term 83 is the first above 5 Term 227 is the first above 6 Term 616 is the first above 7 Term 1674 is the first above 8 Term 4550 is the first above 9 Term 12367 is the first above 10
J
To calculate a specific value in the harmonic series, we might define:
Hn=: {{ +/ %1+i.y }}"0
Inspecting the first 20 values from Hn, we see:
Hn i.4 5
0 1 1.5 1.83333 2.08333
2.28333 2.45 2.59286 2.71786 2.82897
2.92897 3.01988 3.10321 3.18013 3.25156
3.31823 3.38073 3.43955 3.49511 3.54774
However, this is inefficient -- we're regenerating the sequence each time just to add one more term. So, instead, we should move that i.
inside our harmonic series generator:
Hni=: {{ 0,+/\ %1+i.y}}
Note that we've added an explicit 0 here -- that's both for compatibility with Hn
and to ensure that the Hn value at index 1 has the value 1. (We're using a running sum here, which omits the empty case, but that empty case was relevant for us...)
Anyways:
4 5$Hni 20
0 1 1.5 1.83333 2.08333
2.28333 2.45 2.59286 2.71786 2.82897
2.92897 3.01988 3.10321 3.18013 3.25156
3.31823 3.38073 3.43955 3.49511 3.54774
Inspecting values from the series, we see that 1e5 terms will get us into numbers larger than 12:
Hn 1e5
12.0901
So, we can show the index values of the first harmonic numbers which match or exceed integer values:
(Hni 1e5) (] ,. I. ,. I. { [) i.13
0 0 0
1 1 1
2 4 2.08333
3 11 3.01988
4 31 4.02725
5 83 5.00207
6 227 6.00437
7 616 7.00127
8 1674 8.00049
9 4550 9.00021
10 12367 10
11 33617 11
12 91380 12
Of course, the later values are not precise integers -- but their fractional part is not significant for J's default display precision:
(Hn 91380)-12
3.05167e_6
Java
Java does not have a built-in fraction type, so we create our own class Rational.
import java.math.BigInteger;
public class HarmonicSeries {
public static void main(String[] aArgs) {
System.out.println("The first twenty Harmonic numbers:");
for ( int i = 1; i <= 20; i++ ) {
System.out.println(String.format("%2s", i) + ": " + harmonicNumber(i));
}
System.out.println();
for ( int i = 1; i <= 10; i++ ) {
System.out.print("The first term greater than ");
System.out.println(String.format("%2s%s%5s", i, " is Term ", indexedHarmonic(i)));
}
}
private static Rational harmonicNumber(int aNumber) {
Rational result = Rational.ZERO;
for ( int i = 1; i <= aNumber; i++ ) {
result = result.add( new Rational(BigInteger.ONE, BigInteger.valueOf(i)) );
}
return result;
}
private static int indexedHarmonic(int aTarget) {
BigInteger target = BigInteger.valueOf(aTarget);
Rational harmonic = Rational.ZERO;
BigInteger next = BigInteger.ZERO;
while ( harmonic.numerator.compareTo(target.multiply(harmonic.denominator)) <= 0 ) {
next = next.add(BigInteger.ONE);
harmonic = harmonic.add( new Rational(BigInteger.ONE, next) );
}
return next.intValueExact();
}
private static class Rational {
private Rational(BigInteger aNumerator, BigInteger aDenominator) {
numerator = aNumerator;
denominator = aDenominator;
BigInteger gcd = numerator.gcd(denominator);
numerator = numerator.divide(gcd);
denominator = denominator.divide(gcd);
}
@Override
public String toString() {
return numerator + " / " + denominator;
}
private Rational add(Rational aRational) {
BigInteger numer = numerator.multiply(aRational.denominator)
.add(aRational.numerator.multiply(denominator));
BigInteger denom = aRational.denominator.multiply(denominator);
return new Rational(numer, denom);
}
private BigInteger numerator;
private BigInteger denominator;
private static final Rational ZERO = new Rational(BigInteger.ZERO, BigInteger.ONE);
}
}
- Output:
The first twenty Harmonic numbers: 1: 1 / 1 2: 3 / 2 3: 11 / 6 4: 25 / 12 5: 137 / 60 6: 49 / 20 7: 363 / 140 8: 761 / 280 9: 7129 / 2520 10: 7381 / 2520 11: 83711 / 27720 12: 86021 / 27720 13: 1145993 / 360360 14: 1171733 / 360360 15: 1195757 / 360360 16: 2436559 / 720720 17: 42142223 / 12252240 18: 14274301 / 4084080 19: 275295799 / 77597520 20: 55835135 / 15519504 The first term greater than 1 is Term 2 The first term greater than 2 is Term 4 The first term greater than 3 is Term 11 The first term greater than 4 is Term 31 The first term greater than 5 is Term 83 The first term greater than 6 is Term 227 The first term greater than 7 is Term 616 The first term greater than 8 is Term 1674 The first term greater than 9 is Term 4550 The first term greater than 10 is Term 12367
jq
Works with gojq, the Go implementation of jq
This entry requires a rational arithmetic module such as is available at Arithmetic/Rational#jq.
# include "rational"; # a reminder
def harmonic:
reduce range(1; 1+.) as $i ( r(0;1);
radd(.; r(1; $i) ));
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
def task1:
"The first 20 harmonic numbers and the 100th, expressed in rational form, are:",
(range(1;21), 100
| "\(.) : \(harmonic|rpp)" );
def task2($limit):
"The first harmonic number to exceed the following integers is:",
limit($limit;
foreach range(0; infinite) as $n (
{i: 1, n: 1, h: r(0;1)};
.emit = false
| .h = radd(.h; r(1; .n))
| .i as $i
| if .h | rgreaterthan($i)
then .emit = "integer = \(.i|lpad(2)) -> n = \(.n| lpad(6)) -> harmonic number = \(.h|r_to_decimal(6)) (to 6dp)"
| .i += 1
else .
end
| .n += 1;
select(.emit).emit) );
task1, "", task2(10)
- Output:
The first 20 harmonic numbers and the 100th, expressed in rational form, are: 1 : 1 // 1 2 : 3 // 2 3 : 11 // 6 4 : 25 // 12 5 : 137 // 60 6 : 49 // 20 7 : 363 // 140 8 : 761 // 280 9 : 7129 // 2520 10 : 7381 // 2520 11 : 83711 // 27720 12 : 86021 // 27720 13 : 1145993 // 360360 14 : 1171733 // 360360 15 : 1195757 // 360360 16 : 2436559 // 720720 17 : 42142223 // 12252240 18 : 14274301 // 4084080 19 : 275295799 // 77597520 20 : 55835135 // 15519504 100 : 14466636279520351160221518043104131447711 // 2788815009188499086581352357412492142272 The first harmonic number to exceed the following integers is: integer = 1 -> n = 2 -> harmonic number = 1.5 (to 6dp) integer = 2 -> n = 4 -> harmonic number = 2.083333 (to 6dp) integer = 3 -> n = 11 -> harmonic number = 3.019877 (to 6dp) integer = 4 -> n = 31 -> harmonic number = 4.027245 (to 6dp) integer = 5 -> n = 83 -> harmonic number = 5.002068 (to 6dp) integer = 6 -> n = 227 -> harmonic number = 6.004366 (to 6dp) integer = 7 -> n = 616 -> harmonic number = 7.001274 (to 6dp) integer = 8 -> n = 1674 -> harmonic number = 8.000485 (to 6dp) integer = 9 -> n = 4550 -> harmonic number = 9.000208 (to 6dp) integer = 10 -> n = 12367 -> harmonic number = 10.000043 (to 6dp)
Julia
const memoizer = [BigFloat(1.0), BigFloat(1.5)]
"""
harmonic(n::Integer)::BigFloat
Calculates harmonic numbers. The integer argument `n` should be positive.
"""
function harmonic(n::Integer)::BigFloat
if n < 0
throw(DomainError(n))
elseif n == 0
return BigFloat(0.0) # by convention
elseif length(memoizer) >= n
return memoizer[n]
elseif length(memoizer) + 1 == n
h = memoizer[end] + BigFloat(1.0) / n
push!(memoizer, h)
return h
elseif n < 1_000_000
start, x = length(memoizer), memoizer[end]
for i in start+1:n
push!(memoizer, (x += big"1.0" / i))
end
return memoizer[end]
else
# use H(n) = eulergamma + digamma(n + 1), instead, if memory use of memoization too large
x = n + big"1.0"
digam = BigFloat()
ccall((:mpfr_digamma, :libmpfr), Int32, (Ref{BigFloat}, Ref{BigFloat}, Int32), digam, x, 1)
return Base.MathConstants.eulergamma + digam
end
end
function testharmonics(upperlimit = 11)
n = 1
while (h = harmonic(n)) < upperlimit
nextintegerfloor = h < 1.8 ? h > 1.0 : floor(h) > floor(memoizer[n - 1])
if n < 21 || nextintegerfloor
println("harmonic($n) = $h")
nextintegerfloor && println(" $n is also the term number for the first harmonic > $(floor(h))")
end
n += 1
end
end
testharmonics()
- Output:
harmonic(1) = 1.0 harmonic(2) = 1.5 2 is also the term number for the first harmonic > 1.0 harmonic(3) = 1.833333333333333333333333333333333333333333333333333333333333333333333333333339 harmonic(4) = 2.083333333333333333333333333333333333333333333333333333333333333333333333333356 4 is also the term number for the first harmonic > 2.0 harmonic(5) = 2.283333333333333333333333333333333333333333333333333333333333333333333333333363 harmonic(6) = 2.450000000000000000000000000000000000000000000000000000000000000000000000000041 harmonic(7) = 2.592857142857142857142857142857142857142857142857142857142857142857142857142913 harmonic(8) = 2.717857142857142857142857142857142857142857142857142857142857142857142857142913 harmonic(9) = 2.828968253968253968253968253968253968253968253968253968253968253968253968254009 harmonic(10) = 2.928968253968253968253968253968253968253968253968253968253968253968253968253995 harmonic(11) = 3.019877344877344877344877344877344877344877344877344877344877344877344877344889 11 is also the term number for the first harmonic > 3.0 harmonic(12) = 3.103210678210678210678210678210678210678210678210678210678210678210678210678211 harmonic(13) = 3.180133755133755133755133755133755133755133755133755133755133755133755133755123 harmonic(14) = 3.251562326562326562326562326562326562326562326562326562326562326562326562326542 harmonic(15) = 3.318228993228993228993228993228993228993228993228993228993228993228993228993199 harmonic(16) = 3.380728993228993228993228993228993228993228993228993228993228993228993228993199 harmonic(17) = 3.439552522640757934875581934405463817228523110876052052522640757934875581934384 harmonic(18) = 3.495108078196313490431137489961019372784078666431607608078196313490431137489932 harmonic(19) = 3.547739657143681911483769068908387793836710245378976029130827892437799558542556 harmonic(20) = 3.597739657143681911483769068908387793836710245378976029130827892437799558542549 harmonic(31) = 4.027245195436520102759838180253409570739320924649712368107240380481568735938418 31 is also the term number for the first harmonic > 4.0 harmonic(83) = 5.002068272680166053728324750753870264345455215566438587478989543061001039767003 83 is also the term number for the first harmonic > 5.0 harmonic(227) = 6.004366708345566023376436217157408474650893771305512336984772241757969069086895 227 is also the term number for the first harmonic > 6.0 harmonic(616) = 7.001274097134160381487068933022945074864048309674852535721112060499845844673362 616 is also the term number for the first harmonic > 7.0 harmonic(1674) = 8.000485571995779067790304796519697445800341927883408389172647367923220595045883 1674 is also the term number for the first harmonic > 8.0 harmonic(4550) = 9.000208062931140339164179501268928624268799275400095995932594006439583360896694 4550 is also the term number for the first harmonic > 9.0 harmonic(12367) = 10.00004300827580769470675707492981720768686887243344211163998834649135547210551 12367 is also the term number for the first harmonic > 10.0
Using rationals
const harmonics = accumulate((x, y) -> x + big"1" // y, 1:12370)
println("First twenty harmonic numbers as rationals:")
foreach(i -> println(rpad(i, 3), " => ", harmonics[i]), 1:20)
println("\nThe 100th harmonic is: ", harmonics[100], "\n")
for n in 1:10
idx = findfirst(x -> x > n, harmonics)
print("First Harmonic > $n is at position $idx and is: ", harmonics[idx], "\n\n")
end
- Output:
First twenty harmonic numbers as rationals: 1 => 1//1 2 => 3//2 3 => 11//6 4 => 25//12 5 => 137//60 6 => 49//20 7 => 363//140 8 => 761//280 9 => 7129//2520 10 => 7381//2520 11 => 83711//27720 12 => 86021//27720 13 => 1145993//360360 14 => 1171733//360360 15 => 1195757//360360 16 => 2436559//720720 17 => 42142223//12252240 18 => 14274301//4084080 19 => 275295799//77597520 20 => 55835135//15519504 The 100th harmonic is: 14466636279520351160221518043104131447711//2788815009188499086581352357412492142272 First Harmonic > 1 is at position 2 and is: 3//2 First Harmonic > 2 is at position 4 and is: 25//12 First Harmonic > 3 is at position 11 and is: 83711//27720 First Harmonic > 4 is at position 31 and is: 290774257297357//72201776446800 First Harmonic > 5 is at position 83 and is: 3672441655127796364812512959533039359//734184632222154704090370027645633600 First Harmonic > 6 is at position 227 and is: 7210530454341478178114292924106791866448071719960766673184657267908514585008387695857601640547547//1200881092808579751109445892858157237623011602251376919557525378451885327053551694768211209584000 First Harmonic > 7 is at position 616 and is: 32418148234584438506244669620559801586453637524407441287287956498408167324384836135154335608450103705554364675635095796463552565723833053990601655182066284053456674137000162471237344506126617371216079120095971345235097691744446098739930413505848076716148051590567//4630321250792651667959778962730272725135972962879403462498154236164728708558353376685441262094879300811505205446228182535680317471673227192574715015221837802633281044802046825192844588381756912000006314261374254853934981337617963082619967597058012665881508170240 First Harmonic > 8 is at position 1674 and is: 138141199730356031917751723608451630140926572041533266161867229808423134343694448776284861362361049658120307218628922472967074569643922410693236711646552594017799177544898923160715275467074773052672543691485042344006328346792717577331346270889819765648723902241194752204176829233330048155240810379245143159803746553605910654524991868894244655125224374793405027930983653080599361646248333997230466686371943554425849838679719632376766617639339476485319908534320267241696294676687857612211224929536683459738832437894009105247288571220395942120501422698013842452465990861198601652372525840473807472136998877762025722745653584203415416989419985647929410780044991971375219261681255528981314607252039408935696726675566989805504130221402879//17266601943998720215934555231097205020805360283925021776131771421603665580550992851730546192114435876915764081799263950036774496079790573533431946151195888729825227967898856935376506079740151630837994958679444177020560516804785312006925540853535681555388532126434276232761609235943363516882249874992501288848101663246418034482830782765799910587627015490435618612817485429045075697874945013812237906815356826216080083918931352849328226757321069450237292900402036556169613799106635542806391854137317272454464723030848621364955770185788658456980359320481573473968897297574022422610618929844739054324826111937140267616883649616842817036401014150739236179076410461198210703989272527503945999049527912447331310263532711648780174245760000 First Harmonic > 9 is at position 4550 and is: 2803922057204811543989535496612889221797101689401339733425779071893883726062730194418722759045899108563649222513327676111056373937430194191361767957531399947657882950860187200723323262653682200418079207248717851019834955117510807290247517344853824182604853734193915236890382944826941254750728989773414206859570065960640186792890664839103798433780558510849879082382309565191620282894846917562664482131202291813204472491830923673050493632880376511556753354676402403084278296415856939754434734260623967677761451430096042117604187063669249143393076890252523001247824132437003474131230135624887874799541971404156392012052221712958314528322355541629626096561834856317166367946519841625273109689443740339231545297896759513984852874078072318627511091395704617775835151474534768408675032414448963002972590468720049363107497714657975180640114587539853156735035634359134035816625004885128358508857789053399591546078553132392557669776329295754833648165907192091248381853554990310275294735796601315160268572473977239894244510958924644461475601889585298550864600912608515846981406115574447937712467306028124552530287697424685820096894634400504911945644842525080877704081133701601474836419212357427281193595545654309059483619700606698188346807113314394305087007324692154551457096864441413765832492015835459544797423019196304195496229963766867559041682555605485756372169731071238590755894190062578370776223859945908951232125318924762539326986977852885933136208484015119262988152215227210365689996539057011922584498047033647706625149283085817504520106280560129638082705378996661011957957116006944584486439354147266379272818775057457727700062964206158298239058238442033871955799108732891594547873095023995742714560400884479305635074935996707008596929664779547461570776674459690821497530879010144224813067523793975748941040890361283562073364309054362072137372458221297707667641071756676535258762295067395479041974831597965979613081474695278123265026663091006352059826017007472704096220374679625403//311539693038123496722215310551186904103082524726970170658802584453586817702845967012058559851648961565162714074357248615113237727615741409397613403942762027416418250197869235139807433555974792925305500675331577565501246819843747067123329275977858482555209853394601249731116273203314723492820718920663543363350452108859588055589207296367576316485295250028686463172112871115738305282269830733309445640796833467195761172540352742868324044527033042113461149657815168691435568328007659916683562048346389048741726140068665849102873300936534794943981012153540913055621237325128266901087332680399450826342551172911601227269655973249675723840414635853583858640961466968497444812002669481333031399627561658239662030094505016308687209615676717899935366285911202891060019766201048122485091665890488010192945266722188069264271709669076333959826410108104815827793429989042734394907438794428685359256959974813630940895555145059961227687918900885009633119015801758204737016204228694445315173976166116707848897795690334687813067638452214980721143416739719469158748498888549650173439285892765248219730073273036517725939409971809083058041780264560576764115967213013380206017646943405476909576091357482868476761698005324735669002986992261514164471647621973497050651105016702049275202360233254308086080840811811270395182950866854592166254651076234420662875446908943737749367221987863265181700223872816922018831416550743452655599236620182838774266078307310527709836462300005876748274266928980195184478251265986886488170211071786897470230189921260226806813948222307759474759342997757077589856537503856731410785456607398210129322637205537554981139121822428297380197652187006595903988741596680008103907700803965881407891948670316751093348441767470344198247057046756517630261990510817072323901911147038583224901683429072731095666462995891134319532658460042039832285713339493699639220237857309737109028479215274870712938102667472652582674547746273957596211401299308669708874527010828161490844069542400000 First Harmonic > 10 is at position 12367 and is: 4534503430707033513455566663502488777398404081163864262146240513258488614453237798607335814524420102703735793862177214220961640516162786810577801568379848400841651563172393145644747756934779147852785761076984123029496399397933274328333851023356832490595994957906245622634743917027121730163673444620574773571394586325343348374089752330084853480910846154523214600594885010321970738793199335121376742737688996290912022884023314845989317485564897100378511371007284095835544913458386488350273752793299623280953681770210860670497293958742056567860493303919432966767309289555005524116155997967505009262492686887145801834344158217659625052992919107429112826740068763017007260951761133678087563009777021924759295735860359747992008280482368678698363760290512075843263479257144567423473653608660780306498167138240689075702661825821881383897412095062894498190524562267366610500376186508574923546863369628573748735962288669973834867370052620567124452691818158059495529870775349719430883965813897867964261906884105709015328654134185094852649077443558343796100212309241953109323566593312098467538550988320147927458982568637261872251614826312806756190545537354754639105220779296735305508074404777698608072480025436626465940783557587776095412527179972733639880928504521162532474790119331444432691186539731972229608857034838322577825073128558410147097241778325338487130870125908822766048925435961031468685135925285730005192072367106087421540485758689853548032678218115860840827961919559051579906147674926980159462587970312884204058339415498440724533667854443260894961415867322707773766644126293587970041291934576744798355640180480297466389631305725091134483147261680364583681456904845585042916227359755995566890651618068412417567353169223028238974716410284035466524218357680139996958854138926338447160349489618026519182480829051291094774428369589524841439952414899018430629415759045664629576805779430276126299459472265505596409675499333035181404107887631586541773720233030773460233097013905563454586768052944023799630803277004868637818739278212959623313318901685226624666106128149541383179968968079822908437213133926503243634564555471480742603760558963949447568409555153275556694530840495402464574679819190097934082680991390359677270683921719809487985411431453913318562222280325934810896976109622317012462673397599719705029993095451945802745111845994127113737531302666646673629309399879563721820841693763990040297218084280469660603933736914103580592334169009905536955683757799785465521029810481052093318974648597912401819690931945953441013940611090922220615447632315575131416623986489801748397222861527442923686453815927754305883939843644528744788311441317667800082400625247002131690240576547715553985566084722165603169180546444489624520529458589659642945674302803518493446186365401036652868957343947436300845516052248544996767002703372227801331704347861429376714087429190841582994100706608870432263478840976847125656598528047665054259600221287735441697634905261794158123419440836603187910006400385658161609560077480916666767855249401496376453813742910897685304674607932781480153350592305086143517293124048321908049033338641165570949920967640973467814840149770609739430967880836391708342980969076413706547475361151566568646558729953788076269958878680638806411347398270002468450490060229923546495153668589442405650268354841362770166414940668952342796856334297184594689014220369402540999903691567293267477507617730573216005494288894386265419609930709688051786459868855999927483488595292377625472492052607166011299662062394773003492445503755319504334407628427786801438298993197490802949903537017176795900523366221528304387658556186131452558642788326427005831945047208416461903276903155157668071084197085232239303753932511966601799642086840010635787283417484115163601638040747720429853554897965062666245152120838888282696144547158569268308151508594359471912253952609211269960896327745083608820919865564411609729050094802982153483731969811821363213666501089803250069914862591069398131811421717727581994465281157595132213790173740210606315458787942312889500024592644472634497210343312196800423898410785211559075127039914648882418769844305126070628158439406823975898202123936987508547712323439814808927188496139029784726424065836399799566957465329325900733347158011735890776039622239371179265322102988095792334295987922829904316643744024475158366697011639022690011158534933281478551427221827338035502405739017675964995339845575688974247145430375550691172792583150675040459847494992816879937873922797432917540308251685230808170901253598248750205022912447198383112847277587880630475986296945942943527602129139602849994318853893879911800330577976183782475767979870512555206262710949997353103772493020471652674012338306053325512634115113811440908388247422072755018950413835394298503429471638926223466724120693416489874608276360557167546047009826979490836032462574788898996808959092152232893733971469326230223411125857734727852907092167761679250398986918637504310219629562470003641972668110649513078347115663607119611611006136091187311740932841583114177470218100285066869010543963406829140648421377028252417899384810247910009920738953581331407151723899810868371969278374342093106625781466735739058011357436506412309273928847791977164882301609474829416331188046487042397727216661613196578592821103409588225020153177686173957843637300970946602788598104463189226384477573248319694609//453448392867348851861091842716460781522665326792904183722427862157021725614855278045402902750948524499248477906574954049723047247594567849381505559142259985012563911748565504645288824396149684911357398473040997444532446072249205183698951114867996915790953480940595875198164176514792266197724950029214098402750523319656510658391308781455532640143957171928728555028441113976098936445243888308518334732068287540969911145046182240997844332542069999808052999118116686423274752490237063716145951662497086525502824771022018772683298755747961799756488875473662436395793972289765688786340400767092625088976215404821615642169932407067470102277881619113300360581665503419953488853618786486589079218434762164433122957020446969147378233696729003877954852548129234246125950262402365717815616819562222237997997268259525610560218332639694073974306248739683910746615242978454786299588282966741711638421737040643849869111250119460946958342235754393754105273921365540335675025520532198380359075366480578543033141107171068864236199764731934475297409089137917767464818172280194587098425992699315337227143311157563983501099319586806728853272646048761957836787873218028733894581386787413379357471544256309173104246757027297103897425448969584443551192032578044112779996916037308469908337849261001566062681902158730668479447685029245562145758050351907230317974951652391896463264624212612669169958584934650809482293303230830931776045695753750127961326467827548499522738908622830870349146611375298940888140985679637170914965525299929769378946655485787070387076631251882242836138520842058399796780766046354724533075054753447434289238707943437708102115231865561988793697866081966627386198255657705081440529935972313855299293571946459814547702790931940409505592380201618395383529120246923953942192402976907753500903555076008341911303039471562108255892056978939810785607998919899547795388848467866707335193584754101418435349055093490132220307797847159336930832196642264566173052472986519467903662478761577267524782906438677344301510628707749510764610883151848961955324250103497542040100381108000294328086486819670637824004877822719162400898805753721906246725669673698667303029853553151086095673161642688637369399134211142673038004309271354569340138672196310045673847468188540492497939082450727559160669323441829424345229568861519806871166312840505922345924286612289038405635960847312841549454914894505350287965178933448588642960151653234597627993111784598027362458363048975481887472153211279255977999546404147533745281771529556720982887239728930885170033344102088264480888466142172463254195760915805324061034675182591049442628706041312626422073008073380371673927489824737483560681019534670531017902066234272224653619745905599447903061483059896873406142453228071022111502256443781491460846164401184358168702828324631516293734123540067969597713270070892954605122527765020904360443840604089525630920883767509762055795186065284871898250633904172393012014014535429691316180843284005611214029789777910907448104608381684001408038080004630598753746420393898907687445970436071633844317405361945225336609003279748456376641015025188398108421593478229298294410838458456380669395413849296975844767158362010790056013282230712593275083853985899993525361915338786353135213679507571177474865535450360805151635896650877459021597451290179824388706852573538022338292357056094650723608655495776391045556275691435553166984429143943751883621223890112143444263384709343311021515999913133625576607936737600163990937589076505709728288249796177860701551483858105729270343952736046045949895941189683687455280876075868089128908950093274631325285867675575977007649875882080181911556426324514888965309812114552424769046963560561519998228670210152775853158532301504121266893422531369102008133615525509443494794446512860320064722889237146201868974019228593633572436903033783142941154726917069945760001298893890438043207045074201509279648515350335803482110210899536912444564551795055524051376159340142763939561343534419114897944064189816231618709358147206686123692571007252707031453516920926510941282670271991207431645277787732194166279571541705091430384118591739755560716583929251984774474735360846706097322805037517607175954157003966139895604444104180849566439510557422016972444504568924435928285183045942516523723723922905128092098303510237702313418511361585451364656754043639465582976252775658243115735311521322732866960027744814046142646066362389168699571924976468952738225372771528877335171820809981966462557399840199438944317868064756592423558340956344597149662019813621964301710551795219655353560019310354145741006960293249850509760942103140771516196121166914225789961295123942408454678165630224229246096815718964524008072338418161910957019466321162530778568751489056122708488740001553449809520216651409154456422832210306621326600466249277216434300763703544991709516688672829002850684750220066717750016340009488155733886564204666531055424099636022638066094074880147267683122477920693324135470681030117673286007072403853987896516881673522241375339519109365317259361633140780497503747668264390394453428165247265288377265912593743778917613302228374835985611202269353962434983431127134732498447341566434664481796653135468887881140453881191678527573715771628361883084372307861539269288978542389654945192750390734178119092263987452761982138487929715357003527512352779194620327380792004034424949320206418355200000
Lua
-- Task 1
function harmonic (n)
if n < 1 or n ~= math.floor(n) then
error("Argument to harmonic function is not a natural number")
end
local Hn = 1
for i = 2, n do
Hn = Hn + (1/i)
end
return Hn
end
-- Task 2
for x = 1, 20 do
print(x .. " :\t" .. harmonic(x))
end
-- Task 3
local x, lastInt, Hx = 0, 1
repeat
x = x + 1
Hx = harmonic(x)
if Hx > lastInt then
io.write("The first harmonic number above " .. lastInt)
print(" is " .. Hx .. " at position " .. x)
lastInt = lastInt + 1
end
until lastInt > 10 -- Stretch goal just meant changing that value from 5 to 10
-- Execution still only takes about 120 ms under LuaJIT
- Output:
1 : 1 2 : 1.5 3 : 1.8333333333333 4 : 2.0833333333333 5 : 2.2833333333333 6 : 2.45 7 : 2.5928571428571 8 : 2.7178571428571 9 : 2.8289682539683 10 : 2.9289682539683 11 : 3.0198773448773 12 : 3.1032106782107 13 : 3.1801337551338 14 : 3.2515623265623 15 : 3.318228993229 16 : 3.380728993229 17 : 3.4395525226408 18 : 3.4951080781963 19 : 3.5477396571437 20 : 3.5977396571437 The first harmonic number above 1 is 1.5 at position 2 The first harmonic number above 2 is 2.0833333333333 at position 4 The first harmonic number above 3 is 3.0198773448773 at position 11 The first harmonic number above 4 is 4.0272451954365 at position 31 The first harmonic number above 5 is 5.0020682726802 at position 83 The first harmonic number above 6 is 6.0043667083456 at position 227 The first harmonic number above 7 is 7.0012740971342 at position 616 The first harmonic number above 8 is 8.0004855719958 at position 1674 The first harmonic number above 9 is 9.0002080629311 at position 4550 The first harmonic number above 10 is 10.000043008276 at position 12367
Mathematica /Wolfram Language
nums = HarmonicNumber[Range[15000]];
nums[[;; 20]]
LengthWhile[nums, LessEqualThan[#]] + 1 & /@ Range[10]
- Output:
{1, 3/2, 11/6, 25/12, 137/60, 49/20, 363/140, 761/280, 7129/2520, 7381/2520, 83711/27720, 86021/27720, 1145993/360360, 1171733/360360, 1195757/360360, 2436559/720720, 42142223/12252240, 14274301/4084080, 275295799/77597520, 55835135/15519504} {2, 4, 11, 31, 83, 227, 616, 1674, 4550, 12367}
Maxima
harmonic(n):=apply("+",1/makelist(i,i,n))$
first_greater_than_n(len):=block(i:1,result:[],while harmonic(i)<=len do (result:endcons(i,result),i:i+1),last(result)+1)$
/* Test cases */
/* First 20 harmonic numbers */
makelist(harmonic(j),j,20);
/* First harmonic number that exceeds a positive integer from 1 to 5 */
makelist(first_greater_than_n(k),k,5);
- Output:
[1,3/2,11/6,25/12,137/60,49/20,363/140,761/280,7129/2520,7381/2520,83711/27720,86021/27720,1145993/360360,1171733/360360,1195757/360360,2436559/720720,42142223/12252240,14274301/4084080,275295799/77597520,55835135/15519504] [2,4,11,31,83]
Nim
Using floats
import strformat
iterator h(): (int, float) =
## Yield the index of the term and its value.
var n = 1
var r = 0.0
while true:
r += 1 / n
yield (n, r)
inc n
echo "First 20 terms of the harmonic series:"
for (idx, val) in h():
echo &"{idx:2}: {val}"
if idx == 20: break
echo()
var target = 1.0
for (idx, val) in h():
if val > target:
echo &"Index of the first term greater than {target.int:2}: {idx}"
if target == 10: break
else: target += 1
- Output:
1: 1.0 2: 1.5 3: 1.833333333333333 4: 2.083333333333333 5: 2.283333333333333 6: 2.45 7: 2.592857142857143 8: 2.717857142857143 9: 2.828968253968254 10: 2.928968253968254 11: 3.019877344877345 12: 3.103210678210678 13: 3.180133755133755 14: 3.251562326562327 15: 3.318228993228994 16: 3.380728993228994 17: 3.439552522640758 18: 3.495108078196314 19: 3.547739657143682 20: 3.597739657143682 Index of the first term greater than 1: 2 Index of the first term greater than 2: 4 Index of the first term greater than 3: 11 Index of the first term greater than 4: 31 Index of the first term greater than 5: 83 Index of the first term greater than 6: 227 Index of the first term greater than 7: 616 Index of the first term greater than 8: 1674 Index of the first term greater than 9: 4550 Index of the first term greater than 10: 12367
Using big integers
import strformat
import bignum
iterator h(): (int, Rat) =
var n = 1
var r = newRat()
while true:
r += newRat(1, n)
yield (n, r)
inc n
echo "First 20 terms of the harmonic series:"
for (idx, val) in h():
echo &"{idx:2}: {val}"
if idx == 20: break
echo()
var target = 1
for (idx, val) in h():
if val > target:
echo &"Index of the first term greater than {target:2}: {idx}"
if target == 10: break
else: inc target
- Output:
1: 1 2: 3/2 3: 11/6 4: 25/12 5: 137/60 6: 49/20 7: 363/140 8: 761/280 9: 7129/2520 10: 7381/2520 11: 83711/27720 12: 86021/27720 13: 1145993/360360 14: 1171733/360360 15: 1195757/360360 16: 2436559/720720 17: 42142223/12252240 18: 14274301/4084080 19: 275295799/77597520 20: 55835135/15519504 Index of the first term greater than 1: 2 Index of the first term greater than 2: 4 Index of the first term greater than 3: 11 Index of the first term greater than 4: 31 Index of the first term greater than 5: 83 Index of the first term greater than 6: 227 Index of the first term greater than 7: 616 Index of the first term greater than 8: 1674 Index of the first term greater than 9: 4550 Index of the first term greater than 10: 12367
PARI/GP
h=0
for(n=1,20,h=h+1/n;print(n," ",h))
h=0; n=1
for(i=1,10,while(h<i,h=h+1/n;n=n+1);print(n-1))
PascalABC.NET
function H(n: integer): real := (1..n).Sum(i -> 1/i);
begin
for var i:=1 to 20 do
Println($'{i,2}: {H(i),10:f8}');
var i := 1;
var num := 1;
while num < 11 do
begin
if H(i) > num then
begin
Println('Position of the first harmonic number >',num,':',i);
num += 1;
end;
i += 1;
end;
end.
- Output:
1: 1.00000000 2: 1.50000000 3: 1.83333333 4: 2.08333333 5: 2.28333333 6: 2.45000000 7: 2.59285714 8: 2.71785714 9: 2.82896825 10: 2.92896825 11: 3.01987734 12: 3.10321068 13: 3.18013376 14: 3.25156233 15: 3.31822899 16: 3.38072899 17: 3.43955252 18: 3.49510808 19: 3.54773966 20: 3.59773966 Position of the first harmonic number > 1 : 2 Position of the first harmonic number > 2 : 4 Position of the first harmonic number > 3 : 11 Position of the first harmonic number > 4 : 31 Position of the first harmonic number > 5 : 83 Position of the first harmonic number > 6 : 227 Position of the first harmonic number > 7 : 616 Position of the first harmonic number > 8 : 1674 Position of the first harmonic number > 9 : 4550 Position of the first harmonic number > 10 : 12367
Perl
use strict;
use warnings;
use feature 'say';
use Math::AnyNum ':overload';
use List::AllUtils 'firstidx';
my(@H,$n) = 0;
do { ++$n and push @H, $H[-1] + 1/$n } until $H[-1] >= 10;
shift @H;
say 'First twenty harmonic numbers as rationals:';
my $c = 0;
printf("%20s", $_) and (not ++$c%5) and print "\n" for @H[0..19];
say "\nIndex of first value (zero based):";
for my $i (1..10) {
printf " greater than %2d: %5s\n", $i, firstidx { $_ > $i } @H;
}
- Output:
First twenty harmonic numbers as rationals: 1 3/2 11/6 25/12 137/60 49/20 363/140 761/280 7129/2520 7381/2520 83711/27720 86021/27720 1145993/360360 1171733/360360 1195757/360360 2436559/720720 42142223/12252240 14274301/4084080 275295799/77597520 55835135/15519504 Index of first value (zero based): greater than 1: 1 greater than 2: 3 greater than 3: 10 greater than 4: 30 greater than 5: 82 greater than 6: 226 greater than 7: 615 greater than 8: 1673 greater than 9: 4549 greater than 10: 12366
Phix
requires("0.8.4") include mpfr.e integer n = 1, gn = 1, lim = iff(platform()=JS?8:10) mpq hn = mpq_init_set_si(1) sequence gt = {} puts(1,"First twenty harmonic numbers as rationals:\n") while gn<=lim do if n<=20 then printf(1,"%18s%s",{mpq_get_str(hn),iff(mod(n,5)?" ","\n")}) end if if n=100 then printf(1,"\nOne Hundredth:\n%s\n\n",{mpq_get_str(hn)}) end if if mpq_cmp_si(hn,gn)>0 then gt &= n gn += 1 end if n += 1 mpq_add_si(hn,hn,1,n) end while printf(1,"(one based) Index of first value:\n") for i=1 to length(gt) do printf(1," greater than %2d: %,6d (%s term)\n",{i,gt[i],ordinal(gt[i])}) end for
- Output:
First twenty harmonic numbers as rationals: 1 3/2 11/6 25/12 137/60 49/20 363/140 761/280 7129/2520 7381/2520 83711/27720 86021/27720 1145993/360360 1171733/360360 1195757/360360 2436559/720720 42142223/12252240 14274301/4084080 275295799/77597520 55835135/15519504 One Hundredth: 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 (one based) Index of first value: greater than 1: 2 (second term) greater than 2: 4 (fourth term) greater than 3: 11 (eleventh term) greater than 4: 31 (thirty-first term) greater than 5: 83 (eighty-third term) greater than 6: 227 (two hundred and twenty-seventh term) greater than 7: 616 (six hundred and sixteenth term) greater than 8: 1,674 (one thousand, six hundred and seventy-fourth term) greater than 9: 4,550 (four thousand, five hundred and fiftieth term) greater than 10: 12,367 (twelve thousand, three hundred and sixty-seventh term)
(The last two entries are too slow/beyond the reach of the first version of mpfr.js, but it's quick on the desktop)
using standard floats
integer n = 1, gn = 1 atom hn = 1 sequence gt = {} puts(1,"First twenty harmonic numbers as fractions:\n") while gn<=10 do if n<=20 then printf(1,"%18.15f%s",{hn,iff(mod(n,5)?" ","\n")}) end if if n=100 then printf(1,"\nOne Hundredth: %18.15f\n\n",{hn}) end if if hn>gn then gt &= n gn += 1 end if n += 1 hn += 1/n end while printf(1,"(one based) Index of first value:\n") for i=1 to length(gt) do printf(1," greater than %2d: %,6d (%s term)\n",{i,gt[i],ordinal(gt[i])}) end for {} = wait_key()
- Output:
First twenty harmonic numbers as fractions: 1.000000000000000 1.500000000000000 1.833333333333333 2.083333333333333 2.283333333333333 2.450000000000000 2.592857142857143 2.717857142857143 2.828968253968254 2.928968253968254 3.019877344877345 3.103210678210678 3.180133755133755 3.251562326562327 3.318228993228994 3.380728993228994 3.439552522640758 3.495108078196314 3.547739657143682 3.597739657143682 One Hundredth: 5.187377517639621 (one based) Index of first value: greater than 1: 2 (second term) greater than 2: 4 (fourth term) greater than 3: 11 (eleventh term) greater than 4: 31 (thirty-first term) greater than 5: 83 (eighty-third term) greater than 6: 227 (two hundred and twenty-seventh term) greater than 7: 616 (six hundred and sixteenth term) greater than 8: 1,674 (one thousand, six hundred and seventy-fourth term) greater than 9: 4,550 (four thousand, five hundred and fiftieth term) greater than 10: 12,367 (twelve thousand, three hundred and sixty-seventh term)
Prolog
main:-
print_harmonic_series(20),
nl,
nth_harmonic_number(100, T),
Num is numerator(T),
Denom is denominator(T),
writef('100th harmonic number: %t/%t\n', [Num, Denom]),
nl,
print_first_harmonic_greater_than(10).
print_harmonic_series(N):-
writef('First %t harmonic numbers:\n', [N]),
harmonic_first(H),
print_harmonic_series(N, H).
print_harmonic_series(N, H):-
H = h(I, T),
Num is numerator(T),
Denom is denominator(T),
writef('%3r. %t/%t\n', [I, Num, Denom]),
(I == N, ! ; harmonic_next(H, H1), print_harmonic_series(N, H1)).
print_first_harmonic_greater_than(N):-
harmonic_first(H),
print_first_harmonic_greater_than(1, N, H).
print_first_harmonic_greater_than(N, L, _):-
N > L,
!.
print_first_harmonic_greater_than(N, L, H):-
H = h(P, T),
(T > N ->
writef('Position of first term >%3r: %t\n', [N, P]),
N1 is N + 1
;
N1 = N),
harmonic_next(H, H1),
print_first_harmonic_greater_than(N1, L, H1).
harmonic_first(h(1, 1)).
harmonic_next(h(N1, T1), h(N2, T2)):-
N2 is N1 + 1,
T2 is T1 + 1 rdiv N2.
nth_harmonic_number(N, T):-
harmonic_first(H),
nth_harmonic_number(N, T, H).
nth_harmonic_number(N, T, h(N, T)):-!.
nth_harmonic_number(N, T, H1):-
harmonic_next(H1, H2),
nth_harmonic_number(N, T, H2).
- Output:
First 20 harmonic numbers: 1. 1/1 2. 3/2 3. 11/6 4. 25/12 5. 137/60 6. 49/20 7. 363/140 8. 761/280 9. 7129/2520 10. 7381/2520 11. 83711/27720 12. 86021/27720 13. 1145993/360360 14. 1171733/360360 15. 1195757/360360 16. 2436559/720720 17. 42142223/12252240 18. 14274301/4084080 19. 275295799/77597520 20. 55835135/15519504 100th harmonic number: 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 Position of first term > 1: 2 Position of first term > 2: 4 Position of first term > 3: 11 Position of first term > 4: 31 Position of first term > 5: 83 Position of first term > 6: 227 Position of first term > 7: 616 Position of first term > 8: 1674 Position of first term > 9: 4550 Position of first term > 10: 12367
Python
A generator function using fractions:
from fractions import Fraction
def harmonic_series():
n, h = Fraction(1), Fraction(1)
while True:
yield h
h += 1 / (n + 1)
n += 1
if __name__ == '__main__':
from itertools import islice
for n, d in (h.as_integer_ratio() for h in islice(harmonic_series(), 20)):
print(n, '/', d)
- Output:
1 / 1 3 / 2 11 / 6 25 / 12 137 / 60 49 / 20 363 / 140 761 / 280 7129 / 2520 7381 / 2520 83711 / 27720 86021 / 27720 1145993 / 360360 1171733 / 360360 1195757 / 360360 2436559 / 720720 42142223 / 12252240 14274301 / 4084080 275295799 / 77597520 55835135 / 15519504
Or alternatively, in terms of itertools.accumulate:
'''Harmonic series'''
from fractions import Fraction
from itertools import accumulate, count, islice
from operator import add
# harmonic :: [Fraction]
def harmonic():
'''Non finite stream of the terms
of the Harmonic series.
'''
return accumulate(
(1 / Fraction(x) for x in count(1)),
add
)
# ------------------------- TEST -------------------------
# main :: IO ()
def main():
'''Tests of the harmonic series function'''
print('First 20 terms of the harmonic series:')
print('\n'.join([
showFraction(nd) for nd in islice(harmonic(), 20)
]))
print('\n100th term:')
print(
showFraction(
next(islice(harmonic(), 99, None))
)
)
print('')
print(
'One-based indices of terms above threshold values:'
)
indexedHarmonic = enumerate(harmonic())
print('\n'.join([
next(
showFirstLimit(n)(x) for x
in indexedHarmonic if n < x[1]
) for n in range(1, 1 + 10)
]))
# ------------------ DISPLAY FORMATTING ------------------
# showFraction :: Fraction -> String
def showFraction(nd):
'''String representation of the fraction nd.
'''
n, d = nd.as_integer_ratio()
return f'{n} / {d}'
# showFirstLimit :: Int -> (Int, Fraction) -> String
def showFirstLimit(n):
'''Report of 1-based index of first term
with a value over n
'''
def go(indexedFraction):
i = indexedFraction[0]
return f'Term {1 + i} is the first above {n}'
return go
# MAIN ---
if __name__ == '__main__':
main()
- Output:
First 20 terms of the harmonic series: 1 / 1 3 / 2 11 / 6 25 / 12 137 / 60 49 / 20 363 / 140 761 / 280 7129 / 2520 7381 / 2520 83711 / 27720 86021 / 27720 1145993 / 360360 1171733 / 360360 1195757 / 360360 2436559 / 720720 42142223 / 12252240 14274301 / 4084080 275295799 / 77597520 55835135 / 15519504 100th term: 14466636279520351160221518043104131447711 / 2788815009188499086581352357412492142272 One-based indices of terms above threshold values: Term 2 is the first above 1 Term 4 is the first above 2 Term 11 is the first above 3 Term 31 is the first above 4 Term 83 is the first above 5 Term 227 is the first above 6 Term 616 is the first above 7 Term 1674 is the first above 8 Term 4550 is the first above 9 Term 12367 is the first above 10
Quackery
[ $ "bigrat.qky" loadfile ] now!
0 n->v
20 times
[ i^ 1+ n->v 1/v v+
2dup 20 point$ echo$
say " = "
2dup vulgar$ echo$ cr ]
2drop
cr
1 temp put
0 n->v 1
[ dup dip
[ n->v 1/v v+
temp share n->v 2over v< ]
swap if
[ temp share echo
say " : "
dup echo cr
1 temp tally ]
temp share 11 < while
1+
again ]
temp release
drop 2drop
- Output:
1 = 1/1 1.5 = 3/2 1.83333333333333333333 = 11/6 2.08333333333333333333 = 25/12 2.28333333333333333333 = 137/60 2.45 = 49/20 2.59285714285714285714 = 363/140 2.71785714285714285714 = 761/280 2.82896825396825396825 = 7129/2520 2.92896825396825396825 = 7381/2520 3.01987734487734487734 = 83711/27720 3.10321067821067821068 = 86021/27720 3.18013375513375513376 = 1145993/360360 3.25156232656232656233 = 1171733/360360 3.31822899322899322899 = 1195757/360360 3.38072899322899322899 = 2436559/720720 3.43955252264075793488 = 42142223/12252240 3.49510807819631349043 = 14274301/4084080 3.54773965714368191148 = 275295799/77597520 3.59773965714368191148 = 55835135/15519504 1 : 2 2 : 4 3 : 11 4 : 31 5 : 83 6 : 227 7 : 616 8 : 1674 9 : 4550 10 : 12367
R
Direct Summation
The talk page helpfully points out that we can be remarkably lazy here.
HofN <- function(n) sum(1/seq_len(n)) #Task 1
H <- sapply(1:100000, HofN)
print(H[1:20]) #Task 2
print(sapply(1:10, function(x) which.max(H > x))) #Task 3 and stretch
- Output:
> print(H[1:20]) #Task 2 [1] 1.000000 1.500000 1.833333 2.083333 2.283333 2.450000 2.592857 2.717857 2.828968 2.928968 3.019877 3.103211 3.180134 3.251562 [15] 3.318229 3.380729 3.439553 3.495108 3.547740 3.597740 > print(sapply(1:10, function(x) which.max(H > x))) #Task 3 and stretch [1] 2 4 11 31 83 227 616 1674 4550 12367
Cumulative Sums
As for doing this properly, R provides a handy cumsum function.
firstNHarmonicNumbers <- function(n) cumsum(1/seq_len(n)) #Task 1
H <- firstNHarmonicNumbers(100000) #Runs stunningly quick
print(H[1:20]) #Task 2
print(sapply(1:10, function(x) which.max(H > x))) #Task 3 and stretch
Raku
Using Lingua::EN::Numbers from the Raku ecosystem.
use Lingua::EN::Numbers;
my @H = [\+] (1..*).map: { FatRat.new: 1, $_ };
say "First twenty harmonic numbers as rationals:\n",
@H[^20]».&pretty-rat.batch(5)».fmt("%18s").join: "\n";
put "\nOne Hundredth:\n", pretty-rat @H[99];
say "\n(zero based) Index of first value:";
printf " greater than %2d: %6s (%s term)\n",
$_, comma( my $i = @H.first(* > $_, :k) ), ordinal 1 + $i for 1..10;
- Output:
First twenty harmonic numbers as rationals: 1 3/2 11/6 25/12 137/60 49/20 363/140 761/280 7129/2520 7381/2520 83711/27720 86021/27720 1145993/360360 1171733/360360 1195757/360360 2436559/720720 42142223/12252240 14274301/4084080 275295799/77597520 55835135/15519504 One Hundredth: 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 (zero based) Index of first value: greater than 1: 1 (second term) greater than 2: 3 (fourth term) greater than 3: 10 (eleventh term) greater than 4: 30 (thirty-first term) greater than 5: 82 (eighty-third term) greater than 6: 226 (two hundred twenty-seventh term) greater than 7: 615 (six hundred sixteenth term) greater than 8: 1,673 (one thousand, six hundred seventy-fourth term) greater than 9: 4,549 (four thousand, five hundred fiftieth term) greater than 10: 12,366 (twelve thousand, three hundred sixty-seventh term)
REXX
The default number of decimal digits (9) could've been used instead of 80 for this task's particular limits.
/*REXX pgm to calculate N numbers (sums) in the harmonic series and also when they > X. */
parse arg digs sums high ints /*obtain optional arguments from the CL*/
if digs='' | digs="," then digs= 80 /*Not specified? Then use the default.*/
if sums='' | sums="," then sums= 20 /* " " " " " " */
if high='' | high="," then high= 10 /* " " " " " " */
if ints='' | ints="," then ints= 1 2 3 4 5 6 7 8 9 10 /*Not specified? " " " */
w= length(sums) + 2 /*width of Nth harmonic index + suffix.*/
numeric digits digs /*have REXX use more numeric dec. digs.*/
s= 0 /*initialize harmonic series sum to 0. */
do j=1 for sums; s= s + 1/j /*calc "sums" of harmonic series nums.*/
@iter= right((j)th(j), w) /*obtain a nicely formatted sum index. */
say right(@iter, w) 'harmonic sum ──►' s /*indent the output to the terminal. */
end /*j*/
say /*have a blank line between output sets*/
many= words(ints) /*obtain number of limits to be used. */
z= word(ints, 1) /* " the first " " " " */
lastInt= word(ints, many) /* " " last " " " " */
w= length(lastInt) /*W: is the maximum width of any limit*/
#= 1 /*a pointer to a list of integer limits*/
s= 0 /*initialize harmonic series sum to 0. */
do j=1; s= s + 1/j /*calculate sums of harmonic sum index.*/
if s<=z then iterate /*Is sum <= a limit? Then keep going. */
iter= commas(j)th(j) /*obtain a nicely formatted sum index. */
L= length(iter) /*obtain length so as to align output. */
@iter= right(iter, max(L, 25) ) /*indent the output to the terminal. */
say @iter " iteration of the harmonic series, the sum is greater than " right(z, w)
#= # + 1 /*bump the pointer to the next limit. */
if #>many then leave /*Are at the end of the limits? Done. */
z= word(ints, #) /*point to the next limit to be used. */
end /*j*/ /* [↑] above indices are unity─based. */
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?
th: parse arg x; return word('th st nd rd', 1 + (x//10) *(x//100%10\==1) *(x//10<4))
- output when using the default inputs:
1st harmonic sum ──► 1 2nd harmonic sum ──► 1.5 3rd harmonic sum ──► 1.8333333333333333333333333333333333333333333333333333333333333333333333333333333 4th harmonic sum ──► 2.0833333333333333333333333333333333333333333333333333333333333333333333333333333 5th harmonic sum ──► 2.2833333333333333333333333333333333333333333333333333333333333333333333333333333 6th harmonic sum ──► 2.4500000000000000000000000000000000000000000000000000000000000000000000000000000 7th harmonic sum ──► 2.5928571428571428571428571428571428571428571428571428571428571428571428571428571 8th harmonic sum ──► 2.7178571428571428571428571428571428571428571428571428571428571428571428571428571 9th harmonic sum ──► 2.8289682539682539682539682539682539682539682539682539682539682539682539682539682 10th harmonic sum ──► 2.9289682539682539682539682539682539682539682539682539682539682539682539682539682 11th harmonic sum ──► 3.0198773448773448773448773448773448773448773448773448773448773448773448773448773 12th harmonic sum ──► 3.1032106782106782106782106782106782106782106782106782106782106782106782106782106 13th harmonic sum ──► 3.1801337551337551337551337551337551337551337551337551337551337551337551337551337 14th harmonic sum ──► 3.2515623265623265623265623265623265623265623265623265623265623265623265623265623 15th harmonic sum ──► 3.3182289932289932289932289932289932289932289932289932289932289932289932289932290 16th harmonic sum ──► 3.3807289932289932289932289932289932289932289932289932289932289932289932289932290 17th harmonic sum ──► 3.4395525226407579348755819344054638172285231108760520525226407579348755819344055 18th harmonic sum ──► 3.4951080781963134904311374899610193727840786664316076080781963134904311374899611 19th harmonic sum ──► 3.5477396571436819114837690689083877938367102453789760291308278924377995585425927 20th harmonic sum ──► 3.5977396571436819114837690689083877938367102453789760291308278924377995585425927 2nd iteration of the harmonic series, the sum is greater than 1 4th iteration of the harmonic series, the sum is greater than 2 11th iteration of the harmonic series, the sum is greater than 3 31st iteration of the harmonic series, the sum is greater than 4 83rd iteration of the harmonic series, the sum is greater than 5 227th iteration of the harmonic series, the sum is greater than 6 616th iteration of the harmonic series, the sum is greater than 7 1,674th iteration of the harmonic series, the sum is greater than 8 4,550th iteration of the harmonic series, the sum is greater than 9 12,367th iteration of the harmonic series, the sum is greater than 10
Ring
decimals(12)
sum = 0
nNew = 1
limit = 13000
Harmonic = []
for n = 1 to limit
sum += 1/n
add(Harmonic,[n,sum])
next
see "The first twenty harmonic numbers are:" + nl
for n = 1 to 20
see "" + Harmonic[n][1] + " -> " + Harmonic[n][2] + nl
next
see nl
for m = 1 to 10
for n = nNew to len(Harmonic)
if Harmonic[n][2] > m
see "The first harmonic number greater than "
see "" + m + " is " + Harmonic[n][2] + ", at position " + n + nl
nNew = n
exit
ok
next
next
- Output:
The first twenty harmonic numbers are: 1 -> 1 2 -> 1.500000000000 3 -> 1.833333333333 4 -> 2.083333333333 5 -> 2.283333333333 6 -> 2.450000000000 7 -> 2.592857142857 8 -> 2.717857142857 9 -> 2.828968253968 10 -> 2.928968253968 11 -> 3.019877344877 12 -> 3.103210678211 13 -> 3.180133755134 14 -> 3.251562326562 15 -> 3.318228993229 16 -> 3.380728993229 17 -> 3.439552522641 18 -> 3.495108078196 19 -> 3.547739657144 20 -> 3.597739657144 The first harmonic number greater than 1 is 1.500000000000, at position 2 The first harmonic number greater than 2 is 2.083333333333, at position 4 The first harmonic number greater than 3 is 3.019877344877, at position 11 The first harmonic number greater than 4 is 4.027245195437, at position 31 The first harmonic number greater than 5 is 5.002068272680, at position 83 The first harmonic number greater than 6 is 6.004366708346, at position 227 The first harmonic number greater than 7 is 7.001274097134, at position 616 The first harmonic number greater than 8 is 8.000485571996, at position 1674 The first harmonic number greater than 9 is 9.000208062931, at position 4550 The first harmonic number greater than 10 is 10.000043008276, at position 12367
RPL
≪ 0 1 ROT FOR j INV + NEXT ≫ ‘HARMO’ STO ≪ 5 FIX { } 1 20 FOR n n + HARMO NEXT ≫ EVAL
- Output:
1: { 1.00000 1.50000 1.83333 2.08333 2.28333 2.45000 2.59286 2.71786 2.82897 2.92897 3.01988 3.10321 3.18013 3.25156 3.31823 3.38073 3.43955 3.49511 3.54774 3.59774 }
We haved fulfilled the stretched part of the task on a vintage HP-28S, with the objective to be as fast as possible. H(n+1) is calculated directly from H(n), and a FOR..NEXT
loop allows to reduce stack depth and eliminate the counter incrementation by the user; 9999 is a magic number used to exit the loop.
≪ → max ≪ { } 0 1 9999 FOR j j INV + IF OVER SIZE 1 + OVER < THEN SWAP j + IF DUP SIZE max > THEN 9999 'j' STO END SWAP END NEXT DROP ≫ ≫ ‘TASK2’ STO
- Output:
1: { 2 4 11 31 83 227 616 1674 4550 12367 }
was returned in less than 8 minutes.
Ruby
harmonics = Enumerator.new do |y|
res = 0
(1..).each {|n| y << res += Rational(1, n) }
end
n = 20
The first #{n} harmonics (as rationals):""
harmonics.take(n).each_slice(5){|slice| puts "%20s"*slice.size % slice }
puts
milestones = (1..10).to_a
harmonics.each.with_index(1) do |h,i|
if h > milestones.first then
puts "The first harmonic number > #{milestones.shift} is #{h.to_f} at position #{i}"
end
break if milestones.empty?
end
- Output:
1/1 3/2 11/6 25/12 137/60 49/20 363/140 761/280 7129/2520 7381/2520 83711/27720 86021/27720 1145993/360360 1171733/360360 1195757/360360 2436559/720720 42142223/12252240 14274301/4084080 275295799/77597520 55835135/15519504 The first harmonic number > 1 is 1.5 at position 2 The first harmonic number > 2 is 2.0833333333333335 at position 4 The first harmonic number > 3 is 3.019877344877345 at position 11 The first harmonic number > 4 is 4.02724519543652 at position 31 The first harmonic number > 5 is 5.002068272680166 at position 83 The first harmonic number > 6 is 6.004366708345566 at position 227 The first harmonic number > 7 is 7.001274097134161 at position 616 The first harmonic number > 8 is 8.00048557199578 at position 1674 The first harmonic number > 9 is 9.00020806293114 at position 4550 The first harmonic number > 10 is 10.000043008275808 at position 12367
Rust
Using big rationals and big integers from the num crate.
use num::rational::Ratio;
use num::BigInt;
use std::num::NonZeroU64;
fn main() {
for n in 1..=20 {
// `harmonic_number` takes the type `NonZeroU64`,
// which is just a normal u64 which is guaranteed to never be 0.
// We convert n into this type with `n.try_into().unwrap()`,
// where the unwrap is okay because n is never 0.
println!(
"Harmonic number {n} = {}",
harmonic_number(n.try_into().unwrap())
);
}
// The unwrap here is likewise okay because 100 is not 0.
println!(
"Harmonic number 100 = {}",
harmonic_number(100.try_into().unwrap())
);
// In order to avoid recomputing all the terms in the sum for every harmonic number
// we save the value of the harmonic series between loop iterations
// and just add 1/iter to it.
let mut target = 1;
let mut iter = 1;
let mut harmonic_number: Ratio<BigInt> = Ratio::from_integer(1.into());
while target <= 10 {
if harmonic_number > Ratio::from_integer(target.into()) {
println!("Position of first term > {target} is {iter}");
target += 1;
}
// Compute the next term in the harmonic series.
iter += 1;
harmonic_number += Ratio::from_integer(iter.into()).recip();
}
}
fn harmonic_number(n: NonZeroU64) -> Ratio<BigInt> {
// Convert each integer from 1 to n into an arbitrary precision rational number
// and sum their reciprocals.
(1..=n.get())
.map(|i| Ratio::from_integer(i.into()).recip())
.sum()
}
- Output:
Harmonic number 1 = 1 Harmonic number 2 = 3/2 Harmonic number 3 = 11/6 Harmonic number 4 = 25/12 Harmonic number 5 = 137/60 Harmonic number 6 = 49/20 Harmonic number 7 = 363/140 Harmonic number 8 = 761/280 Harmonic number 9 = 7129/2520 Harmonic number 10 = 7381/2520 Harmonic number 11 = 83711/27720 Harmonic number 12 = 86021/27720 Harmonic number 13 = 1145993/360360 Harmonic number 14 = 1171733/360360 Harmonic number 15 = 1195757/360360 Harmonic number 16 = 2436559/720720 Harmonic number 17 = 42142223/12252240 Harmonic number 18 = 14274301/4084080 Harmonic number 19 = 275295799/77597520 Harmonic number 20 = 55835135/15519504 Harmonic number 100 = 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 Position of first term > 1 is 2 Position of first term > 2 is 4 Position of first term > 3 is 11 Position of first term > 4 is 31 Position of first term > 5 is 83 Position of first term > 6 is 227 Position of first term > 7 is 616 Position of first term > 8 is 1674 Position of first term > 9 is 4550 Position of first term > 10 is 12367
Tcl
# Task 1
proc harmonic {n} {
if {$n < 1 || $n != [expr {floor($n)}]} {
error "Argument to harmonic function is not a natural number"
}
set Hn 1
for {set i 2} {$i <= $n} {incr i} {
set Hn [expr {$Hn + (1.0/$i)}]
}
return $Hn
}
# Task 2
for {set x 1} {$x <= 20} {incr x} {
set Hx [harmonic $x]
puts "$x: $Hx"
}
# Task 3 /stretch
set x 0
set lastInt 1
while {$lastInt <= 10} {
incr x
set Hx [harmonic $x]
if {$Hx > $lastInt} {
puts -nonewline "The first harmonic number above $lastInt"
puts " is $Hx at position $x"
incr lastInt
}
}
- Output:
1: 1 2: 1.5 3: 1.8333333333333333 4: 2.083333333333333 5: 2.283333333333333 6: 2.4499999999999997 7: 2.5928571428571425 8: 2.7178571428571425 9: 2.8289682539682537 10: 2.9289682539682538 11: 3.0198773448773446 12: 3.103210678210678 13: 3.180133755133755 14: 3.251562326562327 15: 3.3182289932289937 16: 3.3807289932289937 17: 3.439552522640758 18: 3.4951080781963135 19: 3.547739657143682 20: 3.597739657143682 The first harmonic number above 1 is 1.5 at position 2 The first harmonic number above 2 is 2.083333333333333 at position 4 The first harmonic number above 3 is 3.0198773448773446 at position 11 The first harmonic number above 4 is 4.02724519543652 at position 31 The first harmonic number above 5 is 5.002068272680166 at position 83 The first harmonic number above 6 is 6.004366708345567 at position 227 The first harmonic number above 7 is 7.001274097134162 at position 616 The first harmonic number above 8 is 8.000485571995782 at position 1674 The first harmonic number above 9 is 9.000208062931115 at position 4550 The first harmonic number above 10 is 10.000043008275778 at position 12367
Verilog
module main;
integer n, i;
real h;
initial begin
h = 0.0;
$display("The first twenty harmonic numbers are:");
for(n=1; n<=20; n=n+1) begin
h = h + 1.0 / n;
$display(n, " ", h);
end
$display("");
h = 1.0;
n = 2;
for(i=2; i<=10; i=i+1) begin
while (h < i) begin
h = h + 1.0 / n;
n = n + 1;
end
$write("The first harmonic number greater than ");
$display(i, " is ", h, ", at position ", n-1);
end
$finish ;
end
endmodule
Wren
import "./big" for BigRat
import "./fmt" for Fmt
var harmonic = Fn.new { |n| (1..n).reduce(BigRat.zero) { |sum, i| sum + BigRat.one/i } }
BigRat.showAsInt = true
System.print("The first 20 harmonic numbers and the 100th, expressed in rational form, are:")
var numbers = (1..20).toList
numbers.add(100)
for (i in numbers) Fmt.print("$3d : $s", i, harmonic.call(i))
System.print("\nThe first harmonic number to exceed the following integers is:")
var i = 1
var limit = 10
var n = 1
var h = 0
while (true) {
h = h + 1/n
if (h > i) {
Fmt.print("integer = $2d -> n = $,6d -> harmonic number = $9.6f (to 6dp)", i, n, h)
i = i + 1
if (i > limit) return
}
n = n + 1
}
- Output:
The first 20 harmonic numbers and the 100th, expressed in rational form, are: 1 : 1 2 : 3/2 3 : 11/6 4 : 25/12 5 : 137/60 6 : 49/20 7 : 363/140 8 : 761/280 9 : 7129/2520 10 : 7381/2520 11 : 83711/27720 12 : 86021/27720 13 : 1145993/360360 14 : 1171733/360360 15 : 1195757/360360 16 : 2436559/720720 17 : 42142223/12252240 18 : 14274301/4084080 19 : 275295799/77597520 20 : 55835135/15519504 100 : 14466636279520351160221518043104131447711/2788815009188499086581352357412492142272 The first harmonic number to exceed the following integers is: integer = 1 -> n = 2 -> harmonic number = 1.500000 (to 6dp) integer = 2 -> n = 4 -> harmonic number = 2.083333 (to 6dp) integer = 3 -> n = 11 -> harmonic number = 3.019877 (to 6dp) integer = 4 -> n = 31 -> harmonic number = 4.027245 (to 6dp) integer = 5 -> n = 83 -> harmonic number = 5.002068 (to 6dp) integer = 6 -> n = 227 -> harmonic number = 6.004367 (to 6dp) integer = 7 -> n = 616 -> harmonic number = 7.001274 (to 6dp) integer = 8 -> n = 1,674 -> harmonic number = 8.000486 (to 6dp) integer = 9 -> n = 4,550 -> harmonic number = 9.000208 (to 6dp) integer = 10 -> n = 12,367 -> harmonic number = 10.000043 (to 6dp)
XPL0
func real Harmonic(N); \Return Nth harmonic number
int N; real X;
[X:= 1.0;
while N >= 2 do
[X:= X + 1.0/float(N); N:= N-1];
return X;
];
int N, M;
[for N:= 1 to 20 do
[RlOut(0, Harmonic(N));
if rem(N/5) = 0 then CrLf(0);
];
for M:= 1 to 10 do
[N:= 1;
repeat N:= N+1 until Harmonic(N) > float(M);
IntOut(0, M);
Text(0, ": ");
IntOut(0, N);
CrLf(0);
];
]
- Output:
1.00000 1.50000 1.83333 2.08333 2.28333 2.45000 2.59286 2.71786 2.82897 2.92897 3.01988 3.10321 3.18013 3.25156 3.31823 3.38073 3.43955 3.49511 3.54774 3.59774 1: 2 2: 4 3: 11 4: 31 5: 83 6: 227 7: 616 8: 1674 9: 4550 10: 12367
- Programming Tasks
- Solutions by Programming Task
- WikipediaSourced
- ALGOL 68
- Arturo
- AWK
- BASIC
- Applesoft BASIC
- BASIC256
- CBASIC
- Chipmunk Basic
- Craft Basic
- Gambas
- GW-BASIC
- MSX Basic
- QBasic
- Run BASIC
- S-BASIC
- True BASIC
- Yabasic
- BQN
- Bruijn
- C
- C sharp
- C++
- Boost
- COBOL
- Delphi
- SysUtils,StdCtrls
- EasyLang
- Factor
- Forth
- FreeBASIC
- FutureBasic
- Go
- Haskell
- J
- Java
- Jq
- Julia
- Lua
- Mathematica
- Wolfram Language
- Maxima
- Nim
- Bignum
- PARI/GP
- PascalABC.NET
- Perl
- Phix
- Phix/mpfr
- Prolog
- Python
- Quackery
- R
- Raku
- REXX
- Ring
- RPL
- Ruby
- Rust
- Tcl
- Verilog
- Wren
- Wren-big
- Wren-fmt
- XPL0