One of n lines in a file: Difference between revisions

Added Easylang
m (Add reference to Rust rand library)
(Added Easylang)
 
(37 intermediate revisions by 19 users not shown)
Line 1:
{{task}}
A method of choosing a line randomly from a file:
::* Without reading the file more than once
::* When substantial parts of the file cannot be held in memory
::* Without knowing how many lines are in the file
Is to:
::* keep the first line of the file as a possible choice, then
::* Read the second line of the file if possible and make it the possible choice if a uniform random value between zero and one is less than 1/2.
::* Read the third line of the file if possible and make it the possible choice if a uniform random value between zero and one is less than 1/3.
::* ...
::* Read the Nth line of the file if possible and make it the possible choice if a uniform random value between zero and one is less than 1/N
 
::* Return the computed possible choice when no further lines exist in the file.
 
:* Return the computed possible choice when no further lines exist in the file.
 
;Task:
# Create a function/method/routine called <code>one_of_n</code> that given <code>n</code>, the number of actual lines in a file, follows the algorithm above to return an integer - the line number of the line chosen from the file. <br>The number returned can vary, randomly, in each run.
# Use <code>one_of_n</code> in a ''simulation'' to find what woudwould be the chosen line of a 10 -line file simulated 1,000,000 times.
# Print and show how many times each of the 10 lines is chosen as a rough measure of how well the algorithm works.
 
 
Note: You may choose a smaller number of repetitions if necessary, but mention this up-front.
 
Note: This is a specific version of a Reservoir Sampling algorithm: https://en.wikipedia.org/wiki/Reservoir_sampling
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">F one_of_n(lines)
V choice = 0
L(line) lines
I random:(0..L.index) == 0
choice = line
R choice
 
F one_of_n_test(n = 10, trials = 1000000)
V bins = [0] * n
I n != 0
L 1..trials
bins[one_of_n(0 .< n)]++
R bins
 
print(one_of_n_test())</syntaxhighlight>
 
;Sample output:
<pre>
[100032, 100304, 99964, 100101, 100666, 100276, 99470, 99547, 99738, 99902]
</pre>
 
=={{header|Ada}}==
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO, Ada.Numerics.Float_Random;
 
procedure One_Of_N is
Line 54 ⟶ 83:
Ada.Text_IO.Put(Integer'Image(Results(R)));
end loop;
end One_Of_N;</langsyntaxhighlight>
 
Example output:<pre> 100104 100075 99761 99851 100457 100315 100101 99557 99678 100101</pre>
 
=={{header|Aime}}==
<syntaxhighlight lang="aime">one_of_n(integer n)
{
integer i, r;
 
i = r = 0;
while ((r += 1) < n) {
i = drand(r) ? i : r;
}
 
i;
}
 
main(void)
{
integer i;
index x;
 
i = 1000000;
do {
x[one_of_n(10)] += 1;
} while (i -= 1);
 
x.ucall(o_winteger, 1, 7);
o_newline();
 
0;
}</syntaxhighlight>
{{Out}}
<pre> 99804 100236 99846 100484 99888 99639 99886 99810 99923 100484</pre>
 
=={{header|ALGOL 68}}==
<langsyntaxhighlight lang="algol68">BEGIN
INT max lines = 10; CO Should be read from a file. CO
[max lines]INT stats;
Line 73 ⟶ 133:
print (("Line Number times chosen", newline));
FOR i TO max lines DO printf (($g(0)7xg(0)l$, i, stats[i])) OD
END</langsyntaxhighlight>
{{out}}
<pre>
Line 91 ⟶ 151:
=={{header|Applesoft BASIC}}==
A million iterations will take a very very long time to run. I suggest cranking the end value of J down to 1000 or less in line 20, and run this at full speed in a modern Apple II emulator. Initializing with RND(0) in line 10, seeds the RND function to be random, otherwise you may see the same results every time.
<langsyntaxhighlight ApplesoftBASIClang="applesoftbasic">10 I = RND(0) : REMRANDOM SEED
 
20 FOR J = 1 TO 1000000 : REMMAYBE TRY 100 ON A 1MHZ APPLE II
Line 107 ⟶ 167:
120 IF INT(RND(1) * I) = 0 THEN C = I
130 NEXT I
140 RETURN</langsyntaxhighlight>
 
=={{header|Arturo}}==
 
<syntaxhighlight lang="rebol">oneOfN: function [n][
result: 0
loop 0..dec n 'x [
if zero? random 0 x ->
result: x
]
return result
]
 
oneOfNTest: function [n,trials][
ret: array.of:n 0
if n > 0 [
loop 1..trials 'i [
oon: oneOfN n
ret\[oon]: ret\[oon] + 1
]
]
return ret
]
 
print oneOfNTest 10 1000000</syntaxhighlight>
 
{{out}}
 
<pre>100120 100126 99975 99847 100235 100238 99528 99956 100038 99937</pre>
 
=={{header|AutoHotkey}}==
{{trans|Python}}
This simulation is for 100,000 repetitions.
<langsyntaxhighlight AutoHotkeylang="autohotkey">one_of_n(n){
; One based line numbers
choice = 1
Line 133 ⟶ 221:
Loop 10
out .= A_Index ": " b[A_Index] "`n"
MsgBox % out</langsyntaxhighlight>
Output:
<pre>---------------------------
Line 154 ⟶ 242:
 
=={{header|AWK}}==
<langsyntaxhighlight AWKlang="awk">#!/usr/bin/gawk -f
#
# Usage:
Line 169 ⟶ 257:
END {
print line;
}</langsyntaxhighlight>
 
Test randomness
<langsyntaxhighlight lang="bash">
for i in `seq 1 10000`; do seq 1 10 | awk -v Seed=$RANDOM -f one_of_n_lines_in_a_file.awk; done |sort|uniq -c
</syntaxhighlight>
</lang>
 
<pre>
Line 192 ⟶ 280:
{{works with|QBasic}}
 
<langsyntaxhighlight lang="qbasic">DECLARE FUNCTION oneofN& (n AS LONG)
 
DIM L0 AS LONG, c AS LONG
Line 215 ⟶ 303:
NEXT
oneofN& = choice
END FUNCTION</langsyntaxhighlight>
 
Sample output:
Line 228 ⟶ 316:
9 100154
10 99880
 
=={{header|Batch File}}==
I chose to only run this 100,000 times as it is slightly time consuming (running at 105 simulations / second).
I attempted to optimise a few ways but none were especially helpful.
 
There is also no need to parse the actual number of lines in the file to <code>one_of_n</code>
 
'''Batch file to call one_of_n'''
<syntaxhighlight lang="dos">
@echo off
 
for /l %%i in (1,1,10000) do call one_of_n
:: To show progress add to the FOR loop code block -
:: title %%i
 
for /l %%i in (1,1,10) do (
for /f "usebackq tokens=1,2 delims=:" %%j in (`find /c "%%i" output.txt`) do echo Line %%i =%%k
)
del output.txt
pause>nul
</syntaxhighlight>
 
 
'''one_of_n'''
<syntaxhighlight lang="dos">
setlocal enabledelayedexpansion
 
set /a count=1
 
for /f "tokens=*" %%i in (file.txt) do (
set /a rand=!random! %% !count!
if !rand!==0 set line=!count!
set /a count+=1
)
echo %line% >> output.txt
 
endlocal
exit /b
</syntaxhighlight>
 
 
'''Output'''
<pre>
Line 1 = 9,868‬
Line 2 = 10032
Line 3 = 9988
Line 4 = 10160
Line 5 = 10189
Line 6 = 9953
Line 7 = 9851
Line 8 = 10052
Line 9 = 9937
Line 10 = 9970
</pre>
 
=={{header|BBC BASIC}}==
<langsyntaxhighlight lang="bbcbasic"> @% = 7 : REM Column width
DIM cnt%(10)
FOR test% = 1 TO 1000000
Line 246 ⟶ 388:
IF RND(1) <= 1/i% l% = i%
NEXT
= l%</langsyntaxhighlight>
'''Output:'''
<pre>
Line 253 ⟶ 395:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
 
Line 279 ⟶ 421:
 
return 0;
}</langsyntaxhighlight>output
<pre>100561 99814 99816 99721 99244 99772 100790 100072 99997 100213</pre>
 
=={{header|C++}}==
{{works with|C++11}}
<lang cpp>#include <random>
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
 
mt19937 engine; //mersenne twister
 
unsigned int one_of_n(unsigned int n) {
unsigned int choice;
for(unsigned int i = 0; i < n; ++i) {
uniform_int_distribution<unsigned int> distribution(0, i);
if(!distribution(engine))
choice = i;
}
return choice;
}
 
int main() {
engine = mt19937(random_device()()); //seed random generator from system
unsigned int results[10] = {0};
for(unsigned int i = 0; i < 1000000; ++i)
results[one_of_n(10)]++;
ostream_iterator<unsigned int> out_it(cout, " ");
copy(results, results+10, out_it);
cout << '\n';
}
</lang>output
<pre>99981 99806 100190 99831 99833 100291 99356 100165 100279 100268</pre>
 
=={{header|C sharp|C#}}==
 
<langsyntaxhighlight lang="csharp">
class Program
{
Line 349 ⟶ 459:
}
}
</syntaxhighlight>
</lang>
<pre>
1 99777
Line 362 ⟶ 472:
10 99726
</pre>
 
=={{header|C++}}==
{{works with|C++11}}
<syntaxhighlight lang="cpp">#include <random>
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
 
mt19937 engine; //mersenne twister
 
unsigned int one_of_n(unsigned int n) {
unsigned int choice;
for(unsigned int i = 0; i < n; ++i) {
uniform_int_distribution<unsigned int> distribution(0, i);
if(!distribution(engine))
choice = i;
}
return choice;
}
 
int main() {
engine = mt19937(random_device()()); //seed random generator from system
unsigned int results[10] = {0};
for(unsigned int i = 0; i < 1000000; ++i)
results[one_of_n(10)]++;
ostream_iterator<unsigned int> out_it(cout, " ");
copy(results, results+10, out_it);
cout << '\n';
}
</syntaxhighlight>output
<pre>99981 99806 100190 99831 99833 100291 99356 100165 100279 100268</pre>
 
=={{header|Chapel}}==
 
<langsyntaxhighlight lang="chapel">use Random;
 
proc one_of_n(n) {
Line 378 ⟶ 520:
 
return keep;
}</langsyntaxhighlight>
 
=={{header|Clojure}}==
The function ''rand-seq-elem'' actually implements the algorithm; ''one-of-n'' uses it to select a random element from the sequence (1 ... n). (Though they weren't automatically highlighted when I wrote this, ''rand-int'', ''second'', and ''frequencies'' and ''println'' are also standard functions)
<langsyntaxhighlight lang="clojure">(defn rand-seq-elem [sequence]
(let [f (fn [[k old] new]
[(inc k) (if (zero? (rand-int k)) new old)])]
Line 392 ⟶ 534:
(let [countmap (frequencies (repeatedly 1000000 #(one-of-n 10)))]
(doseq [[n cnt] (sort countmap)]
(println n cnt)))</langsyntaxhighlight>
 
Sample output
<syntaxhighlight lang="text">1 99350
2 99933
3 99820
Line 404 ⟶ 546:
8 100020
9 100342
10 99382</langsyntaxhighlight>
 
To actually get a randomly selected line from a file:
<langsyntaxhighlight lang="clojure">(require '[clojure.java.io :as io])
 
(defn rand-line [filename]
(with-open [reader (io/reader filename)]
(rand-seq-elem (line-seq reader)))</langsyntaxhighlight>
 
=={{header|Common Lisp}}==
Great place to use closures.
<langsyntaxhighlight lang="lisp">(defun one-of-n-fn ()
(let ((cur 0) (sel nil))
#'(lambda (v)
Line 433 ⟶ 575:
(let* ((sel (funcall fnt 9)))
(setf (aref counts sel) (+ 1 (aref counts sel)))))))
</syntaxhighlight>
</lang>
Output:
<syntaxhighlight lang="text">#(100104 100144 100004 99593 100049 99706 100612 99481 100029 100278)</langsyntaxhighlight>
 
=={{header|D}}==
<langsyntaxhighlight lang="d">import std.stdio, std.random, std.algorithm;
 
// Zero-based line numbers.
Line 456 ⟶ 598:
bins.writeln;
writeln("Total of bins: ", bins[].sum);
}</langsyntaxhighlight>
{{out}}
<pre>[100091, 99940, 100696, 99799, 100234, 99419, 100225, 99716, 99942, 99938]
Total of bins: 1000000</pre>
=={{header|Delphi}}==
See [https://rosettacode.org/wiki/One_of_n_lines_in_a_file#Pascal Pascal].
=={{header|EasyLang}}==
{{trans|Lua}}
<syntaxhighlight>
n = 10
trials = 1000000
func one n .
for i = 1 to n
if randomf < 1 / i
chosen = i
.
.
return chosen
.
len results[] n
for i = 1 to trials
r = one n
results[r] += 1
.
print "Value Occurrences"
print "-------------------"
for i to n
print i & "\t" & results[i]
.
</syntaxhighlight>
 
=={{header|Eiffel}}==
<syntaxhighlight lang="eiffel">
<lang Eiffel>
class
APPLICATION
Line 496 ⟶ 664:
 
end
</syntaxhighlight>
</lang>
<syntaxhighlight lang="eiffel">
<lang Eiffel>
class
ONE_OF_N_LINES
Line 537 ⟶ 705:
 
end
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 554 ⟶ 722:
=={{header|Elixir}}==
{{trans|Erlang}}
<langsyntaxhighlight lang="elixir">defmodule One_of_n_lines_in_file do
def task do
dict = Enum.reduce(1..1000000, %{}, fn _,acc ->
Line 571 ⟶ 739:
end
 
One_of_n_lines_in_file.task</langsyntaxhighlight>
 
{{out}}
Line 588 ⟶ 756:
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
<lang Erlang>
-module( one_of_n_lines_in_file ).
 
Line 605 ⟶ 773:
 
update_counter( _N, Dict ) -> dict:update_counter( one_of_n(10), 1, Dict ).
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 622 ⟶ 790:
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
<lang ERRE>
PROGRAM ONE_OF_N
 
Line 646 ⟶ 814:
PRINT
END PROGRAM
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 653 ⟶ 821:
 
=={{header|Euphoria}}==
<langsyntaxhighlight Euphorialang="euphoria">-- One of n lines in a file
include std/rand.e
include std/math.e
Line 680 ⟶ 848:
 
main()
</syntaxhighlight>
</lang>
Sample Output:
<pre>
Line 697 ⟶ 865:
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">open System
 
[<EntryPoint>]
Line 719 ⟶ 887:
test 10 1000000
0</langsyntaxhighlight>
Output
<pre>99721 100325 99939 99579 100174 100296 99858 99910 100192 100006</pre>
Line 726 ⟶ 894:
''random-line'' uses an input stream. <code>"/etc/passwd" ascii [ random-line . ] with-file-reader</code> would print a random line from /etc/passwd.
 
<langsyntaxhighlight lang="factor">! rosettacode/random-line/random-line.factor
USING: io kernel locals math random ;
IN: rosettacode.random-line
Line 736 ⟶ 904:
[ choice! ] [ drop ] if
] while drop
choice ;</langsyntaxhighlight>
 
''one-of-n'' wants to use the same algorithm. Factor has duck typing, so ''one-of-n'' creates a mock object that quacks like an input stream. This mock object only responds to ''stream-readln'', not the other methods of stream protocol. This works because ''random-line'' only needs ''stream-readln''. The mock response is a line number instead of a real line.
 
<langsyntaxhighlight lang="factor">! rosettacode/one-of-n/one-of-n.factor
USING: accessors io kernel math rosettacode.random-line ;
IN: rosettacode.one-of-n
Line 770 ⟶ 938:
] each ;
PRIVATE>
MAIN: test-one-of-n</langsyntaxhighlight>
 
<pre>$ ./factor -run=rosettacode.one-of-n
Line 790 ⟶ 958:
=={{header|Forth}}==
{{works with|GNU Forth}}for random.fs and 1/f
<langsyntaxhighlight lang="forth">require random.fs
 
: frnd
Line 802 ⟶ 970:
: .hist cr 10 0 do i 1+ 2 .r ." : " i hist @ . cr loop ;
 
simulate .hist bye</langsyntaxhighlight>
{{out}}
<pre>&gt; gforthamd64 rosetta_one_of_n.fs
Line 816 ⟶ 984:
9: 100309
10: 100452</pre>
 
=={{header|Fortran}}==
Task description is contradictory in that it states number of lines
in file is unknown, and then that it is passed in as "n", and exercise
seems to be to simulate instead of actually perform the file reads; but
(at least when using Fortran, even on an old laptop) it only takes a
few seconds to run the 1 000 000, cases so actually ran them.
<syntaxhighlight lang="fortran">
!> read lines one at a time and randomly choose one
!! using a Reservoir Sampling algorithm:
!! http://www.rosettacode.org/wiki/One_of_n_lines_in_a_file
program reservoir_sample
use, intrinsic :: iso_fortran_env, only : dp=>real64
implicit none
character(len=256) :: line
integer :: lun, n, i, count(10)
call random_seed()
!! create test file
open(file='_data.txt',newunit=lun)
do i=1,10
write(lun,'(*(g0))')'test line ',i
enddo
!! run once and show result
call one_of_n(line,n)
write(*,'(i10,":",a)')n,trim(line)
!! run 1 000 000, times on ten-line test file
count=0
do i=1,1000000
call one_of_n(line,n)
if(n.gt.0.and.n.le.10)then
count(n)=count(n)+1
else
write(*,*)'<ERROR>'
endif
enddo
write(*,*)count
write(*,*)count-100000
contains
subroutine one_of_n(line,n)
character(len=256),intent(out) :: line
integer,intent(out) :: n
real(kind=dp) :: rand_val
integer :: ios, ilines
line=''
ios=0
ilines=1
n=0
rewind(lun)
do
call random_number(rand_val)
if( rand_val < 1.0d0/(ilines) )then
read(lun,'(a)',iostat=ios)line
if(ios/=0)exit
n=ilines
else
read(lun,'(a)',iostat=ios)
if(ios/=0)exit
endif
ilines=ilines+1
enddo
end subroutine one_of_n
end program reservoir_sample
}</syntaxhighlight>
{{out}}
<pre>
time fpm run --compiler gfortran
100112 99672 99928 100707 99612 100086 100628 99645 99676 99934
112 -328 -72 707 -388 86 628 -355 -324 -66
 
real 0m7.281s
user 0m5.812s
sys 0m1.465s
</pre>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">Declare Function one_of_n (n As Long) As Long
 
Dim As Long L0, c, elegido(1 To 10)
 
Function one_of_n (n As Long) As Long
 
'asume que la primera línea es 1
Dim As Long L1, opcion
For L1 = 1 To n
If Int(Rnd * L1) = 0 Then opcion = L1
Next L1
one_of_n = opcion
End Function
 
Randomize Timer
 
For L0 = 1 To 1000000
c = one_of_n(10)
elegido(c) += 1
Next L0
 
For L0 = 1 To 10
Print Using "##. #######"; L0; elegido(L0)
Next L0
 
Sleep</syntaxhighlight>
 
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import (
Line 899 ⟶ 1,169:
// task item 3. show frequencies.
fmt.Println(freq)
}</langsyntaxhighlight>
Output:
<pre>
Line 908 ⟶ 1,178:
The function selItem will operate on any list, whether a lazy list of strings from a file or a list of numbers, as in the test.
 
<langsyntaxhighlight Haskelllang="haskell">import qualified Data.Map as M
import System.Random
import Data.List
Line 940 ⟶ 1,210:
else putStrLn.(\(l, n, _, _) -> "Line " ++
show n ++ ": " ++ l)
.selItem g.lines =<< (readFile $ head a)</langsyntaxhighlight>
 
Running without any args runs the test:
Line 963 ⟶ 1,233:
=={{header|Icon}} and {{header|Unicon}}==
{{trans|Python}}
<langsyntaxhighlight Iconlang="icon">procedure main() # one of n
one_of_n_test(10,1000000)
end
Line 979 ⟶ 1,249:
every writes(bins[i := 1 to n]," ")
return bins
end</langsyntaxhighlight>
 
Sample output:<pre>99470 99806 99757 99921 100213 100001 99778 100385 100081 100588</pre>
Line 987 ⟶ 1,257:
This implementation also implements line buffering, since the built-in line handling does not work quite how I want it to work. That said, if a line is too large (many gigabytes, for example), the system will crawl to a halt when the line is read.
 
<langsyntaxhighlight lang="j">randLineBig=:3 :0
file=. boxopen y
r=. ''
Line 1,006 ⟶ 1,276:
end.
r
)</langsyntaxhighlight>
 
Usage: randLineBig 'filename'
Line 1,012 ⟶ 1,282:
Testing:
 
<langsyntaxhighlight lang="j"> (,LF,.~":,.i.10) fwrite <'seq.txt'
20
(#;~.)/.~ /:~ <@randLineBig"0]1e6#<'seq.txt'
Line 1,035 ⟶ 1,305:
├──────┼───┤
│99583 │9 │
└──────┴───┘</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|Python}}
<langsyntaxhighlight Javalang="java">import java.util.Arrays;
import java.util.Random;
 
Line 1,070 ⟶ 1,340:
}
}
</syntaxhighlight>
</lang>
 
Sample output:
<pre>[99832, 99958, 100281, 99601, 99568, 99689, 100118, 99753, 100659, 100541]</pre>
 
=={{header|jq}}==
{{trans|Wren}}
{{works with|jq}}
 
Since jq does not have a built-in PRNG, this entry assumes the
availability of an external source
of entropy such as /dev/random. The output shown below
is from a run of the following:
<syntaxhighlight lang="sh">
export LC_ALL=C
< /dev/random tr -cd '0-9' | fold -w 4 | jq -Mnr -f program.jq
</syntaxhighlight>
 
'''program.jq'''
<syntaxhighlight lang="jq"># oneOfN presupposes an unbounded stream
# of 4-digit PRNs uniformly distributed on [0-9999]
def oneOfN:
reduce range(2; 1+.) as $i (1;
if (input / 10000) < (1/$i) then $i else . end);
def n: 10;
def repetitions: 1e6;
 
( reduce range(0; repetitions) as $i (null;
(n|oneOfN) as $num
| .[$num-1] += 1 )) as $freqs
| range(1; 1+n) | "Line\(.) \($freqs[.-1] )"</syntaxhighlight>
{{out}}
<pre>
Line1 99745
Line2 100351
Line3 99805
Line4 100240
Line5 100155
Line6 99525
Line7 100182
Line8 99738
Line9 100360
Line10 99899
</pre>
 
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">
<lang Julia>
const N = 10
const GOAL = 10^6
Line 1,099 ⟶ 1,411:
println(@sprintf " %2d => %6d" i nhist[i])
end
</syntaxhighlight>
</lang>
 
{{out}}
Line 1,114 ⟶ 1,426:
9 => 100139
10 => 99778
</pre>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.1.51
 
import java.util.Random
 
val r = Random()
 
fun oneOfN(n: Int): Int {
var choice = 1
for (i in 2..n) {
if (r.nextDouble() < 1.0 / i) choice = i
}
return choice
}
 
fun main(args: Array<String>) {
val n = 10
val freqs = IntArray(n)
val reps = 1_000_000
repeat(reps) {
val num = oneOfN(n)
freqs[num - 1]++
}
for (i in 1..n) println("Line ${"%-2d".format(i)} = ${freqs[i - 1]}")
}</syntaxhighlight>
 
Sample output:
<pre>
Line 1 = 100363
Line 2 = 99669
Line 3 = 100247
Line 4 = 100248
Line 5 = 100401
Line 6 = 99457
Line 7 = 100015
Line 8 = 100215
Line 9 = 99920
Line 10 = 99465
</pre>
 
=={{header|Liberty BASIC}}==
<syntaxhighlight lang="lb">
<lang lb>
DIM chosen(10)
 
Line 1,136 ⟶ 1,488:
NEXT
END FUNCTION
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,152 ⟶ 1,504:
 
=={{header|Lua}}==
<syntaxhighlight lang="lua">
<lang Lua>
math.randomseed(os.time())
 
Line 1,184 ⟶ 1,536:
print(k,v)
end
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,201 ⟶ 1,553:
</pre>
 
=={{header|MathematicaMaple}}==
<syntaxhighlight lang="maple">
<lang Mathematica>chooseLine[file_] := Block[{strm = OpenRead[file], n = 1, rec, selected},
with(RandomTools[MersenneTwister]);
one_of_n_lines_in_a_file := proc(fn)
local fid, N, n, L, l, line;
fid := fopen(fn,'READ');
if fid<0 then
return;
end if;
N := 0;
n := 1;
while not feof(fid) do
N := N+1;
L := FileTools[Text][ReadLine](fid);
if (N*GenerateFloat() < 1) then
n := N;
line := L;
end if;
end do;
fclose(fid);
return(n);
end proc;
</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">chooseLine[file_] := Block[{strm = OpenRead[file], n = 1, rec, selected},
rec = selected = Read[strm];
While[rec =!= EndOfFile,
Line 1,209 ⟶ 1,585:
If[RandomReal[] < 1/n, selected = rec]];
Close[strm];
selected]</langsyntaxhighlight>
 
=={{header|MATLAB}} / {{header|Octave}}==
 
<langsyntaxhighlight Matlablang="matlab">function [n,line] = one_of_n_lines_in_a_file(fn)
fid = fopen(fn,'r');
if fid<0, return; end;
Line 1,226 ⟶ 1,602:
end;
end
fclose(fid);</langsyntaxhighlight>
test
<langsyntaxhighlight Matlablang="matlab">x=zeros(1,10);
for k = 1:1e6;
n = one_of_n_lines_in_a_file('f1');
x(n) = x(n) + 1;
end;
[1:10;x]</langsyntaxhighlight>
<pre> 1 2 3 4 5 6 7 8 9 10
105973 105715 106182 106213 105443 105255 106048 105999 105366 106070</pre>
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import mathrandom
randomize()
 
proc oneOfN(n: int): int =
result = 0
for x in 0 .. < n:
if random(x+1) == 0:
result = x
 
Line 1,253 ⟶ 1,629:
inc result[oneOfN(n)]
 
echo oneOfNTest()</langsyntaxhighlight>
 
Output:
{{out}}
<pre>@[99912, 100048, 99894, 99697, 99806, 100316, 100209, 99898, 100027, 100193]</pre>
<pre>@[100454, 100110, 99882, 99733, 100171, 99724, 100111, 99874, 100159, 99782]</pre>
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let one_of_n n =
let rec aux i r =
if i >= n then r else
Line 1,278 ⟶ 1,655:
let () =
Random.self_init ();
test ~n:10 ~trials:1_000_000</langsyntaxhighlight>
 
Executing:
Line 1,290 ⟶ 1,667:
=={{header|PARI/GP}}==
gp can't read individual lines from a file (PARI would be needed for that) but it can do the simulation easily. The <code>random()</code> function produces high-quality pseudorandom numbers (via Brent's [http://maths-people.anu.edu.au/~brent/pub/pub224.html XORGEN]) so the output passes a chi-square test easily (p = 0.848).
<langsyntaxhighlight lang="parigp">one_of_n(n)={
my(chosen=1);
for(k=2,n,
Line 1,297 ⟶ 1,674:
chosen;
}
v=vector(10); for(i=1,1e6, v[one_of_n(10)]++); v</langsyntaxhighlight>
{{out}}
<pre>%1 = [99933, 100021, 100125, 100071, 99876, 99485, 100108, 100183, 99861, 100337]</pre>
Line 1,303 ⟶ 1,680:
=={{header|Pascal}}==
{{works with|Free_Pascal}}
<langsyntaxhighlight lang="pascal">Program OneOfNLines (Output);
 
{$IFDEF FPC}
{$MODE DELPHI}
{$ENDIF}
 
function one_of_n(n: longint): longint;
Line 1,319 ⟶ 1,700:
i: integer;
begin
sumResult := 0;
for i := low(a) to high(a) do
sum Result := sumResult + a[i];
end;
 
Line 1,341 ⟶ 1,722:
writeln('Number of times line ', i, ' was selected: ', lines[i]);
writeln('Total number selected: ', sum(lines));
end.</langsyntaxhighlight>
Output:
<pre>% ./OneOfNLines
Line 1,358 ⟶ 1,739:
===using int-random===
int-random needn't the calculation of (1.0 /i).That is 3-times faster.I implemented the use of reading a random line of a textfile as discribed.In that case, there is no need to use the functoin one_of_n .
<langsyntaxhighlight lang="pascal">
Program OneOfNLines(InPut,Output);
{$h+} //use Ansistring
Line 1,444 ⟶ 1,825:
inc(LnCnt,cntLns[i]);
writeln('Total number selected: ', LnCnt);
end.</langsyntaxhighlight>
;Output:
<pre>
Line 1,461 ⟶ 1,842:
=={{header|Perl}}==
 
<langsyntaxhighlight lang="perl">#!/usr/bin/perl
use warnings;
use strict;
Line 1,479 ⟶ 1,860:
my @freq;
++$freq[ one_of_n($size) - 1 ] for 1 .. $repeat;
print "@freq\n";</langsyntaxhighlight>
 
=={{header|Perl 6}}==
{{trans|Python}}
<lang perl6>sub one_of_n($n) {
my $choice;
$choice = $_ if .rand < 1 for 1 .. $n;
$choice - 1;
}
 
sub one_of_n_test($n = 10, $trials = 1_000_000) {
my @bins;
@bins[one_of_n($n)]++ for ^$trials;
@bins;
}
 
say one_of_n_test();</lang>
Output:
<pre>100288 100047 99660 99773 100256 99633 100161 100483 99789 99910</pre>
 
=={{header|Phix}}==
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>function one_of_n(integer n)
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
integer line_num = 1
<span style="color: #008080;">function</span> <span style="color: #000000;">one_of_n</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
for i=2 to n do
<span style="color: #004080;">integer</span> <span style="color: #000000;">line_num</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
if rnd()<1/i then
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
line_num = i
<span style="color: #008080;">if</span> <span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()<</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">i</span> <span style="color: #008080;">then</span>
end if
<span style="color: #000000;">line_num</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return line_num
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
end function
<span style="color: #008080;">return</span> <span style="color: #000000;">line_num</span>
 
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
sequence counts = repeat(0,10)
for i=1 to 1000000 do
<span style="color: #004080;">sequence</span> <span style="color: #000000;">counts</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
counts[one_of_n(10)] += 1
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1000000</span> <span style="color: #008080;">do</span>
end for
<span style="color: #004080;">integer</span> <span style="color: #000000;">cdx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">one_of_n</span><span style="color: #0000FF;">(</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
?counts</lang>
<span style="color: #000000;">counts</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cdx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">counts</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 1,521 ⟶ 1,888:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de one-of-n (N)
(let R 1
(for I N
Line 1,531 ⟶ 1,898:
(do 1000000
(inc (nth L (one-of-n 10))) )
L )</langsyntaxhighlight>
Output:
<pre>-> (99893 100145 99532 100400 100263 100229 99732 100116 99709 99981)</pre>
Line 1,537 ⟶ 1,904:
=={{header|PowerShell}}==
'''Translation''' of: '''C#'''
<syntaxhighlight lang="powershell">
<lang PowerShell>
function Get-OneOfN ([int]$Number)
{
Line 1,570 ⟶ 1,937:
 
[PSCustomObject]$table
</syntaxhighlight>
</lang>
{{Out}}
<pre>
Line 1,584 ⟶ 1,951:
Line 10 : 99600
</pre>
The above version runs in ~650 seconds, because of the large overhead of calling PowerShell functions and binding their parameters. With a small change to move the function into a class method, the parameter binding becomes faster, and swapping Get-Random for System.Random, the overall code runtime drops to ~20 seconds. Changing the ordered hashtable to a Generic Dictionary reduces it again to ~15 seconds:
<syntaxhighlight lang="powershell">class Holder {
[System.Random]$rng
 
Holder()
{
$this.rng = [System.Random]::new()
}
 
[int] GetOneOfN([int]$Number)
{
$current = 1
for ($i = 2; $i -le $Number; $i++)
{
$limit = 1 / $i
if ($this.rng.NextDouble() -lt $limit)
{
$current = $i
}
}
return $current
}
}
 
$table = [Collections.Generic.Dictionary[int, int]]::new()
$X = [Holder]::new()
 
1..10 | ForEach-Object {
$table.Add($_, 0)
}
for ($i = 0; $i -lt 1e6; $i++)
{
$index = $X.GetOneOfN(10) - 1
$table[$index] += 1
}
[PSCustomObject]$table</syntaxhighlight>
 
=={{header|PureBasic}}==
<langsyntaxhighlight lang="purebasic">Procedure.f randomFloat()
ProcedureReturn Random(1000000) / 1000000
EndProcedure
Line 1,618 ⟶ 2,027:
Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()
EndIf</langsyntaxhighlight>
Sample output:
<pre>99959 100011 100682 100060 99834 99632 100083 99817 99824 100098</pre>
Line 1,624 ⟶ 2,033:
=={{header|Python}}==
To be more in line with the spirit of the problem, <code>one_of_n</code> will take the "lines" as an iterator, guaranteeing that it only traverses the lines one time, and does not know the length until the end.
<langsyntaxhighlight lang="python">from random import randrange
try:
range = xrange
Line 1,643 ⟶ 2,052:
return bins
 
print(one_of_n_test())</langsyntaxhighlight>
 
;Sample output:
Line 1,649 ⟶ 2,058:
 
=={{header|R}}==
<langsyntaxhighlight lang="rsplus">one_of_n <- function(n)
{
choice <- 1L
Line 1,662 ⟶ 2,071:
}
 
table(sapply(1:1000000, function(i) one_of_n(10)))</langsyntaxhighlight>
 
Sample output:
Line 1,669 ⟶ 2,078:
 
=={{header|Racket}}==
<syntaxhighlight lang="racket">
<lang Racket>
#lang racket
 
Line 1,733 ⟶ 2,142:
 
|#
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
{{trans|Python}}
<syntaxhighlight lang="raku" line>sub one_of_n($n) {
my $choice;
$choice = $_ if .rand < 1 for 1 .. $n;
$choice - 1;
}
 
sub one_of_n_test($n = 10, $trials = 1_000_000) {
my @bins;
@bins[one_of_n($n)]++ for ^$trials;
@bins;
}
 
say one_of_n_test();</syntaxhighlight>
Output:
<pre>100288 100047 99660 99773 100256 99633 100161 100483 99789 99910</pre>
 
=={{header|REXX}}==
<langsyntaxhighlight lang="rexx">/*REXX program simulates reading a ten─line file, count the selection randomness. */
N= 10 /*the number of lines in pseudo-file. */
@.= 0 /*zero all the (ten) "buckets". */
do 1000000 /*perform main loop one million times.*/
?= 1
do k=1 for N /*N is the number of lines in the file*/
if random(0, 99999) / 100000 < 1/k then ?= k /*the criteria.*/
end /*k*/
@.?= @.? + 1 /*bump the count in a particular bucket*/
end /*1000000*/
 
do j=1 for N /*display randomness counts (buckets). */
say "number of times line" right(j, 2) "was selected:" right(@.j, 9)
end /*j*/ /*stick a fork in it, we're all done. */</syntaxhighlight>
end /*j*/
{{out|output|text=&nbsp; when using the internal default input:}}
/*stick a fork in it, we're all done. */</lang>
'''output'''
<pre>
number of times line 1 was selected: 99752
Line 1,766 ⟶ 2,193:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
cnt = list(10)
for nr = 1 to 10000
Line 1,781 ⟶ 2,208:
next
return d
</syntaxhighlight>
</lang>
<pre>
1 : 15
Line 1,796 ⟶ 2,223:
 
=={{header|Ruby}}==
<langsyntaxhighlight lang="ruby"># Returns a random line from _io_, or nil if _io_ has no lines.
# # Get a random line from /etc/passwd
# line = open("/etc/passwd") {|f| random_line(f) }
Line 1,824 ⟶ 2,251:
chosen.keys.sort.each do |key|
puts "#{key} chosen #{chosen[key]} times"
end</langsyntaxhighlight>
 
<pre>$ ruby one-of-n.rb
Line 1,839 ⟶ 2,266:
 
=={{header|Run BASIC}}==
<langsyntaxhighlight lang="runbasic">for i1 = 1 to 1000000
c = oneOfN(10)
chosen(c) = chosen(c) + 1
Line 1,853 ⟶ 2,280:
next
oneOfN = choice
END FUNCTION</langsyntaxhighlight>Output:
<pre>1 99034
2 98462
Line 1,867 ⟶ 2,294:
=={{header|Rust}}==
{{libheader|rand}}
You could also use `rand::seq::sample_iter` which uses a more general version of this problem, Reservoir Sampling: https://en.wikipedia.org/wiki/Reservoir_sampling.
<lang rust>
<syntaxhighlight lang="rust">extern crate rand;
 
use rand::{Rng, thread_rng};
 
fn one_of_n<R: Rng>(rng: &mut rand::ThreadRngR, n: usize) -> usize {
(1..n).fold(0, |keep, cand| {
// Note that this will break if n is larger than match rng.next_f64() {u32::MAX
y if y < (1rng.0 / gen_weighted_bool(cand as u32 + 1) as f64) => cand,{
_ => keep cand
} else }{
)keep
}
})
}
 
fn main() {
letconst mutLINES: distusize = [0usize; 10];
 
let mut rng = rand::thread_rng();
let mut dist = [0; LINES];
let mut rng = thread_rng();
 
for _ in 0..1_000_000 {
dist[let num = one_of_n(&mut rng, 10LINES)] += 1;
dist[num] += 1;
}
 
println!("{:?}", dist);
}
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,898 ⟶ 2,330:
 
=={{header|Scala}}==
<langsyntaxhighlight Scalalang="scala">def one_of_n(n: Int, i: Int = 1, j: Int = 1): Int =
if (n < 1) i else one_of_n(n - 1, if (scala.util.Random.nextInt(j) == 0) n else i, j + 1)
 
Line 1,907 ⟶ 2,339:
}
 
println(simulate(10, 1000000) mkString "\n")</langsyntaxhighlight>
{{out}}
<pre>100014
Line 1,921 ⟶ 2,353:
 
=={{header|Seed7}}==
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
 
const func integer: one_of_n (in integer: n) is func
Line 1,948 ⟶ 2,380:
end for;
writeln;
end func;</langsyntaxhighlight>
 
Output:
Line 1,956 ⟶ 2,388:
 
=={{header|Sidef}}==
{{trans|Perl 6Raku}}
<langsyntaxhighlight lang="ruby">func one_of_n(n) {
var choice
n.times { |i|
Line 1,973 ⟶ 2,405:
}
 
say one_of_n_test()</langsyntaxhighlight>
 
{{out}}
Line 1,979 ⟶ 2,411:
 
=={{header|Swift}}==
<langsyntaxhighlight lang="swift">func one_of_n(n: Int) -> Int {
var result = 1
for i in 2...n {
Line 1,994 ⟶ 2,426:
}
println(counts)</langsyntaxhighlight>
 
{{Output|Sample Output}}
Line 2,000 ⟶ 2,432:
 
=={{header|Tcl}}==
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
proc 1ofN {n} {
for {set line 1} {$line <= $n} {incr line} {
Line 2,013 ⟶ 2,445:
incr count([1ofN 10])
}
parray count; # Alphabetic order, but convenient</langsyntaxhighlight>
Sample output:
<pre>
Line 2,029 ⟶ 2,461:
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">
<lang vb>
Dim chosen(10)
 
Line 2,049 ⟶ 2,481:
Next
End Function
</syntaxhighlight>
</lang>
 
{{Out}}
Line 2,064 ⟶ 2,496:
10. 99895
</pre>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "random" for Random
import "./fmt" for Fmt
 
var rand = Random.new()
 
var oneOfN = Fn.new { |n|
var choice = 1
for (i in 2..n) {
if (rand.float() < 1/i) choice = i
}
return choice
}
 
var n = 10
var freqs = List.filled(n, 0)
var reps = 1e6
for (i in 0...reps) {
var num = oneOfN.call(n)
freqs[num-1] = freqs[num-1] + 1
}
for (i in 1..n) Fmt.print("Line $-2d = $,7d", i, freqs[i-1])</syntaxhighlight>
 
{{out}}
Sample run:
<pre>
Line 1 = 99,761
Line 2 = 99,876
Line 3 = 99,935
Line 4 = 100,020
Line 5 = 100,281
Line 6 = 100,329
Line 7 = 99,876
Line 8 = 99,810
Line 9 = 100,033
Line 10 = 100,079
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang "XPL0">func One_of_n(N);
int N, Choice, Line;
[Choice:= 1;
for Line:= 2 to N do
if Ran(1_000_000) < 1_000_000/Line then Choice:= Line;
return Choice;
];
 
int Counters(1+10), I, N;
[for I:= 1 to 10 do Counters(I):= 0;
for I:= 1 to 1_000_000 do
[N:= One_of_n(10);
Counters(N):= Counters(N)+1;
];
for I:= 1 to 10 do
[IntOut(0, Counters(I));
ChOut(0, ^ );
];
]</syntaxhighlight>
{{out}}
<pre>
99477 99885 99826 100174 99902 99766 100287 100125 100386 100172 </pre>
 
=={{header|Yabasic}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="yabasic">
dim elegido(10)
 
sub one_of_n (n)
//asume que la primera línea es 1
local L1
for L1 = 1 to n
if int(ran(L1)) = 0 then opcion = L1 : endif
next L1
return opcion
end sub
 
for L0 = 1 to 1000000
c = one_of_n(10)
elegido(c) = elegido(c) + 1
next L0
 
for L0 = 1 to 10
print L0, ". ", elegido(L0)
next L0
 
end</syntaxhighlight>
 
=={{header|zkl}}==
{{trans|Python}}
<langsyntaxhighlight lang="zkl">fcn one_of_n(lines){ # lines is any iterable
#if 0 // iterative
choice:=Void;
Line 2,086 ⟶ 2,607:
}
 
println(one_of_n_test());</langsyntaxhighlight>
A Ref is a strong reference to a value, Ref.set(value) sets the Ref, Ref.value gets the value. A pump pumps data through a list of functions into a sink, Void.Skip skips this value (ie same as continue in a loop).
{{out}}
1,983

edits